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>
132 lines
3.7 KiB
Elixir
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
|