Current section

Files

Jump to
agala lib bot bot.ex
Raw

lib/bot/bot.ex

defmodule Agala.Bot do
@moduledoc """
This module represents main Bot supervisor.
**Bot** is a complex module, that can retreive information, handle it and send either to recepient
or to another Bot module.
Defining new **Bot** requires only `name`, `provider` and `handler`.
When the **Bot** is starting it will automaticly make supervision tree for next modules:
* `Agala.Bot.Receiver` - module which gets new data from the recepient defined as a `provider`
* `Agala.Bot.Handler` - module which is handling messages, that are incoming to the `bot`
* `Agala.Bot.Responser` - module, that converts your application responses into form,
acceptable by the recepient
* `Agala.Bot.Storage` [**OPTIONALY**] - module with *Storage* behaviour, that helps with
keeping cross-crashing data for providers
### Starting your bot
You can start as many bots as you want. They should be differ from each other only by name.
Thus, they can have similar provider, handler and whatever you want. To specify bot instance,
use `Agala.BotParams` - they should be passed as an argument to start new bot.
### Example
# Starting 2 bots with different providers:
Supervisor.start_link([
{Agala.Bot, %{name: "telegram", provider: Agala.Provider.Telegram, handler: ...}},
{Agala.Bot, %{name: "vk", provider: Agala.Provider.Vk, handler: ...}},
])
"""
use Supervisor
@doc false
def child_spec(bot_params = %{name: name}) do
%{
id: :"#Agala.Bot<#{name}>",
start: {Agala.Bot, :start_link, [bot_params]},
type: :supervisor
}
end
defp via_tuple(name) do
{:global, {:agala, :bot, name}}
end
@doc false
def start_link(bot_params) do
Supervisor.start_link(__MODULE__, bot_params, name: via_tuple(bot_params.name))
end
@doc false
def init(bot_params = %{
storage: storage,
provider: provider
}) do
Process.register(self(), :"#Agala.Bot<#{bot_params.name}>")
Code.ensure_loaded(storage)
case function_exported?(storage, :child_spec, 1) do
true -> [{storage, bot_params}]
false -> []
end ++ [
{provider.get_responser(), bot_params},
{Agala.Bot.Handler, bot_params},
{provider.get_receiver(), bot_params},
]
|> Supervisor.init(strategy: :one_for_one, max_restarts: 1000, max_seconds: 1)
end
end