POE::Session->create( package_states => [ main => [ qw(_default _start irc_public irc_join irc_botcmd_slap irc_botcmd_rot13) ], ], ); #### irc_botcmd_slap: 'foo!foo@workstation.local.tld' '#foo' 'foo' 'slap' 'slap' #### #!/usr/bin/perl use 5.010; use strict; use warnings; use POE; use Config::Any; use File::HomeDir; use Getopt::Long::Descriptive; use POE::Component::IRC::State; use POE::Component::IRC::Plugin::AutoJoin; use POE::Component::IRC::Plugin::BotCommand; my $home = File::HomeDir->my_home; # take options from command line my ($opt, $usage) = describe_options( "\%c \%o", [ "server-address|s=s" => 'IRC Server Address', ], [ "server-port|p=s" => 'IRC Server Port [default: 6667]', ], [ "protocol|P=s" => 'IRC Server Protocol [default: TCP]', ], [ "timeout|t=s" => 'IRC Server Connection Timeout (in seconds) [default: 30]', ], [ "channel|c=s" => 'IRC Channel', ], [ "config-name|n=s" => 'Config File Name', { default => 'testbot' }, ], [ "nick|N=s" => 'IRC Nick', ], [ "password|A=s" => 'IRC Password', ], [ "username|u=s" => 'IRC Username, defaults to Nick if unset', ], [ "hostname|h=s" => 'IRC Hostname', ], [ "desc|d=s" => 'IRC User Desc.', ], [], [ "verbose|v" => 'Print Status Messages' ], [ "help|h" => 'Print This message and Exit', ], ); ( print $usage->text ), exit if $opt->help; # get config name my $config = $opt->config_name; # look for config file my $cfg = Config::Any->load_stems( { stems => ["/etc/$config", "$home/etc/$config", "$home/etc/$config", "./etc/$config", "./$config", ], use_ext => 1, } ); # take only the last loaded config file my $last_config = shift @$cfg; my ($file_name, $loaded_config); if ($last_config) { ($file_name, $loaded_config) = %$last_config; } else { ($file_name, $loaded_config) = ('NONE', {} ); } say "[*] Loaded config file $file_name" if $opt->verbose; # Thinking about config file design, my $server_address = $opt->server_address || $loaded_config->{'server'}->{'address'} || 'myserver.net'; my $server_port = $opt->server_port || $loaded_config->{'server'}->{'port'} || '6667'; my $server_protocol = $opt->protocol || $loaded_config->{'server'}->{'protocol'} || 'tcp'; my $timeout = $opt->timeout || $loaded_config->{'server'}->{'timeout'} || '30'; my $channel = $opt->channel || $loaded_config->{'server'}->{'channel'} || [ '#foo',]; my $nick = $opt->nick || $loaded_config->{'user'}->{'nick'} || 'testbot'; my $password = $opt->password || $loaded_config->{'user'}->{'password'} || ''; my $username = $opt->username || $loaded_config->{'user'}->{'username'} || $nick; my $hostname = $opt->hostname || $loaded_config->{'user'}->{'hostname'} || 'foo.test.irc'; my $desc = $opt->desc || $loaded_config->{'user'}->{'desc'}; my $irc = POE::Component::IRC::State->spawn( nick => $nick, Username => $username, ircname => $desc, server => $server_address, ); POE::Session->create( package_states => [ main => [ qw(_default _start irc_public irc_join) ], ], ); $poe_kernel->run(); sub _start { $irc->plugin_add( 'BotCommand', POE::Component::IRC::Plugin::BotCommand->new( In_channels => 1, Addressed => 0, Commands => { slap => 'Takes one argument: a nickname to slap.', } ) ); $irc->plugin_add( 'AutoJoin', POE::Component::IRC::Plugin::AutoJoin->new( Channels => $channel, ), ); $irc->yield( register => 'all' ); $irc->yield( 'connect' ); return; } sub _default { my ($event, $args) = @_[ARG0 .. $#_]; my @output = ( "$event: " ); for my $arg (@$args) { if (ref $arg eq 'ARRAY') { push @output, '[' . join ', ', @$arg . ']'; } else { push @output, "'$arg'"; } } print join ' ', @output, "\n"; return; } sub irc_public { my ($sender, $who, $where, $what) = @_[SENDER, ARG0 .. ARG2]; my $nick = ( split /!/, $who )[0]; my $irc = $_[SENDER]->get_heap; if (my ($rot13) = $what =~ /^rot13 (.+)/ ) { $rot13 =~ tr/a-zA-Z/n-za-mN-ZA-M/; $irc->yield( privmsg => $where => "$nick: $rot13" ); } } sub irc_join { my $nick = (split /!/, $_[ARG0])[0]; my $channel = $_[ARG1]; my $irc = $_[SENDER]->get_heap; if ($nick eq $irc->nick_name) { $irc->yield(privmsg => $channel, "Hi Everybody!"); } else { $irc->yield(privmsg => $channel, "Hi $nick!"); } } # the good old slap sub irc_botcmd_slap { my $nick = (split /!/, $_[ARG0])[0]; my $channel = $_[ARG0]; my ($where, $arg) = @_[ARG1, ARG2]; $irc->yield(privmsg => $where, "ACTION slaps $arg where: $where $channel"); return; } #### -YourBot/#foo- Commands: lookup, slap -YourBot/#foo- For more details, use: !help