Building Services - ahamlinman/peribot GitHub Wiki
Services are where the real work in a Peribot-powered bot takes place. An instance of a service class can send zero or more replies to any given message received by a bot.
Although you can create a service from scratch (the details are documented in
Peribot's code), it is much easier to extend the Peribot::Service
class
provided by Peribot. By extending this class, you can put your logic in simple
handler methods and allow Peribot to handle the details of things like
sending replies.
Handler methods are methods that you define in your service class. Within your class definition, you register these methods to be called based on various triggers. When the right conditions are met, your method will be called with keyword arguments containing details from the message that triggered your handler.
Peribot::Service
provides three types of handler methods: message
handlers, command handlers, and listen handlers.
Message handlers are the simplest type of handler, and are called every time a message is received. They are called with a single keyword argument:
-
message
: The message that was received
A sample message handler might look like this:
def my_handler(message:)
return unless message[:user_name] == 'John Smith'
'Hey, John sent a message!'
end
on_message :my_handler
This example shows off several features of message handlers in general:
- They can return a string to send a reply
- They can return nil to ignore the message and send nothing
- They are registered using
on_[type]
declarations within the service class definition
Command handlers are called when a message starts with a particular command. Peribot defines a command as a word preceded by a '#' character and possibly followed by arguments. For example, if you are creating a service to retrieve weather conditions, you might have it respond to messages of the form "#weather Seattle, WA". Given a message like this, the command is "weather" and the arguments are "Seattle, WA". Command handlers are called with the following keyword arguments:
-
command
: The command that the message started with -
arguments
: The text following the command at the start of the message -
message
: The message that was received
A sample command handler that responds to the "#echo" command might look like this:
def talk_back(arguments:, **)
['You asked me to echo:', arguments]
end
on_command :echo, :talk_back
This shows off some additional aspects of working with handler methods:
- They can return an array of messages, and all will be sent as replies to the original
- Unnecessary keyword arguments can be ignored using Ruby's double-splat (
**
) operator
Listen handlers are called when a message matches a given regular expression. Listen handlers are called with the following keyword arguments:
-
match
: TheMatchData
obtained by matching the regex to the message text -
message
: The message that was received
A sample listen handler that likes all messages mentioning Peribot might look like this:
def show_approval(message:, **)
return if bot.config['ignore_mentions']
{
service: message[:service],
group: message[:group],
attachments: { kind: :like, message_id: message[:id] }
}
end
on_hear /peribot/i, :show_approval
Once again, we see a few more aspects of handler methods here:
- They can use the Peribot instance (and the shared resources it provides) via
the
bot
accessor method - They can return a hash, which Peribot will interpret as a message in its standard Message Format
- In addition to the expected
on_listen
, listen handlers can be registered usingon_hear
(which reads a bit more naturally)
If your service extends Peribot::Service
, you can easily tell your bot to use
it with the use
method. For example:
bot.use MyGreatService
If you do not extend Peribot::Service
, you should provide a class-level
register_into
method in your service:
def self.register_into(bot)
bot.service.register self
end
This ensures that the use
method will work properly for your custom service.