Current section

Files

Jump to
agala lib bot receiver.ex
Raw

lib/bot/receiver.ex

defmodule Agala.Bot.Receiver do
@type message :: any
@moduledoc """
You can use this behaviour for implementing your own **provider**.
This receiver has simple generic idea:
* In loop, it's geting new messages via `get_updates/2` callback
* Then, these messages are sent into handler one after one.
So, you actually can `use Agala.Bot.Receiver`, and implement only one method -
`get_updates/2`, which will get new messages.
This callback will be called by framework itself, but in order to push messages into `Agala.Bot.Handler`
you should call `notify_with/1` lambda, that will come as first argument to your `get_updates/2` function.
### Example
# Simple random numbers generator
defmodule Random.Receiver do
use Agala.Bot.Receiver
def get_updates(notify_with, _bot_params) do
notify_with(:rand.uniform)
end
end
"""
@doc """
TODO: Docs
"""
@callback get_updates(notify_with :: (message -> :ok), bot_params :: Agala.BotParams.t) :: Agala.BotParams.t
defmacro __using__(_) do
quote location: :keep do
use GenServer
require Logger
@behaviour Agala.Bot.Receiver
defp via_tuple(name) do
{:global, {:agala, :receiver, name}}
end
@spec start_link(bot_params :: Agala.BotParams.t) :: GenServer.on_start
def start_link(bot_params) do
GenServer.start_link(__MODULE__, bot_params, name: via_tuple(bot_params.name))
end
@spec init(bot_params :: Agala.BotParams.t) :: {:ok, Agala.BotParams.t}
def init(bot_params) do
Process.register(self(), :"#Agala.Bot.Receiver<#{bot_params.name}>")
Logger.debug("Starting receiver with params:\n\t#{inspect bot_params}\r")
Process.send(self(), :loop, [])
bot_params.provider.init(bot_params, :receiver)
end
@spec handle_info(:loop, bot_params :: Agala.BotParams.t) :: {:noreply, Agala.BotParams.t}
def handle_info(:loop, bot_params) do
Process.send(self(), :loop, [])
# this callback will be call to asyncronosly push messages to handler
notify_with = fn message ->
Agala.Bot.Handler.handle(message, bot_params)
end
new_params = get_updates(notify_with, bot_params)
case get_in(new_params, ([:common, :restart])) do
true -> {:stop, :normal, new_params}
_ -> {:noreply, new_params}
end
end
def handle_info(_, state), do: {:noreply, state}
end
end
end