Current section

Files

Jump to
ex_gram lib ex_gram bot supervisor.ex
Raw

lib/ex_gram/bot/supervisor.ex

defmodule ExGram.Bot.Supervisor do
@moduledoc """
Bot supervisor that starts the `ExGram.Dispatcher` and Updates processes.
This supervisor coordinates the lifecycle of a bot's core components: the dispatcher
(which handles incoming updates) and the updates worker (which fetches or receives
updates from Telegram via polling, webhooks, or test mode).
See the [Polling and Webhooks guide](polling-and-webhooks.md) for more details about different updates methods and the [testing guide](testing.md) for using the test updates worker in your tests.
"""
alias ExGram.Dispatcher
def child_spec(opts, module) do
%{
id: opts[:id] || module,
start: {ExGram.Bot.Supervisor, :start_link, [opts, module]},
type: :supervisor,
restart: :permanent,
shutdown: 500
}
end
def start_link(opts, module) do
supervisor_name = opts[:name] || Module.concat(module, Supervisor)
params = Keyword.put(opts, :module, module)
Supervisor.start_link(ExGram.Bot.Supervisor, params, name: supervisor_name)
end
def init(opts) do
updates_method = Keyword.fetch!(opts, :method)
token = Keyword.fetch!(opts, :token)
module = Keyword.fetch!(opts, :module)
name = Keyword.get(opts, :bot_name, module.name())
{:ok, _} = Registry.register(Registry.ExGram, name, token)
{updates_worker, updates_worker_opts} = updates_worker(updates_method)
updates_worker_opts = Map.merge(updates_worker_opts, %{bot: name, token: token})
extra_info = Keyword.get(opts, :extra_info, %{})
dispatcher_init_opts = Keyword.take(opts, [:username, :setup_commands])
dispatcher_opts = Dispatcher.init_state(name, module, dispatcher_init_opts, extra_info)
children =
[
{Dispatcher, dispatcher_opts},
{updates_worker, updates_worker_opts}
]
Supervisor.init(children, strategy: :one_for_one)
end
defp updates_worker(nil), do: raise("No updates method received, try with :polling or your custom module")
defp updates_worker(name) when is_atom(name) do
{updates_worker_module(name), %{}}
end
defp updates_worker({name, options}) when is_atom(name) do
{updates_worker_module(name), Map.new(options)}
end
defp updates_worker_module(:webhook), do: ExGram.Updates.Webhook
defp updates_worker_module(:noup), do: ExGram.Updates.Noup
defp updates_worker_module(:polling), do: ExGram.Updates.Polling
defp updates_worker_module(:test), do: ExGram.Updates.Test
defp updates_worker_module(module) when is_atom(module), do: module
end