root/branches/hackathon-mt/plagger/bin/plagger-ircbot

Revision 1045 (checked in by jbisbee, 3 years ago)

* change ->new('bot') to ->spawn( alias => 'bot' )
* add new event 'connect'
* move connect from bot_start to new bot_connect so that the

delay( connect => 60 ) will actually work ( delay only works

on the same session and can't post back to the PoCo?
IRC session
(aliases 'bot' session)

  • Property svn:executable set to *
  • Property svn:keywords set to Id Revision
Line 
1 #!/usr/bin/perl
2 use warnings;
3 use strict;
4
5 use FindBin;
6 use Getopt::Long;
7 use List::Util qw(first);
8 use YAML;
9
10 use POE qw(
11     Session
12     Component::IRC
13     Component::IKC::Server
14     Component::IKC::Specifier
15 );
16
17 sub msg (@) { print "[msg] ", "@_\n" }
18 sub err (@) { print "[err] ", "@_\n" }
19
20 my $path = "$FindBin::Bin/../config.yaml";
21 GetOptions("--config=s", \$path);
22 Getopt::Long::Configure("bundling"); # allows -c
23
24 msg "loading configuration $path";
25
26 my $config_yaml = YAML::LoadFile($path);
27 my $plugin = first { $_->{module} eq 'Notify::IRC' } @{ $config_yaml->{plugins} }
28     or die "Can't find Notify::IRC config in $path";
29
30 my $config = $plugin->{config};
31
32 msg 'creating daemon component';
33 POE::Component::IKC::Server->spawn(
34     port => $config->{daemon_port} || 9999,
35     name => 'NotifyIRCBot',
36 );
37
38 msg 'creating irc component';
39 POE::Component::IRC->spawn( alias => 'bot' )
40     or die "Couldn't create IRC POE session: $!";
41
42 msg 'creating kernel session';
43 POE::Session->create(
44     inline_states => {
45         _start           => \&bot_start,
46         _stop            => \&bot_stop,
47         connect          => \&bot_connect,
48         irc_001          => \&bot_connected,
49         irc_372          => \&bot_motd,
50         irc_433          => \&bot_nick_taken,
51         irc_disconnected => \&bot_reconnect,
52         irc_error        => \&bot_reconnect,
53         irc_socketerr    => \&bot_reconnect,
54         autoping         => \&bot_do_autoping,
55         update           => \&update,
56         _default         => $ENV{DEBUG} ? \&bot_default : sub { },
57     }
58 );
59
60 msg 'starting the kernel';
61 POE::Kernel->run();
62 msg 'exiting';
63 exit 0;
64
65 sub bot_default
66 {
67     my ( $event, $args ) = @_[ ARG0 .. $#_ ];
68     err "unhandled $event";
69     err "  - $_" foreach @$args;
70     return 0;
71 }
72
73 sub update
74 {
75     my ( $kernel, $heap, $msg ) = @_[ KERNEL, HEAP, ARG0 ];
76     eval {
77         for my $channel (@{ $config->{server_channels} }) {
78             if ($config->{announce} =~ /action/i) {
79                 $kernel->post( bot => ctcp => $channel, "ACTION $msg");
80             } else {
81                 $kernel->post( bot => notice => $channel, $msg )
82             }
83         }
84     };
85     err "update error: $@" if $@;
86 }
87
88 sub bot_start
89 {
90     my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
91     msg "starting irc session";
92     $kernel->alias_set('notify_irc');
93     $kernel->call( IKC => publish => notify_irc => ['update'] );
94     $kernel->post( bot => register => 'all' );
95     $kernel->yield('connect');
96 }
97
98 sub bot_connect
99 {
100     my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
101     msg "attempting to connect to server";
102     $kernel->post(
103         bot => connect => {
104             Nick     => $config->{nickname},
105             Ircname  => $config->{ircname} || $config->{nickname},
106             Username => $ENV{USER},
107             Server   => $config->{server_host},
108             Port     => $config->{server_port} || 6667,
109             Password => $config->{server_password} || undef,
110         }
111     );
112 }
113
114 sub bot_stop
115 {
116     msg "stopping bot";
117 }
118
119 sub bot_connected
120 {
121     my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
122     foreach ( @{$config->{server_channels}} )
123     {
124         msg "joining channel $_";
125         $kernel->post( bot => join => $_ );
126         if ($config->{charset}) {
127             $kernel->post( bot => charset => $config->{charset} );
128         }
129     }
130 }
131
132 sub bot_motd
133 {
134     msg '[motd] ' . $_[ARG1];
135 }
136
137 sub bot_do_autoping
138 {
139     my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
140     $kernel->post( bot => userhost => $config->{nickname} )
141         unless $heap->{seen_traffic};
142     $heap->{seen_traffic} = 0;
143     $kernel->delay( autoping => 300 );
144 }
145
146 sub bot_reconnect
147 {
148     my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
149     err "reconnect: " . $_[ARG0];
150     $kernel->delay( autoping => undef );
151     $kernel->delay( connect  => 60 );
152 }
153
154 sub bot_nick_taken
155 {
156     my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
157     if ($config->{nick} !~ /\d$/) {
158         $config->{nick} .= 0;
159     } else {
160         substr( $config->{nick}, -1, 1 )++;
161     }
162     err 'nick taken, trying new nick ' . $config->{nick};
163     $kernel->post( bot => nick => $config->{nick} );
164     $heap->{seen_traffic} = 1;
165 }
Note: See TracBrowser for help on using the browser.