01-basics
Basics Tutorial
Table of Contents
This tutorial covers basic usage of IRC::Client
, without going into
all of the supported events or describing
all of the methods or available Message
Objects. This should be enough
if you're just bringing some functionality using IRC as your interface, rather
than making, say, a full-featured IRC client.
Blog Tutorial
There exists a blog post describing this bot and showcasing some of the more advanced features. You can find it at yet to be published.
Subscribing to Events
All of the functionality is implemented as "plugins", which are passed to
the :plugins
attribute. Plugins are just regular classes, altough they can
do the IRC::Client::Plugin
role to obtain extra functionality.
To subscribe to one of the events, simply create a
method with the event's name in your class. The tutorial will use the
irc-to-me
event, which is a convenience event fired when the bot is addressed
in-channel or someone sends it a notice or a private message.
Event Handler Input
The event handlers receive one positional argument, which is an object that
does the IRC::Client::Message
role. The actual object received depends on the
event that triggered the handler. For example, the irc-to-me
can receive
these message objects:
IRC::Client::Message::Privmsg::Me
IRC::Client::Message::Privmsg::Channel
IRC::Client::Message::Notice::Me
IRC::Client::Message::Notice::Channel
While message objects differ in methods they offer, all of the above do have
a .text
attribute and stringify to its value. This means we can add a type
constraint on it without having to explicitly call it:
method irc-to-me ($e where /'bot command'/) { 'Do things here!'; }
Responding to Events
Channel messages, private messages, and notices can be replied to. Their
message objects have a .reply
method you can call to send a reply to the
message's sender. However, it's easier to just return a value from your method
handler, which will automatically call .reply
on the message object for you.
Returning a value from your event handler signals to the Client Object that
it handled the event and no other plugins or event handlers should be tried.
Your plugin can do the IRC::Client::Plugin
role (automatically exported
when you use IRC::Client
), which provides $.NEXT
attribute. The value
of that attribute is special and returning it signals the Client Object
that your event handler did not handle the event and other plugins and
event handlers should be tried.
Here are the things your event handler can return:
Value of
$.NEXT
: pass the event to the next plugin or event handler than can handle itNil
(and a select few other items that don't make sense as replies, such asIRC::Client
object): do not reply to the message, but do not pass the event to any other event handler; we handled itPromise
: when the Promise is.kept
, use its value for the .reply, unless it's aNil
. Note: you cannot return$.NEXT
here.Any other value: mark the event as handled and don't pass it further. The returned value will be given to message object's
.reply
method if it has one, or ignored if it doesn't. Forirc-to-me
message objects, this means the value will be sent back to the sender of the original message
Example: Echo Bot
In this example, we subscribe to the irc-to-me
event and respond by returning
the original message, prefixed with You said
.
use IRC::Client;
.run with IRC::Client.new:
:host<irc.freenode.net>
:channels('#rakubot', '#zofbot', '#myown' => 's3cret')
:debug
:plugins(
class { method irc-to-me ($e) { "You said $e.text()"} }
)
Generating Messages
If your plugin needs to generate messages instead of merely responding to
commands, you can use the Client Object's .send
method. Your plugin needs
to do the IRC::Client::Plugin
role to get access to the Client Object via
the $.irc
attribute:
use IRC::Client;
class AlarmBot does IRC::Client::Plugin {
method irc-connected ($) {
react {
whenever Supply.interval(3) {
$.irc.send: :where<#raku> :text<Three seconds passed!>;
}
}
}
}
.run with IRC::Client.new:
:nick<MahBot>
:host<irc.freenode.net>
:channels<#raku>
:debug
:plugins(AlarmBot.new)
Here, we subscribe to the irc-connected
event (using an anonymous parameter
for its message object, since we don't need it). It fires whenever we
successfully connect to a server. In the event handler we setup a
react
/whenever
loop, with a Supply
generating an event every three
seconds. In the whenever
block, we use the $.irc
attribute provided
by the IRC::Client::Plugin
role to call method .send
on the Client Object.
In the :where
parameter, we specify we want to send the message to
channel #raku
and the :text
parameter contains the text we want to send.
The bot will send that text every 3 seconds.
Up Next
Read the event reference next.