1POE::Component::IRC::StUasteer(3C)ontributed Perl DocumePnOtEa:t:iCoonmponent::IRC::State(3)
2
3
4
6 POE::Component::IRC::State - A fully event-driven IRC client module
7 with nickname and channel tracking
8
10 # A simple Rot13 'encryption' bot
11
12 use strict;
13 use warnings;
14 use POE qw(Component::IRC::State);
15
16 my $nickname = 'Flibble' . $$;
17 my $ircname = 'Flibble the Sailor Bot';
18 my $ircserver = 'irc.blahblahblah.irc';
19 my $port = 6667;
20
21 my @channels = ( '#Blah', '#Foo', '#Bar' );
22
23 # We create a new PoCo-IRC object and component.
24 my $irc = POE::Component::IRC::State->spawn(
25 nick => $nickname,
26 server => $ircserver,
27 port => $port,
28 ircname => $ircname,
29 ) or die "Oh noooo! $!";
30
31 POE::Session->create(
32 package_states => [
33 main => [ qw(_default _start irc_001 irc_public) ],
34 ],
35 heap => { irc => $irc },
36 );
37
38 $poe_kernel->run();
39
40 sub _start {
41 my ($kernel, $heap) = @_[KERNEL, HEAP];
42
43 # We get the session ID of the component from the object
44 # and register and connect to the specified server.
45 my $irc_session = $heap->{irc}->session_id();
46 $kernel->post( $irc_session => register => 'all' );
47 $kernel->post( $irc_session => connect => { } );
48 return;
49 }
50
51 sub irc_001 {
52 my ($kernel, $sender) = @_[KERNEL, SENDER];
53
54 # Get the component's object at any time by accessing the heap of
55 # the SENDER
56 my $poco_object = $sender->get_heap();
57 print "Connected to ", $poco_object->server_name(), "\n";
58
59 # In any irc_* events SENDER will be the PoCo-IRC session
60 $kernel->post( $sender => join => $_ ) for @channels;
61 return;
62 }
63
64 sub irc_public {
65 my ($kernel ,$sender, $who, $where, $what) = @_[KERNEL, SENDER, ARG0 .. ARG2];
66 my $nick = ( split /!/, $who )[0];
67 my $channel = $where->[0];
68 my $poco_object = $sender->get_heap();
69
70 if ( my ($rot13) = $what =~ /^rot13 (.+)/ ) {
71 # Only operators can issue a rot13 command to us.
72 return if !$poco_object->is_channel_operator( $channel, $nick );
73
74 $rot13 =~ tr[a-zA-Z][n-za-mN-ZA-M];
75 $kernel->post( $sender => privmsg => $channel => "$nick: $rot13" );
76 }
77 return;
78 }
79
80 # We registered for all events, this will produce some debug info.
81 sub _default {
82 my ($event, $args) = @_[ARG0 .. $#_];
83 my @output = ( "$event: " );
84
85 for my $arg ( @$args ) {
86 if (ref $arg eq 'ARRAY') {
87 push( @output, '[' . join(', ', @$arg ) . ']' );
88 }
89 else {
90 push ( @output, "'$arg'" );
91 }
92 }
93 print join ' ', @output, "\n";
94 return 0;
95 }
96
98 POE::Component::IRC::State is a sub-class of POE::Component::IRC which
99 tracks IRC state entities such as nicks and channels. See the
100 documentation for POE::Component::IRC for general usage. This document
101 covers the extra methods that POE::Component::IRC::State provides.
102
103 The component tracks channels and nicks, so that it always has a
104 current snapshot of what channels it is on and who else is on those
105 channels. The returned object provides methods to query the collected
106 state.
107
109 POE::Component::IRC::State's constructors, and its "connect" event, all
110 take the same arguments as POE::Component::IRC does, as well as two
111 additional ones:
112
113 'AwayPoll', the interval (in seconds) in which to poll (i.e. "WHO
114 #channel") the away status of channel members. Defaults to 0
115 (disabled). If enabled, you will receive "irc_away_sync_*" /
116 "irc_user_away" / "irc_user_back" events, and will be able to use the
117 "is_away" method for users other than yourself. This can cause a lot of
118 increase in traffic, especially if you are on big channels, so if you
119 do use this, you probably don't want to set it too low. For reference,
120 X-Chat uses 300 seconds (5 minutes).
121
122 'WhoJoiners', a boolean indicating whether the component should send a
123 "WHO nick" for every person which joins a channel. Defaults to on (the
124 "WHO" is sent). If you turn this off, "is_operator" will not work and
125 "nick_info" will only return the keys 'Nick', 'User', 'Host' and
126 'Userhost'.
127
129 All of the POE::Component::IRC methods are supported, plus the
130 following:
131
132 "ban_mask"
133 Expects a channel and a ban mask, as passed to MODE +b-b. Returns a
134 list of nicks on that channel that match the specified ban mask or an
135 empty list if the channel doesn't exist in the state or there are no
136 matches.
137
138 "channel_ban_list"
139 Expects a channel as a parameter. Returns a hashref containing the
140 banlist if the channel is in the state, a false value if not. The
141 hashref keys are the entries on the list, each with the keys 'SetBy'
142 and 'SetAt'. These keys will hold the nick!hostmask of the user who set
143 the entry (or just the nick if it's all the ircd gives us), and the
144 time at which it was set respectively.
145
146 "channel_creation_time"
147 Expects a channel as parameter. Returns channel creation time or a
148 false value.
149
150 "channel_except_list"
151 Expects a channel as a parameter. Returns a hashref containing the ban
152 exception list if the channel is in the state, a false value if not.
153 The hashref keys are the entries on the list, each with the keys
154 'SetBy' and 'SetAt'. These keys will hold the nick!hostmask of the user
155 who set the entry (or just the nick if it's all the ircd gives us), and
156 the time at which it was set respectively.
157
158 "channel_invex_list"
159 Expects a channel as a parameter. Returns a hashref containing the
160 invite exception list if the channel is in the state, a false value if
161 not. The hashref keys are the entries on the list, each with the keys
162 'SetBy' and 'SetAt'. These keys will hold the nick!hostmask of the user
163 who set the entry (or just the nick if it's all the ircd gives us), and
164 the time at which it was set respectively.
165
166 "channel_key"
167 Expects a channel as parameter. Returns the channel key or a false
168 value.
169
170 "channel_limit"
171 Expects a channel as parameter. Returns the channel limit or a false
172 value.
173
174 "channel_list"
175 Expects a channel as parameter. Returns a list of all nicks on the
176 specified channel. If the component happens to not be on that channel
177 an empty list will be returned.
178
179 "channel_modes"
180 Expects a channel as parameter. Returns a hash ref keyed on channel
181 mode, with the mode argument (if any) as the value. Returns a false
182 value instead if the channel is not in the state.
183
184 "channels"
185 Takes no parameters. Returns a hashref, keyed on channel name and
186 whether the bot is operator, halfop or has voice on that channel.
187
188 for my $channel ( keys %{ $irc->channels() } ) {
189 $irc->yield( 'privmsg' => $channel => 'm00!' );
190 }
191
192 "channel_topic"
193 Expects a channel as a parameter. Returns a hashref containing topic
194 information if the channel is in the state, a false value if not. The
195 hashref contains the following keys: 'Value', 'SetBy', 'SetAt'. These
196 keys will hold the topic itself, the nick!hostmask of the user who set
197 it (or just the nick if it's all the ircd gives us), and the time at
198 which it was set respectively.
199
200 If the component happens to not be on the channel, nothing will be
201 returned.
202
203 "channel_url"
204 Expects a channel as a parameter. Returns the channel's URL. If the
205 channel has no URL or the component is not on the channel, nothing will
206 be returned.
207
208 "has_channel_voice"
209 Expects a channel and a nickname as parameters. Returns a true value if
210 the nick has voice on the specified channel. Returns false if the nick
211 does not have voice on the channel or if the nick/channel does not
212 exist in the state.
213
214 "is_away"
215 Expects a nick as parameter. Returns a true value if the specified nick
216 is away. Returns a false value if the nick is not away or not in the
217 state. This will only work for your IRC user unless you specified a
218 value for 'AwayPoll' in "spawn".
219
220 "is_channel_admin"
221 Expects a channel and a nickname as parameters. Returns a true value if
222 the nick is an admin on the specified channel. Returns false if the
223 nick is not an admin on the channel or if the nick/channel does not
224 exist in the state.
225
226 "is_channel_halfop"
227 Expects a channel and a nickname as parameters. Returns a true value if
228 the nick is a half-operator on the specified channel. Returns false if
229 the nick is not a half-operator on the channel or if the nick/channel
230 does not exist in the state.
231
232 "is_channel_member"
233 Expects a channel and a nickname as parameters. Returns a true value if
234 the nick is on the specified channel. Returns false if the nick is not
235 on the channel or if the nick/channel does not exist in the state.
236
237 "is_channel_mode_set"
238 Expects a channel and a single mode flag "[A-Za-z]". Returns a true
239 value if that mode is set on the channel.
240
241 "is_channel_operator"
242 Expects a channel and a nickname as parameters. Returns a true value if
243 the nick is an operator on the specified channel. Returns false if the
244 nick is not an operator on the channel or if the nick/channel does not
245 exist in the state.
246
247 "is_channel_owner"
248 Expects a channel and a nickname as parameters. Returns a true value if
249 the nick is an owner on the specified channel. Returns false if the
250 nick is not an owner on the channel or if the nick/channel does not
251 exist in the state.
252
253 "is_channel_synced"
254 Expects a channel as a parameter. Returns true if the channel has been
255 synced. Returns false if it has not been synced or if the channel is
256 not in the state.
257
258 "is_operator"
259 Expects a nick as parameter. Returns a true value if the specified nick
260 is an IRC operator. Returns a false value if the nick is not an IRC
261 operator or is not in the state.
262
263 "is_user_mode_set"
264 Expects single user mode flag "[A-Za-z]". Returns a true value if that
265 user mode is set.
266
267 "nick_channel_modes"
268 Expects a channel and a nickname as parameters. Returns the modes of
269 the specified nick on the specified channel (ie. qaohv). If the nick is
270 not on the channel in the state, a false value will be returned.
271
272 "nick_channels"
273 Expects a nickname. Returns a list of the channels that that nickname
274 and the component are on. An empty list will be returned if the
275 nickname does not exist in the state.
276
277 "nick_info"
278 Expects a nickname. Returns a hashref containing similar information to
279 that returned by WHOIS. Returns a false value if the nickname doesn't
280 exist in the state. The hashref contains the following keys:
281
282 'Nick', 'User', 'Host', 'Userhost', 'Hops', 'Real', 'Server' and, if
283 applicable, 'IRCop'.
284
285 "nick_long_form"
286 Expects a nickname. Returns the long form of that nickname, ie.
287 "nick!user@host" or a false value if the nick is not in the state.
288
289 "nicks"
290 Takes no parameters. Returns a list of all the nicks, including itself,
291 that it knows about. If the component happens to be on no channels then
292 an empty list is returned.
293
294 "umode"
295 Takes no parameters. Returns the current user mode set for the bot.
296
298 Augmented events
299 New parameters are added to the following POE::Component::IRC events.
300
301 "irc_quit"
302
303 See also "irc_quit" in POE::Component::IRC.
304
305 Additional parameter "ARG2" contains an arrayref of channel names that
306 are common to the quitting client and the component.
307
308 "irc_nick"
309
310 See also "irc_nick" in POE::Component::IRC.
311
312 Additional parameter "ARG2" contains an arrayref of channel names that
313 are common to the nick hanging client and the component.
314
315 "irc_kick"
316
317 See also "irc_kick" in POE::Component::IRC.
318
319 Additional parameter "ARG4" contains the full nick!user@host of the
320 kicked individual.
321
322 "irc_topic"
323
324 See also "irc_kick" in POE::Component::IRC.
325
326 Additional parameter "ARG3" contains the old topic hashref, like the
327 one returned by "channel_topic".
328
329 "irc_disconnected"
330
331 "irc_error"
332
333 "irc_socketerr"
334
335 These three all have two additional parameters. "ARG1" is a hash of
336 information about your IRC user (see "nick_info"), while "ARG2" is a
337 hash of the channels you were on (see "channels").
338
339 New events
340 As well as all the usual POE::Component::IRC "irc_*" events, there are
341 the following events you can register for:
342
343 "irc_away_sync_start"
344
345 Sent whenever the component starts to synchronise the away statuses of
346 channel members. "ARG0" is the channel name. You will only receive this
347 event if you specified a value for 'AwayPoll' in "spawn".
348
349 "irc_away_sync_end"
350
351 Sent whenever the component has completed synchronising the away
352 statuses of channel members. "ARG0" is the channel name. You will only
353 receive this event if you specified a value for 'AwayPoll' in "spawn".
354
355 "irc_chan_mode"
356
357 This is almost identical to "irc_mode", except that it's sent once for
358 each individual mode with it's respective argument if it has one (ie.
359 the banmask if it's +b or -b). However, this event is only sent for
360 channel modes.
361
362 "irc_chan_sync"
363
364 Sent whenever the component has completed synchronising a channel that
365 it has joined. "ARG0" is the channel name and "ARG1" is the time in
366 seconds that the channel took to synchronise.
367
368 "irc_chan_sync_invex"
369
370 Sent whenever the component has completed synchronising a channel's
371 INVEX (invite list). Usually triggered by the component being opped on
372 a channel. "ARG0" is the channel name.
373
374 "irc_chan_sync_excepts"
375
376 Sent whenever the component has completed synchronising a channel's
377 EXCEPTS (ban exemption list). Usually triggered by the component being
378 opped on a channel. "ARG0" is the channel.
379
380 "irc_nick_sync"
381
382 Sent whenever the component has completed synchronising a user who has
383 joined a channel the component is on. "ARG0" is the user's nickname and
384 "ARG1" the channel they have joined.
385
386 "irc_user_away"
387
388 Sent when an IRC user sets his/her status to away. "ARG0" is the
389 nickname, "ARG1" is an arrayref of channel names that are common to the
390 nickname and the component. You will only receive this event if you
391 specified a value for 'AwayPoll' in "spawn".
392
393 Note: This above is only for users other than yourself. To know when
394 you change your own away status, register for the "irc_305" and
395 "irc_306" events.
396
397 "irc_user_back"
398
399 Sent when an IRC user unsets his/her away status. "ARG0" is the
400 nickname, "ARG1" is an arrayref of channel names that are common to the
401 nickname and the component. You will only receive this event if you
402 specified a value for 'AwayPoll' in "spawn".
403
404 Note: This above is only for users other than yourself. To know when
405 you change your own away status, register for the "irc_305" and
406 "irc_306" events.
407
408 "irc_user_mode"
409
410 This is almost identical to "irc_mode", except it is sent for each
411 individual umode that is being set.
412
414 The component gathers information by registering for "irc_quit",
415 "irc_nick", "irc_join", "irc_part", "irc_mode", "irc_kick" and various
416 numeric replies. When the component is asked to join a channel, when
417 it joins it will issue 'WHO #channel', 'MODE #channel', and 'MODE
418 #channel b'. These will solicit between them the numerics, "irc_352",
419 "irc_324" and "irc_329", respectively. When someone joins a channel
420 the bot is on, it issues a 'WHO nick'. You may want to ignore these.
421
422 Currently, whenever the component sees a topic or channel list change,
423 it will use "time" for the SetAt value and the full address of the user
424 who set it for the SetBy value. When an ircd gives us its record of
425 such changes, it will use its own time (obviously) and may only give us
426 the nickname of the user, rather than their full address. Thus, if our
427 "time" and the ircd's time do not match, or the ircd uses the nickname
428 only, ugly inconsistencies can develop. This leaves the 'SetAt' and
429 'SetBy' values inaccurate at best, and you should use them with this in
430 mind (for now, at least).
431
433 Chris Williams <chris@bingosnet.co.uk>
434
435 With contributions from Lyndon Miller.
436
438 This module may be used, modified, and distributed under the same terms
439 as Perl itself. Please see the license that came with your Perl
440 distribution for details.
441
443 POE::Component::IRC
444
445 POE::Component::IRC::Qnet::State
446
447
448
449perl v5.38.0 2023-07-21 POE::Component::IRC::State(3)