1 ================================================================================
5 The first 6 lines of autogreet.pl are similar to dicebot.pl from the
13 use base qw(Bot::BasicBot);
15 The only difference is we changed the package to GreetBot instead of
18 Next, we have our first subroutine chanjoin, which greets new users
19 whenever one joins a channel.
23 my $arguments = shift;
24 my $nick = $arguments->{who};
25 if ($nick eq $self->pocoirc->nick_name()) {
29 channel => $arguments->{channel},
30 body => "Welcome, $nick!",
34 We store the user's nick in $nick:
36 my $nick = $arguments->{who};
38 Afterwards, we check if the new user's nick, $nick, is the same as our
39 bot's nick, $self->pocoirc->nick_name(). When the bot itself first joins
40 a channel, chanjoin is called. We don't want the bot to greet itself, so
41 we skip it with return.
43 if ($nick eq $self->pocoirc->nick_name()) {
47 The return statement exits a subroutine without executing any
48 of the code that comes after it:
50 Next, we tell the bot to send a message to the channel to greet the new
54 channel => $arguments->{channel},
55 body => "Welcome, $nick!",
58 Up next is the subroutine chanpart. It is called whenever a user parts from
59 a channel. It tells the bot to send a message whenever a user leaves:
63 my $arguments = shift;
65 channel => $arguments->{channel},
66 body => "I'm sad to see $arguments->{who} go.",
70 Take a closer look at the value of body:
72 body => "I'm sad to see $arguments->{who} go.",
74 Notice that $arguments->{who} is put right inside the quotation marks, but
75 the message does not literally have the string "$arguments->{who}". Instead,
76 perl evalutes $arguments->{who} to get the user's nick, then puts that value
79 We do something different for the subroutine emoted. Instead of merely
80 sending a message, we will emote it (send an action message):
84 my $arguments = shift;
87 channel => $arguments->{channel},
88 body => "$arguments->{body} too",
92 On many irc clients, you can type /me <your-text-here> to emote.
93 Watch the bot emote back!
95 In the subroutine noticed, we use an array for @notices:
99 my $arguments = shift;
101 my $nick = $arguments->{who};
104 "$nick, please resend this in a normal message",
105 "I'm having a hard time reading your notice.",
106 "Good point, $nick.",
107 "Can you message on the public channel instead?",
112 channel => $arguments->{channel},
113 body => $notices[int(rand(4))],
117 When you send a notice to the bot or to a channel the bot is in, it will
118 reply with one of four different notices:
121 "$nick, please resend this in a normal message",
122 "I'm having a hard time reading your notice.",
123 "Good point, $nick.",
124 "Can you message on the public channel instead?",
127 The sigil (the symbol before a variable) for an array is @. An array
128 can begin with an open and close parenthesis ( ) and the items inside are
129 separated with commas ,.
131 @notices has four strings. Those strings use double quotes so
132 that the variables inside will get interpolated.
134 An array stores many items, each one with a unique index. The first
135 element of the array @notices is $notices[0]. The second element is
136 $notices[1], and the third is $notices[2].
138 Arrays in Perl (like in most programming languages) begin with 0 as
141 body => $notices[int(rand(4))],
143 rand(n) will return a random float between 0 and n. int() *truncates*
144 the float, meaning it drops everything after the decimal point. For
145 example, int(3.1415) gets *truncated* to 3: everything after the
146 decimal point gets ignored.
148 int(rand(4)) gives a random integer from 0 to 3, which we use as the
149 index for $notices. In other words, the body is a random notice chosen
150 from an array of four notices.
152 In the subroutine topic, anytime the topic is changed, the bot will
153 add a short warning to the end of it:
157 my $arguments = shift;
159 if ($arguments->{who} eq $self->pocoirc->nick_name()) {
162 $self->pocoirc->yield('topic' => $arguments->{channel} => "$arguments->{topic} || Don't change the topic!");
165 If the new nick $arguments->{who} is the same as the bot's current nick
166 $self->pocoirc->nick_name(), then we return and do nothing. This line
167 is necessary to prevent an infinite loop. Without this line, if the bot
168 changes the topic, the subroutine topic will get called again, causing
169 the bot to again change the topic.
171 if ($arguments->{who} eq $self->pocoirc->nick_name()) {
175 The bot will change the topic in the current channel to a new topic.
176 This topic contains the original topic plus "|| Don't change the topic!":
178 $self->pocoirc->yield('topic' => $arguments->{channel} => "$arguments->{topic} || Don't change the topic!");
180 The last subroutine is nick_change:
187 if ($newnick eq $self->pocoirc->nick_name()) {
191 $self->pocoirc->yield('nick' => "$oldnick");
194 body => "If you don't mind, I'd like to use your old nick.",
198 Again, if the new nick is the same as the bot's current nick, we return
199 to prevent an infinite loop:
201 if ($newnick eq $self->pocoirc->nick_name()) {
205 We change the bot's nick to $oldnick:
207 $self->pocoirc->yield('nick' => "$oldnick");
209 Then have the bot send a message to the user who changed his nick:
213 body => "If you don't mind, I'd like to use your old nick.",
216 The last bit of code is similar to DiceBot. We create a GreetBot then run it:
220 my $bot = GreetBot->new(
221 server => 'irc.example.com',
223 channels => ['#perl102'],
229 ================================================================================
231 To learn more about the Bot::BasicBot framework, visit:
233 https://metacpan.org/pod/Bot::BasicBot
235 View the file ~/challenge to finish the lesson.
237 ================================================================================