Current section
Files
Jump to
Current section
Files
lib/router.ex
defmodule TelegramEx.Router do
@moduledoc """
Behaviour for organizing bot handlers into separate modules.
Routers allow you to split your bot's logic into multiple modules,
each handling specific domains or features. This keeps your main bot
module clean and makes large bots more maintainable.
## Usage
Create a router module:
defmodule MyApp.Routers.Admin do
use TelegramEx.Router
defstate :admin do
def handle_message(%{text: "/exit", chat: chat}, ctx) do
ctx
|> Message.text("Exiting admin mode")
|> Message.send(chat["id"])
FSM.reset_state(:my_bot, chat["id"])
end
def handle_message(%{text: text, chat: chat}, ctx) do
ctx
|> Message.text("Admin command: \#{text}")
|> Message.send(chat["id"])
end
end
def handle_callback(_callback, _ctx), do: :pass
end
Register the router in your bot:
defmodule MyBot do
use TelegramEx, name: :my_bot, routers: [MyApp.Routers.Admin]
def handle_message(%{text: "/admin", chat: chat}, ctx) do
ctx
|> Message.text("Entering admin mode")
|> Message.send(chat["id"])
{:transition, :admin}
end
end
## Handler Chain
When an update arrives, routers are tried in the order they're listed.
If a router returns `:pass`, the next router (or main bot module) is tried.
"""
alias TelegramEx.Types
@doc """
Callback invoked when a message is received.
Should return a `TelegramEx.handler_result()` or `:pass` to skip to the next handler.
"""
@callback handle_message(message :: Types.Message.t(), ctx :: map()) :: any()
@doc """
Callback invoked when a callback query is received.
Should return a `TelegramEx.handler_result()` or `:pass` to skip to the next handler.
"""
@callback handle_callback(callback :: Types.CallbackQuery.t(), ctx :: map()) :: any()
defmacro __using__(_opts) do
quote do
@behaviour TelegramEx.Router
import TelegramEx
import TelegramEx.FSM, only: [defstate: 2]
alias TelegramEx.{API, Config, FSM}
alias TelegramEx.Builder.{Contact, Document, Location, Message, Photo, Poll, Sticker, Video}
@before_compile TelegramEx.Router
end
end
defmacro __before_compile__(_env) do
quote do
def handle_message(_message, _ctx), do: :pass
def handle_callback(_callback, _ctx), do: :pass
end
end
end