This program is a very simple IRC bot. It connects to a network, joins a channel, and responds to "rot13" requests. It uses POE and POE::Component::IRC, which are Perl modules available on the CPAN.

#!/usr/bin/perl
# This is a simple IRC bot that just rot13 encrypts public messages.
# It responds to "rot13 <text to encrypt>".
use warnings;
use strict;
use POE;
use POE::Component::IRC;
sub CHANNEL () { "#poe" }

# Create the component that will represent an IRC network.
my ($irc) = POE::Component::IRC->spawn();

# Create the bot session.  The new() call specifies the events the bot
# knows about and the functions that will handle those events.
POE::Session->create(
  inline_states => {
    _start     => \&bot_start,
    irc_001    => \&on_connect,
    irc_public => \&on_public,
  },
);

# The bot session has started.  Register this bot with the "magnet"
# IRC component.  Select a nickname.  Connect to a server.
sub bot_start {
  $irc->yield(register => "all");
  my $nick = 'usepoe' . $$ % 1000;
  $irc->yield(
    connect => {
      Nick     => $nick,
      Username => 'cookbot',
      Ircname  => 'POE::Component::IRC cookbook bot',
      Server   => 'irc.rhizomatic.net',
      Port     => '6667',
    }
  );
}

# The bot has successfully connected to a server.  Join a channel.
sub on_connect {
  $irc->yield(join => CHANNEL);
}

# The bot has received a public message.  Parse it for commands, and
# respond to interesting things.
sub on_public {
  my ($kernel, $who, $where, $msg) = @_[KERNEL, ARG0, ARG1, ARG2];
  my $nick    = (split /!/, $who)[0];
  my $channel = $where->[0];
  my $ts      = scalar localtime;
  print " [$ts] <$nick:$channel> $msg\n";
  if (my ($rot13) = $msg =~ /^rot13 (.+)/) {
    $rot13 =~ tr[a-zA-Z][n-za-mN-ZA-M];

    # Send a response back to the server.
    $irc->yield(privmsg => CHANNEL, $rot13);
  }
}

# Run the bot until it is done.
$poe_kernel->run();
exit 0;

IRC Bots FAQ

Q: Quit messages don't work. My bots always report "Client Quit" or something.

A1: The server your bot connects to has enabled "static quit" messages. In other words, no matter what your bot (or your IRC client) reports, the quit message will not change.

A2: The server your bot connects to has enabled an anti-spamming feature. This feature prevents clients (and your bot) from sending custom quit messages until they have been connected for a certain amount of time. That time is 5 minutes by default. Your bot (and your IRC client) should report custom quit messages if you leave them online long enough.

Q2: How can I make it return multiple lines? For example, if instead of rot13 output, I instead want to tail a log file, is there a way to return a certain amount at once, rather than reading the output into an array and foreach'ing over each line? That method is very slow to return more than a few lines, but I understand the complication not flooding the channel.

A2: That'd be precisely what [one of Randal's columns] is about.