nosedrum v0.1.0 Nosedrum View Source
nosedrum
is a command framework for use with the excellent
nostrum
library.
It contains behaviour specifications for easily implementing command handling in your bot along with other conveniences to ease creating an interactive bot.
nosedrum
s provided implementations are largely based off what was originally
written for bolt. bolt also contains
around 57
commands based
off the Nosedrum.Command
behaviour that you can explore if you're looking
for inspiration.
The core of the framework consists of three parts:
Nosedrum.Command
, the behaviour that all commands must implement.Nosedrum.Invoker
, the behaviour of command processors. Command processors take a message, look it up in the provided storage implementation, and invoke commands as required. nosedrum ships with an implementation of this based on bolt's original command parser namedNosedrum.Invoker.Split
.Nosedrum.Storage
, the behaviour of command storages. Command storages allow for fast and simple lookups of commands and command groups and store command names along with their correspondingNosedrum.Command
implementations internally. An ETS-based command storage implementation is provided withNosedrum.Storage.ETS
.
Installation
Simply add :nosedrum
to your mix.exs
file:
def deps do
[
{:nostrum, github: "Kraigie/nostrum"},
{:nosedrum, "~> 0.1"}
]
end
If mix
complains due to conflicting versions, you will need to specify
override: true
in your dependencies:
def deps do
[
{:nostrum, github: "Kraigie/nostrum", override: true},
{:nosedrum, "~> 0.1"}
]
end
Note that nosedrum
requires at least version 0.3.0 of nostrum
.
Getting started
To start off, your commands need to implement the Nosedrum.Command
behaviour.
As a simple example, let's reimplement
ed
.
defmodule MyBot.Cogs.Ed do
@behaviour Nosedrum.Command
alias Nostrum.Api
@impl true
def usage, do: ["ed [-GVhs] [-p string] [file]"]
@impl true
def description, do: "Ed is the standard text editor."
@impl true
def predicates, do: []
@impl true
def command(msg, _args) do
{:ok, _msg} = Api.create_message(msg.channel_id, "?")
end
end
With your commands defined, choose a Nosedrum.Storage
implementation and add
it to your application callback. We will use the included
Nosedrum.Storage.ETS
implementation here, but feel free to write your own:
defmodule MyBot.Application do
use Application
def start(_type, _args) do
children = [
Nosedrum.Storage.ETS,
MyBot.Consumer
]
options = [strategy: :one_for_one, name: MyBot.Supervisor]
Supervisor.start_link(children, options)
end
end
Finally, we hook things up in our consumer: we will load commands once the bot is ready, and invoke the command invoker on each message.
defmodule MyBot.Consumer do
alias Nosedrum.Invoker.Split, as: CommandInvoker
alias Nosedrum.Storage.ETS, as: CommandStorage
use Nostrum.Consumer
@commands %{
"ed" => MyBot.Cogs.Ed
}
def handle_event({:READY, {_data}, _ws_state}) do
Enum.each(@commands, fn {name, cog} -> CommandStorage.add_command({name}, cog) end)
end
def handle_event({:MESSAGE_CREATE, {msg}, _ws_state}) do
CommandInvoker.handle_message(msg, CommandStorage)
end
def handle_event(_data), do: :ok
end
That's all we need to get started with. If you want to customize your bot's
prefix, set the nosedrum.prefix
configuration variable:
config :nosedrum,
prefix: System.get_env("BOT_PREFIX") || "."
If no value is configured, the default prefix used depends on the chosen
command invoker implementation. Nosedrum.Invoker.Split
defaults to .
.