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
endRegister 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
endHandler 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.
Summary
Callbacks
Callback invoked when a callback query is received.
Callback invoked when a message is received.
Callbacks
@callback handle_callback(callback :: TelegramEx.Types.CallbackQuery.t(), ctx :: map()) :: any()
Callback invoked when a callback query is received.
Should return a TelegramEx.handler_result() or :pass to skip to the next handler.
@callback handle_message(message :: TelegramEx.Types.Message.t(), ctx :: map()) :: any()
Callback invoked when a message is received.
Should return a TelegramEx.handler_result() or :pass to skip to the next handler.