ExBot v0.1.1 ExBot.Slug behaviour
The slug specification. Slugs are like Plugs, but for Slack.
What do slugs do? They…
- Receive events from Slack.
- Perform any actions they desire as a reaction to the event. For example, sending a message, or adding a reaction.
- Optionally annotate the event they received with metadata that may be helpful to other slugs.
- Return the event, passing it on to the next slug in the pipeline.
In addition to the documentation below, check out the bundled slugs and associated tests under the ExBot.Slug.Common
namespace for examples.
The Slug Pipeline
Many slugs are strung together inside of a ExBot.Bot
module to build a slug pipeline.
A bot’s pipeline of slugs defines how a bot reacts to events coming from the Slack RTM API.
Kinds of Slugs
There are two kind of slugs: function slugs and module slugs.
Function slugs
A function slug is any function that receives a ExBot.Event
and returns a ExBot.Event
or :halt
.
Its type signature must be:
(ExBot.Event.t) :: ExBot.Event.t
Module slugs
A module slug is an extension of the function slug. The API expected by a module slug is defined as a behaviour by the
ExBot.Slug
module (this module), specifically the export of call/2
.
Examples
Function Slug
Here’s an example of a function slug that logs out the event it receives. Later slugs may like to know that an inspection occurred, so this slug also makes a note in the metadata that it inspected the event.
def simple_reply(%ExBot.Event{data: %{user: user_id, channel: channel_id}} = event) do
IO.inspect("Event from #{user_id} in channel #{channel_id}: #{inspect(event)}")
event |> Event.add_metadata(:got_inspected, true)
end
Module Slug
Here’s an example of a module slug that checks if the bot was mentioned
in a Slack message and annotates the ExBot.Event
’s metadata accordingly.
defmodule ExBot.Slug.Common.CheckMentioned do
@behaviour ExBot.Slug
def call(event, _bot) do
%ExBot.Event{
bot_id: bot_id,
data: %{text: message},
metadata: %{bot_name: bot_name}
} = event
is_mentioned = Regex.match?(~r/.*(<@#{bot_id}>|@#{bot_name}).*/, message)
event |> ExBot.Event.add_metadata(:mentioned, is_mentioned)
end
end
Don’t forget the catch-all
If your slug function, or module, uses pattern matching in its clause you probably want to provide a catch-all clause that passes on any event that is not recognized.
def simple_slug(%ExBot.Event{data: %{user: "UTEST"}} = event) do
IO.puts("The test user produced an event")
event
end
#Ignore and forward any events that don't match the clause above
def simple_slug(event), do: event
If you actually want to halt the progress of the pipeline, return :halt
from your slug.
Link to this section Summary
Callbacks
Takes a ExBot.Event
and the ExBot.Bot
module that received the event.
Must return a ExBot.Event
or :halt
Link to this section Callbacks
call(event :: ExBot.Event.t(), bot :: ExBot.Bot.t()) :: ExBot.Event.t() | :halt
Takes a ExBot.Event
and the ExBot.Bot
module that received the event.
Must return a ExBot.Event
or :halt
.
Returning :halt
will abort the pipeline execution, and subsequent slugs in the pipeline will not be run.