Files
omnibot/lib/module/base.ex
Alek Ratzloff 76d96c2fe2 Rename Omnibot.Module -> Omnibot.Module.Base, add Omnibot.Module with agent
Previously, all modules were Agents. This renames the Omnibot.Module to
be the base module, and the new Omnibot.Module uses an Agent by default.

This opens the doors to possibly allowing metamodule supervisors for
modules that may be more complex.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-06-14 17:34:06 -04:00

132 lines
3.7 KiB
Elixir

defmodule Omnibot.Module.Base do
defmodule Hooks do
defmacro __before_compile__(_env) do
quote generated: true do
@impl true
def on_channel_msg(_irc, _channel, _nick, _line), do: nil
@impl true
def on_channel_msg(_irc, _channel, _nick, _cmd, _params), do: nil
@impl true
def on_join(_irc, _channel, _nick), do: nil
@impl true
def on_part(_irc, _channel, _nick), do: nil
@impl true
def on_kick(_irc, _channel, _nick, _target), do: nil
@impl true
def on_init(_cfg), do: nil
@impl true
def default_config(), do: @default_config
def commands(), do: MapSet.to_list(@commands)
end
end
end
defmacro __using__([]) do
quote do
alias Omnibot.{Irc, Module}
import Omnibot.Module.Base
require Logger
@behaviour Module.Base
@impl Module.Base
def on_msg(irc, msg) do
# TODO - instead of using a router for modules, consider using a PubSub with a Registry:
# https://hexdocs.pm/elixir/master/Registry.html#module-using-as-a-pubsub
route_msg(irc, msg)
end
defp route_msg(irc, msg) do
nick = msg.prefix.nick
case String.upcase(msg.command) do
"PRIVMSG" ->
[channel | params] = msg.params
line = Enum.join(params, " ")
case String.split(line, " ") do
[cmd | params] -> if Enum.member?(commands(), cmd),
do: on_channel_msg(irc, channel, nick, cmd, params),
else: on_channel_msg(irc, channel, nick, line)
_ -> on_channel_msg(irc, channel, nick, line)
end
"JOIN" ->
[channel | _] = msg.params
on_join(irc, channel, nick)
"PART" ->
[channel | _] = msg.params
on_part(irc, channel, nick)
"KICK" ->
[channel, target | _] = msg.params
on_kick(irc, channel, nick, target)
_ ->
nil
end
end
defoverridable Module.Base
@commands MapSet.new()
@default_config []
@before_compile Omnibot.Module.Base.Hooks
end
end
@callback on_msg(irc :: pid(), msg :: %Omnibot.Irc.Msg{}) :: any
@callback on_channel_msg(irc :: pid(), channel :: String.t(), nick :: String.t(), line :: String.t()) :: any
@callback on_channel_msg(
irc :: pid(),
channel :: String.t(),
nick :: String.t(),
cmd :: String.t(),
params :: [String.t()]
) :: any
@callback on_join(irc :: pid(), channel :: String.t(), nick :: String.t()) :: any
@callback on_part(irc :: pid(), channel :: String.t(), nick :: String.t()) :: any
@callback on_kick(irc :: pid(), channel :: String.t(), nick :: String.t(), target :: String.t()) :: any
@callback on_init(cfg :: any) :: any
@callback default_config() :: any
defmacro command(cmd, opts) do
quote generated: true do
@commands MapSet.put(@commands, unquote(cmd))
@impl Omnibot.Module.Base
def on_channel_msg(var!(irc), var!(channel), var!(nick), unquote(cmd), var!(params)) do
unquote(opts[:do])
end
end
end
defmacro command(cmd, params, opts) do
params =
Enum.map(
params,
fn param ->
case param do
{_, _, _} -> quote(do: var!(unquote(param)))
lit -> Macro.escape(lit)
end
end
)
quote generated: true do
@commands MapSet.put(@commands, unquote(cmd))
@impl Omnibot.Module.Base
def on_channel_msg(var!(irc), var!(channel), var!(nick), unquote(cmd), unquote(params)) do
unquote(opts[:do])
end
end
end
end