1Bot::BasicBot(3) User Contributed Perl Documentation Bot::BasicBot(3)
2
3
4
6 Bot::BasicBot - simple irc bot baseclass
7
9 #!/usr/bin/perl
10 use strict;
11 use warnings;
12
13 # Subclass Bot::BasicBot to provide event-handling methods.
14 package UppercaseBot;
15 use base qw(Bot::BasicBot);
16
17 sub said {
18 my $self = shift;
19 my $arguments = shift; # Contains the message that the bot heard.
20
21 # The bot will respond by uppercasing the message and echoing it back.
22 $self->say(
23 channel => $arguments->{channel},
24 body => uc $arguments->{body},
25 );
26
27 # The bot will shut down after responding to a message.
28 $self->shutdown('I have done my job here.');
29 }
30
31 # Create an object of your Bot::BasicBot subclass and call its run method.
32 package main;
33
34 my $bot = UppercaseBot->new(
35 server => 'irc.example.com',
36 port => '6667',
37 channels => ['#bottest'],
38 nick => 'UppercaseBot',
39 name => 'John Doe',
40 ignore_list => [ 'laotse', 'georgeburdell' ],
41 );
42 $bot->run();
43
45 Basic bot system designed to make it easy to do simple bots, optionally
46 forking longer processes (like searches) concurrently in the
47 background.
48
49 There are several examples of bots using Bot::BasicBot in the examples/
50 folder in the Bot::BasicBot tarball.
51
52 A quick summary, though - You want to define your own package that
53 subclasses Bot::BasicBot, override various methods (documented below),
54 then call "new" and "run" on it.
55
57 "new"
58 Creates a new instance of the class. Key/value pairs may be passed
59 which will have the same effect as calling the method of that name with
60 the value supplied. Returns a Bot::BasicBot object, that you can call
61 'run' on later.
62
63 eg:
64
65 my $bot = Bot::BasicBot->new( nick => 'superbot', channels => [ '#superheroes' ] );
66
67 "run"
68 Runs the bot. Hands the control over to the POE core.
69
71 To shut down the bot cleanly, use the "shutdown" method, which will
72 (through "AUTOLOAD") send an event of the same name to
73 POE::Component::IRC, so it takes the same arguments:
74
75 $bot->shutdown( $bot->quit_message() );
76
78 In your Bot::BasicBot subclass, you want to override some of the
79 following methods to define how your bot works. These are all object
80 methods - the (implicit) first parameter to all of them will be the bot
81 object.
82
83 "init"
84 called when the bot is created, as part of new(). Override to provide
85 your own init. Return a true value for a successful init, or undef if
86 you failed, in which case new() will die.
87
88 "said"
89 This is the main method that you'll want to override in your subclass -
90 it's the one called by default whenever someone says anything that we
91 can hear, either in a public channel or to us in private that we
92 shouldn't ignore.
93
94 You'll be passed a hashref that contains the arguments described below.
95 Feel free to alter the values of this hash - it won't be used later on.
96
97 who Who said it (the nick that said it)
98
99 raw_nick
100 The raw IRC nick string of the person who said it. Only really
101 useful if you want more security for some reason.
102
103 channel
104 The channel in which they said it. Has special value "msg" if it
105 was in a message. Actually, you can send a message to many
106 channels at once in the IRC spec, but no-one actually does this so
107 this is just the first one in the list.
108
109 body
110 The body of the message (i.e. the actual text)
111
112 address
113 The text that indicates how we were addressed. Contains the string
114 "msg" for private messages, otherwise contains the string off the
115 text that was stripped off the front of the message if we were
116 addressed, e.g. "Nick: ". Obviously this can be simply checked for
117 truth if you just want to know if you were addressed or not.
118
119 You should return what you want to say. This can either be a simple
120 string (which will be sent back to whoever was talking to you as a
121 message or in public depending on how they were talking) or a hashref
122 that contains values that are compatible with say (just changing the
123 body and returning the structure you were passed works very well.)
124
125 Returning undef will cause nothing to be said.
126
127 "emoted"
128 This is a secondary method that you may wish to override. It gets
129 called when someone in channel 'emotes', instead of talking. In its
130 default configuration, it will simply pass anything emoted on channel
131 through to the "said" handler.
132
133 "emoted" receives the same data hash as "said".
134
135 "noticed"
136 This is like "said", except for notices instead of normal messages.
137
138 "chanjoin"
139 Called when someone joins a channel. It receives a hashref argument
140 similar to the one received by said(). The key 'who' is the nick of the
141 user who joined, while 'channel' is the channel they joined.
142
143 This is a do-nothing implementation, override this in your subclass.
144
145 "chanpart"
146 Called when someone parts a channel. It receives a hashref argument
147 similar to the one received by said(). The key 'who' is the nick of the
148 user who parted, while 'channel' is the channel they parted.
149
150 This is a do-nothing implementation, override this in your subclass.
151
152 "got_names"
153 Whenever we have been given a definitive list of 'who is in the
154 channel', this function will be called. It receives a hash reference as
155 an argument. The key 'channel' will be the channel we have information
156 for, 'names' is a hashref where the keys are the nicks of the users,
157 and the values are more hashes, containing the two keys 'op' and
158 'voice', indicating if the user is a chanop or voiced respectively.
159
160 The reply value is ignored.
161
162 Normally, I wouldn't override this method - instead, just use the names
163 call when you want to know who's in the channel. Override this only if
164 you want to be able to do something as soon as possible. Also be aware
165 that the names list can be changed by other events - kicks, joins, etc,
166 and this method won't be called when that happens.
167
168 "topic"
169 Called when the topic of the channel changes. It receives a hashref
170 argument. The key 'channel' is the channel the topic was set in, and
171 'who' is the nick of the user who changed the channel, 'topic' will be
172 the new topic of the channel.
173
174 "nick_change"
175 When a user changes nicks, this will be called. It receives two
176 arguments: the old nickname and the new nickname.
177
178 "mode_change"
179 When a user sets channel modes, or the bot (or someone sharing its
180 bouncer connection?) sets user modes, this will be called. It receives
181 a hashref which will look like the following:
182
183 {
184 channel => "#channel",
185 who => "nick!user@host",
186 mode_changes => "+o+v",
187 mode_operands => ["bigpresh", "somedude"],
188 }
189
190 "kicked"
191 Called when a user is kicked from the channel. It receives a hashref
192 which will look like this:
193
194 {
195 channel => "#channel",
196 who => "nick",
197 kicked => "kicked",
198 reason => "reason",
199 }
200
201 The reply value is ignored.
202
203 "tick"
204 This is an event called every regularly. The function should return the
205 amount of time until the tick event should next be called. The default
206 tick is called 5 seconds after the bot starts, and the default
207 implementation returns '0', which disables the tick. Override this and
208 return non-zero values to have an ongoing tick event.
209
210 Use this function if you want the bot to do something periodically, and
211 don't want to mess with 'real' POE things.
212
213 Call the schedule_tick event to schedule a tick event without waiting
214 for the next tick.
215
216 "help"
217 This is the other method that you should override. This is the text
218 that the bot will respond to if someone simply says help to it. This
219 should be considered a special case which you should not attempt to
220 process yourself. Saying help to a bot should have no side effects
221 whatsoever apart from returning this text.
222
223 "connected"
224 An optional method to override, gets called after we have connected to
225 the server
226
227 "userquit"
228 Receives a hashref which will look like:
229
230 {
231 who => "nick that quit",
232 body => "quit message",
233 }
234
235 "irc_raw"
236 Receives a line of raw IRC input. Intended for cases where you're
237 trying to do something clever which the normal methods and parsing
238 supplied can't handle.
239
240 "irc_raw_out"
241 Receives a line of raw IRC output being sent to the IRC server.
242
244 There are a few methods you can call on the bot object to do things.
245 These are as follows:
246
247 "schedule_tick"
248 Takes an integer as an argument. Causes the tick event to be called
249 after that many seconds (or 5 seconds if no argument is provided). Note
250 that if the tick event is due to be called already, this will override
251 it. You can't schedule multiple future events with this funtction.
252
253 "forkit"
254 This method allows you to fork arbitrary background processes. They
255 will run concurrently with the main bot, returning their output to a
256 handler routine. You should call "forkit" in response to specific
257 events in your "said" routine, particularly for longer running
258 processes like searches, which will block the bot from receiving or
259 sending on channel whilst they take place if you don't fork them.
260
261 Inside the subroutine called by forkit, you can send output back to the
262 channel by printing lines (followd by "\n") to STDOUT. This has the
263 same effect as calling "Bot::BasicBot->say".
264
265 "forkit" takes the following arguments:
266
267 run A coderef to the routine which you want to run. Bear in mind that
268 the routine doesn't automatically get the text of the query -
269 you'll need to pass it in "arguments" (see below) if you want to
270 use it at all.
271
272 Apart from that, your "run" routine just needs to print its output
273 to "STDOUT", and it will be passed on to your designated handler.
274
275 handler
276 Optional. A method name within your current package which we can
277 return the routine's data to. Defaults to the built-in method
278 "say_fork_return" (which simply sends data to channel).
279
280 callback
281 Optional. A coderef to execute in place of the handler. If used,
282 the value of the handler argument is used to name the POE event.
283 This allows using closures and/or having multiple simultanious
284 calls to forkit with unique handler for each call.
285
286 body
287 Optional. Use this to pass on the body of the incoming message that
288 triggered you to fork this process. Useful for interactive
289 processes such as searches, so that you can act on specific terms
290 in the user's instructions.
291
292 who The nick of who you want any response to reach (optional inside a
293 channel.)
294
295 channel
296 Where you want to say it to them in. This may be the special
297 channel "msg" if you want to speak to them directly
298
299 address
300 Optional. Setting this to a true value causes the person to be
301 addressed (i.e. to have "Nick: " prepended to the front of returned
302 message text if the response is going to a public forum.
303
304 arguments
305 Optional. This should be an anonymous array of values, which will
306 be passed to your "run" routine. Bear in mind that this is not
307 intelligent - it will blindly spew arguments at "run" in the order
308 that you specify them, and it is the responsibility of your "run"
309 routine to pick them up and make sense of them.
310
311 "say"
312 Say something to someone. Takes a list of key/value pairs as arguments.
313 You should pass the following arguments:
314
315 who The nick of who you are saying this to (optional inside a channel.)
316
317 channel
318 Where you want to say it to them in. This may be the special
319 channel "msg" if you want to speak to them directly
320
321 body
322 The body of the message. I.e. what you want to say.
323
324 address
325 Optional. Setting this to a true value causes the person to be
326 addressed (i.e. to have "Nick: " prepended to the front of the
327 message text if this message is going to a pulbic forum.
328
329 You can also make non-OO calls to "say", which will be interpreted as
330 coming from a process spawned by "forkit". The routine will serialise
331 any data it is sent, and throw it to STDOUT, where POE::Wheel::Run can
332 pass it on to a handler.
333
334 "emote"
335 "emote" will return data to channel, but emoted (as if you'd said "/me
336 writes a spiffy new bot" in most clients). It takes the same arguments
337 as "say", listed above.
338
339 "notice"
340 "notice" will send a IRC notice to the channel. This is typically used
341 by bots to not break the IRC conversations flow. The message will
342 appear as:
343
344 -nick- message here
345
346 It takes the same arguments as "say", listed above. Example:
347
348 $bot->notice(
349 channel => '#bot_basicbot_test',
350 body => 'This is a notice'
351 );
352
353 "reply"
354 Takes two arguments, a hashref containing information about an incoming
355 message, and a reply message. It will reply in a privmsg if the
356 incoming one was a privmsg, in channel if not, and with prefixes if the
357 incoming one was prefixed. Mostly a shortcut method - it's roughly
358 equivalent to
359
360 $mess->{body} = $body;
361 $self->say($mess);
362
363 "pocoirc"
364 Takes no arguments. Returns the underlying POE::Component::IRC::State
365 object used by Bot::BasicBot. Useful for accessing various state
366 methods and for posting commands to the component. For example:
367
368 # get the list of nicks in the channel #someplace
369 my @nicks = $bot->pocoirc->channel_list("#someplace");
370
371 # join the channel #otherplace
372 $bot->pocoirc->yield('join', '#otherplace');
373
374 "channel_data"
375 Takes a channel names as a parameter, and returns a hash of hashes. The
376 keys are the nicknames in the channel, the values are hashes containing
377 the keys "voice" and "op", indicating whether these users are voiced or
378 opped in the channel. This method is only here for backwards
379 compatibility. You'll probably get more use out of
380 POE::Component::IRC::State's methods (which this method is merely a
381 wrapper for). You can access the POE::Component::IRC::State object
382 through Bot::BasicBot's "pocoirc" method.
383
385 Get or set methods. Changing most of these values when connected won't
386 cause sideffects. e.g. changing the server will not cause a disconnect
387 and a reconnect to another server.
388
389 Attributes that accept multiple values always return lists and either
390 accept an arrayref or a complete list as an argument.
391
392 The usual way of calling these is as keys to the hash passed to the
393 'new' method.
394
395 "server"
396 The server we're going to connect to. Defaults to "irc.perl.org".
397
398 "port"
399 The port we're going to use. Defaults to "6667"
400
401 "password"
402 The server password for the server we're going to connect to. Defaults
403 to undef.
404
405 "ssl"
406 A boolean to indicate whether or not the server we're going to connect
407 to is an SSL server. Defaults to 0.
408
409 "localaddr"
410 The local address to use, for multihomed boxes. Defaults to undef (use
411 whatever source IP address the system deigns is appropriate).
412
413 "useipv6"
414 A boolean to indicate whether IPv6 should be used. Defaults to undef
415 (use IPv4).
416
417 "nick"
418 The nick we're going to use. Defaults to five random letters and
419 numbers followed by the word "bot"
420
421 "alt_nicks"
422 Alternate nicks that this bot will be known by. These are not nicks
423 that the bot will try if it's main nick is taken, but rather other
424 nicks that the bot will recognise if it is addressed in a public
425 channel as the nick. This is useful for bots that are replacements for
426 other bots...e.g, your bot can answer to the name "infobot: " even
427 though it isn't really.
428
429 "username"
430 The username we'll claim to have at our ip/domain. By default this
431 will be the same as our nick.
432
433 "name"
434 The name that the bot will identify itself as. Defaults to "$nick bot"
435 where $nick is the nick that the bot uses.
436
437 "channels"
438 The channels we're going to connect to.
439
440 "quit_message"
441 The quit message. Defaults to "Bye".
442
443 "ignore_list"
444 The list of irc nicks to ignore public messages from (normally other
445 bots.) Useful for stopping bot cascades.
446
447 "charset"
448 IRC has no defined character set for putting high-bit chars into
449 channel. This attribute sets the encoding to be used for outgoing
450 messages. Defaults to 'utf8'.
451
452 "flood"
453 Set to '1' to disable the built-in flood protection of
454 POE::Compoent::IRC
455
456 "no_run"
457 Tells Bot::BasicBot to not run the POE kernel at the end of "run", in
458 case you want to do that yourself.
459
460 "webirc"
461 A hashref of WEBIRC params - keys "user", "pass", "host" and "ip".
462 Unless the network you are connecting to trusts you enough to give you
463 a WEBIRC config block & password, this won't be of any use to you.
464
466 "AUTOLOAD"
467 Bot::BasicBot implements AUTOLOAD for sending arbitrary states to the
468 underlying POE::Component::IRC component. So for a $bot object, sending
469
470 $bot->foo("bar");
471
472 is equivalent to
473
474 $poe_kernel->post(BASICBOT_ALIAS, "foo", "bar");
475
476 "log"
477 Logs the message. This method merely prints to STDERR - If you want
478 smarter logging, override this method - it will have simple text
479 strings passed in @_.
480
481 "ignore_nick"
482 Takes a nick name as an argument. Return true if this nick should be
483 ignored. Ignores anything in the ignore list
484
485 "nick_strip"
486 Takes a nick and hostname (of the form "nick!hostname") and returns
487 just the nick
488
489 "charset_decode"
490 Converts a string of bytes from IRC (uses "decode_irc" from IRC::Utils
491 internally) and returns a Perl string.
492
493 It can also takes a list (or arrayref or hashref) of strings, and
494 return a list of strings
495
496 "charset_encode"
497 Converts a list of perl strings into a list of byte sequences, using
498 the bot's charset. See "charset_decode".
499
501 If you have any questions or issues, you can drop by in #poe or
502 #bot-basicbot @ irc.perl.org, where I (Hinrik) am usually around.
503
505 David Precious (BIGPRESH) "<davidp@preshweb.co.uk>" is the current
506 maintainer.
507
508 Tom Insam <tom@jerakeen.org> was the original author.
509
510 This program is free software; you can redistribute it and/or modify it
511 under the same terms as Perl itself.
512
514 The initial version of Bot::BasicBot was written by Mark Fowler, and
515 many thanks are due to him.
516
517 Nice code for dealing with emotes thanks to Jo Walsh.
518
519 Various patches from Tom Insam, including much improved rejoining,
520 AUTOLOAD stuff, better interactive help, and a few API tidies.
521
522 Maintainership for a while was in the hands of Simon Kent
523 <simon@hitherto.net>. Don't know what he did. :-)
524
525 I (Tom Insam) received patches for tracking joins and parts from
526 Silver, sat on them for two months, and have finally applied them.
527 Thanks, dude. He also sent me changes for the tick event API, which
528 made sense.
529
530 In November 2010, maintainership moved to Hinrik Örn Sigurðsson
531 (hinrik.sig@gmail.com).
532
533 In April 2017, maintainership moved to David Precious
534 (davidp@preshweb.co.uk).
535
537 If you want to write/run a more flexible bot which supports module
538 loading, authentication, data storage etc, consider the subclass
539 Bot::BasicBot::Pluggable.
540
541 Also see POE, POE::Component::IRC
542
543 Possibly Infobot, at http://www.infobot.org
544
545
546
547perl v5.32.0 2020-07-28 Bot::BasicBot(3)