IRC-Bot

 view release on metacpan or  search on metacpan

Bot.pm  view on Meta::CPAN

use POSIX qw( setsid );
use IRC::Bot::Log;
use IRC::Bot::Seen;
use IRC::Bot::Auth;
use IRC::Bot::Help;
use IRC::Bot::Quote;
use constant NICK => 'bot';

require Exporter;

@ISA     = qw(Exporter AutoLoader);
@EXPORT  = qw();
$VERSION = '0.07';

# Set us up the bomb
sub new {

    my $class = shift;
    my %args  = @_;
    return bless \%args, $class;

}

# Run the bot
sub run {

    my $self = shift;
    if ($self->{'LogPath'} eq '') {
      $self->{'LogPath'} = $ENV{'HOME'} . "/";
    }
    $log = IRC::Bot::Log->new( 'Path' => $self->{'LogPath'} );
    $seen = IRC::Bot::Seen->new();
    $auth = IRC::Bot::Auth->new();
    $help = IRC::Bot::Help->new();
    $quote = IRC::Bot::Quote->new();

    POE::Component::IRC->new(NICK)
      || croak "Cannot create new P::C::I object!\n";

    POE::Session->create(
        object_states => [
            $self => {
                _start           => "bot_start",
                irc_001          => "on_connect",
                irc_disconnected => "on_disco",
                irc_public       => "on_public",
                irc_msg          => "on_msg",
                irc_quit         => "on_quit",
                irc_join         => "on_join",
                irc_part         => "on_part",
                irc_mode         => "on_mode",
                irc_kick         => "on_kick",
                irc_notice       => "on_notice",
                irc_ctcp_ping    => "on_ping",
                irc_ctcp_version => "on_ver",
                irc_ctcp_finger  => "on_finger",
                irc_ctcp_page    => "on_page",
                irc_ctcp_time    => "on_time",
                irc_ctcp_action  => "on_action",
                irc_nick         => "on_nick",
                keepalive        => "keepalive",
                irc_433          => "on_nick_taken",
                irc_353          => "on_names",
                irc_dcc_request  => "on_dcc_req",
                irc_dcc_error    => "on_dcc_err",
                irc_dcc_done     => "on_dcc_done",
                irc_dcc_start    => "on_dcc_start",
                irc_dcc_chat     => "on_dcc_chat",

            }
        ]
    );
    $poe_kernel->run();
}

# Start the bot things up
sub bot_start {

    my ( $self, $kernel, $session ) = @_[ OBJECT, KERNEL, SESSION ];

    my $ts = scalar(localtime);
    $log->serv_log("[$ts] Starting Up...");

    $kernel->post( NICK, 'register', 'all' );
    $kernel->post(
        NICK,
        'connect',
        {
            Debug    => $self->{'Debug'},
            Nick     => $self->{'Nick'},
            Server   => $self->{'Server'},
            Port     => $self->{'Port'},
            Username => $self->{'Username'},
            Password => $self->{'Password'},
            Ircname  => $self->{'Ircname'},
	    NSPass   => $self->{'NSPass'}
        }
    );
    $kernel->delay( 'reconnect', 20 );
}

# Handle connect event
# Join specified channels
sub on_connect {

    my ( $self, $kernel ) = @_[ OBJECT, KERNEL ];
    $kernel->post( NICK, 'mode', $self->{'Nick'}, '+B' );
    if ($self->{'NSPass'}) {
      my $msg = "identify " . $self->{'NSPass'};
      $self->botspeak( $kernel, 'NickServ', $msg );
    }
    foreach my $chan ( @{ $self->{'Channels'} } ) {
        $kernel->post( NICK, 'join', $chan );
    }
}

# Someone pinged us, handle it.
sub on_ping {

    my ( $self, $kernel, $who ) = @_[ OBJECT, KERNEL, ARG0 ];
    my $nick = ( split /!/, $who )[0];

Bot.pm  view on Meta::CPAN

    my $time = sprintf( "%02d:%02d", ( localtime( time() ) )[ 2, 1 ] );
    $log->chan_log("[$chan $time] KICK: $nick: $kickee ($msg)");

}

# Handle someone quitting.
sub on_quit {

    my ( $self, $kernel, $who, $msg ) = @_[ OBJECT, KERNEL, ARG0, ARG1 ];
    my $nick = ( split /!/, $who )[0];
    my $time = sprintf( "%02d:%02d", ( localtime( time() ) )[ 2, 1 ] );
    $log->serv_log("[$self->{'Nick'} $time] QUIT: $nick: $msg");
    $seen->log_seen( $nick, "Quit: $msg" );

}

# Handle join event
sub on_join {

    my ( $self, $kernel, $who, $where ) = @_[ OBJECT, KERNEL, ARG0, ARG1 ];
    my $nick = ( split /!/, $who )[0];
    my $time = sprintf( "%02d:%02d", ( localtime( time() ) )[ 2, 1 ] );
    $log->chan_log("[$where $time] JOIN: $nick");
    $seen->log_seen( $nick, "Joining $where" );

}

# Handle part event
sub on_part {

    my ( $self, $kernel, $who, $where ) = @_[ OBJECT, KERNEL, ARG0, ARG1 ];
    my $nick = ( split /!/, $who )[0];
    my $time = sprintf( "%02d:%02d", ( localtime( time() ) )[ 2, 1 ] );
    $log->chan_log("[$where $time] PART: $nick");
    $seen->log_seen( $nick, "Parting $where" );

}

# Changes nick if current nick is taken
sub on_nick_taken {

    my ( $self, $kernel ) = @_[ OBJECT, KERNEL ];
    my $nick  = $self->{'Nick'};
    my $rnick = int( rand(999) );
    $kernel->post( NICK, 'nick', "$nick$rnick" );

}

# Communicate with channel/nick
sub botspeak {

    my ( $self, $kernel, $channel, $msg ) = @_;
    $kernel->post( NICK, 'privmsg', $channel, $msg );

}

# Borrowed this code from another bot
# Can't for the life of me remember which one
# Please, let me know if it was you, so I can
# give props!!
sub keepalive {

    my ( $self, $kernel, $heap ) = @_[ OBJECT, KERNEL, HEAP ];
    $heap->{'keepalive_time'} += 180;
    $kernel->alarm( 'keepalive' => $heap->{'keepalive_time'} );
    $kernel->post( NICK, 'sl', 'PING ' . time() );

}

# Handle public events
sub on_public {

    my ( $self, $kernel, $who, $where, $msg ) =
      @_[ OBJECT, KERNEL, ARG0 .. $#_ ];
    my $nick = ( split /!/, $who )[0];
    my $channel = $where->[0];
    my $pubmsg  = $msg;
    my $time    = sprintf( "%02d:%02d", ( localtime( time() ) )[ 2, 1 ] );
    $log->chan_log("[$channel $time] <$nick> $msg");

    if ( $msg =~ m/^!help$/i ) {

        my %pubHelp = $help->pub_help();
        $self->botspeak( $kernel, $channel, "Here is the help you requested:" );
        foreach my $keys ( keys %pubHelp ) {
            $self->botspeak( $kernel, $channel, $pubHelp{$keys} );
        }

    }
    elsif ( $msg =~ m/^!ping$/i ) {

        $self->botspeak( $kernel, $channel, "Pong!" );

    }
    elsif ( $msg =~ m/^!uptime$/i ) {

        my $time = sprintf( "%d Days, %02d:%02d:%02d",
            ( gmtime( time() - $^T ) )[ 7, 2, 1, 0 ] );
        $self->botspeak( $kernel, $channel, "I've been up for $time" );

    }
    elsif ( $msg =~ m/^!seen/i ) {

        my @arg = split ( / /, $msg );
        my $name = $arg[1];

        if ($name) {

            my $fseen = $seen->get_seen($name) || undef;

            if ( $name eq $nick ) {
                $self->botspeak( $kernel, $channel,
                    "Looking for yourself, $nick?" );
            }
            elsif ( $name eq $self->{'Nick'} ) {
                $self->botspeak( $kernel, $channel, "I'm right here, foo!" );
            }
            elsif ( defined $fseen ) {
                $self->botspeak( $kernel, $channel, $fseen );
            }
            else {
                $self->botspeak( $kernel, $channel,
                    "Sorry, $nick, I haven't seen $name." );
            }
        }



( run in 2.117 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )