IRC Bot

2011-02-15

A while ago I started writing a bot for IRC. It will listen to everything that is written in a particular channel, interpret the text, and generate output. I wrote the bot in Perl where there were an easy to use library to use IRC in Perl. The library is called Net::IRC and can for example be downloaded in Debian with the command: apt-get install libnet-irc-perl.

Net::IRC development stopped in 2004, but it works and is easy to use. You can read about how Net::IRC works on CPAN. Do you want to use a newer library with more functionality, you can look at POE::Component::IRC. I will in this article show how a simple bot can be written.

The code is written so that you can copy all the code into a text file and run it. You only need to set the parameters at the beginning of the script. The following code creates a connection to the IRC server:


#!/usr/bin/perl

#Loading modules
use Net::IRC;

#Defining connection variables
my($irc_server) = "irc_server";
my($irc_port) = "6667";
my($irc_nick) = "Bot";
my($irc_name) = "GreetingBot";
my($irc_username) = "GreetingBot";

#Collect channel name from first argument
if(scalar(@ARGV) > 0)
{
    my($irc_channel) = "#".$ARGV[0];
}
my($irc_channel) = "#".$ARGV[0];
#Create handles for IRC connections
my($connection) = new Net::IRC;
my($irc) = $connection->newconn(Server => $irc_server, Port => $irc_port, Nick => $irc_nick, Ircname => $irc_name, Username => $irc_username);
$irc->{channel} = $irc_channel;

The following code shows some different functions that run at different events in the channel. There are many more but these are examples of some basic functions.

#Function that runs when a user joins the channel
sub on_join
{
    my($irc, $event) = @_;
    #Get the nick of the user
    my($nick) = $event->{nick};
    #Checks that the bot doesn't answer itself
    if($nick ne $irc_nick)
    {
        #Say something in the channel when a new user joins
        $irc->privmsg($irc->{channel}, "Hello $nick!");
    }
}

#Function that runs when someone send a private message to the bot
sub on_msg
{
    my($irc, $event) = @_;
    #get the nick of the user
    my($nick) = $event->{nick};
    #Get the message
    my($text) = $event->{args}[0];

    #Return a message to the sender. You can process the message to generate an answer.
    $irc->privmsg($event->{nick}, "Hello $nick! ");
}

#Function that runs when any user says something
sub on_public
{
    my($irc, $event) = @_;
    #Get the nick of the user
    my($nick) = $event->{nick};
    #Get the message
    my($text) = $event->{args}[0];

    #Checks for messages aimed for the bot and returns an answer.
    if($text =~ /^Bot:/i){
        $irc->privmsg($event->{to}[0], "$nick: Hello!");
    }
}

#Function that runs when the bot connects to the IRC server
sub on_connect
{
    my($irc) = shift;
    $irc->join($irc->{channel});
    print "Connecting to channel ".$irc->{channel}."\n";
    #If you want the bot to say something when it joins the channel
    $irc->privmsg($irc->{channel}, 'God morning!');
    $irc->{connected} = 1;
}

The following code connects various events to the functions we wrote earlier. Then it starts the IRC loop that is listening for incoming messages.

#Create handles
$irc->add_handler('376', \&on_connect);
$irc->add_handler('join', \&on_join);
$irc->add_handler('msg', \&on_msg);
$irc->add_handler('public', \&on_public);

#Start the bot
$connection->start();

You can start the bot with the following command in a GNU/Linux terminal.

perl bot.pl channel_name