================================================================================ AutoGreet Explained The first 6 lines of autogreet.pl are similar to dicebot.pl from the previous lesson: #!/usr/bin/perl use strict; use warnings; package GreetBot; use base qw(Bot::BasicBot); The only difference is we changed the package to GreetBot instead of DiceBot. Next, we have our first subroutine chanjoin, which greets new users whenever one joins a channel. sub chanjoin { my $self = shift; my $arguments = shift; my $nick = $arguments->{who}; if ($nick eq $self->pocoirc->nick_name()) { return; } $self->say( channel => $arguments->{channel}, body => "Welcome, $nick!", ); } We store the user's nick in $nick: my $nick = $arguments->{who}; Afterwards, we check if the new user's nick, $nick, is the same as our bot's nick, $self->pocoirc->nick_name(). When the bot itself first joins a channel, chanjoin is called. We don't want the bot to greet itself, so we skip it with return. if ($nick eq $self->pocoirc->nick_name()) { return; } The return statement exits a subroutine without executing any of the code that comes after it: Next, we tell the bot to send a message to the channel to greet the new user: $self->say( channel => $arguments->{channel}, body => "Welcome, $nick!", ); Up next is the subroutine chanpart. It is called whenever a user parts from a channel. It tells the bot to send a message whenever a user leaves: sub chanpart { my $self = shift; my $arguments = shift; $self->say( channel => $arguments->{channel}, body => "I'm sad to see $arguments->{who} go.", ); } Take a closer look at the value of body: body => "I'm sad to see $arguments->{who} go.", Notice that $arguments->{who} is put right inside the quotation marks, but the message does not literally have the string "$arguments->{who}". Instead, perl evalutes $arguments->{who} to get the user's nick, then puts that value into the string. We do something different for the subroutine emoted. Instead of merely sending a message, we will emote it (send an action message): sub emoted { my $self = shift; my $arguments = shift; $self->emote( channel => $arguments->{channel}, body => "$arguments->{body} too", ); } On many irc clients, you can type /me to emote. Watch the bot emote back! In the subroutine noticed, we use an array for @notices: sub noticed { my $self = shift; my $arguments = shift; my $nick = $arguments->{who}; my @notices = ( "$nick, please resend this in a normal message", "I'm having a hard time reading your notice.", "Good point, $nick.", "Can you message on the public channel instead?", ); $self->notice( who => $nick, channel => $arguments->{channel}, body => $notices[int(rand(4))], ); } When you send a notice to the bot or to a channel the bot is in, it will reply with one of four different notices: my @notices = ( "$nick, please resend this in a normal message", "I'm having a hard time reading your notice.", "Good point, $nick.", "Can you message on the public channel instead?", ); The sigil (the symbol before a variable) for an array is @. An array can begin with an open and close parenthesis ( ) and the items inside are separated with commas ,. @notices has four strings. Those strings use double quotes so that the variables inside will get interpolated. An array stores many items, each one with a unique index. The first element of the array @notices is $notices[0]. The second element is $notices[1], and the third is $notices[2]. Arrays in Perl (like in most programming languages) begin with 0 as the first index. body => $notices[int(rand(4))], rand(n) will return a random float between 0 and n. int() *truncates* the float, meaning it drops everything after the decimal point. For example, int(3.1415) gets *truncated* to 3: everything after the decimal point gets ignored. int(rand(4)) gives a random integer from 0 to 3, which we use as the index for $notices. In other words, the body is a random notice chosen from an array of four notices. In the subroutine topic, anytime the topic is changed, the bot will add a short warning to the end of it: sub topic { my $self = shift; my $arguments = shift; if ($arguments->{who} eq $self->pocoirc->nick_name()) { return; } $self->pocoirc->yield('topic' => $arguments->{channel} => "$arguments->{topic} || Don't change the topic!"); } If the new nick $arguments->{who} is the same as the bot's current nick $self->pocoirc->nick_name(), then we return and do nothing. This line is necessary to prevent an infinite loop. Without this line, if the bot changes the topic, the subroutine topic will get called again, causing the bot to again change the topic. if ($arguments->{who} eq $self->pocoirc->nick_name()) { return; } The bot will change the topic in the current channel to a new topic. This topic contains the original topic plus "|| Don't change the topic!": $self->pocoirc->yield('topic' => $arguments->{channel} => "$arguments->{topic} || Don't change the topic!"); The last subroutine is nick_change: sub nick_change { my $self = shift; my $oldnick = shift; my $newnick = shift; if ($newnick eq $self->pocoirc->nick_name()) { return; } $self->pocoirc->yield('nick' => "$oldnick"); $self->say( who => "$newnick", body => "If you don't mind, I'd like to use your old nick.", ); } Again, if the new nick is the same as the bot's current nick, we return to prevent an infinite loop: if ($newnick eq $self->pocoirc->nick_name()) { return; } We change the bot's nick to $oldnick: $self->pocoirc->yield('nick' => "$oldnick"); Then have the bot send a message to the user who changed his nick: $self->say( who => "$newnick", body => "If you don't mind, I'd like to use your old nick.", ); The last bit of code is similar to DiceBot. We create a GreetBot then run it: package main; my $bot = GreetBot->new( server => 'irc.example.com', port => '6667', channels => ['#perl102'], nick => 'nickname', name => 'username', ); $bot->run(); ================================================================================ To learn more about the Bot::BasicBot framework, visit: https://metacpan.org/pod/Bot::BasicBot View the file ~/challenge to finish the lesson. ================================================================================