Annotation of ChivanetConvoBot/convobot, revision 1.3

1.1       snw         1: #!/usr/bin/env perl
                      2: 
                      3: # 
                      4: # ChivaNet Conversation Bot 
                      5: #  Copyright (C) 2025 Coherent Logic Development LLC
                      6: #
                      7: # Author: Serena Willis <snw@coherent-logic.com>
                      8: #
                      9: # Licensed AGPL-3.0
                     10: #
1.2       snw        11: # $Log: convobot,v $
1.3     ! snw        12: # Revision 1.2  2025/02/03 04:28:34  snw
        !            13: # Fix syntax message
        !            14: #
1.2       snw        15: # Revision 1.1.1.1  2025/02/03 04:22:49  snw
                     16: # Initial Commit
                     17: #
1.1       snw        18: #
                     19: #
                     20: 
                     21: use Net::OSCAR;
                     22: use Getopt::Long;
                     23: use Data::Dumper;
                     24: use HTML::Strip;
1.3     ! snw        25: use DBI;
1.1       snw        26: 
                     27: my $idlemax = 1800;
                     28: my $botsn = '';
                     29: my $botsrv = '';
                     30: my $botpw = '';
                     31: my $rasurl = '';
1.3     ! snw        32: 
        !            33: my $dbhost = '';
        !            34: my $dbname = '';
        !            35: my $dbusername = '';
        !            36: my $dbpw = '';
        !            37: my $dbconn = '';
        !            38: 
1.1       snw        39: my $chatroom = '';
                     40: my $online = 0;
                     41: my $chat_idle_seconds = 0;
                     42: my $last_chat_received = time();
                     43: my $start_time = time();
                     44: 
                     45: my @congregants = ();
                     46: my %seen = ();
                     47: 
                     48: GetOptions("aimsn=s" => \$botsn,
                     49:            "aimhost=s" => \$botsrv,
                     50:            "aimpw=s" => \$botpw,
                     51:            "idlemax=s" => \$idlemax,
1.3     ! snw        52:            "chatroom=s" => \$chatroom,
        !            53:            "dbhost=s" => \$dbhost,
        !            54:            "dbname=s" => \$dbname,
        !            55:            "dbusername=s" => \$dbusername,
        !            56:            "dbpw=s" => \$dbpw);
1.1       snw        57:             or die("error in command line arguments");
                     58: 
                     59: %signon = (
                     60:     screenname => $botsn,
                     61:     password => $botpw,
                     62:     host => $botsrv,
                     63: ); 
                     64: 
                     65: $oscar = Net::OSCAR->new();
1.3     ! snw        66: my $dbh = DBI->connect("DBI:mysql:database=$dbname;host=$dbhost",
        !            67:                        "$dbusername", "$dbpw",
        !            68:                        {'RaiseError' => 1});
        !            69: 
        !            70: sub get_seen_status {
        !            71:     my($sn) = @_;
        !            72: 
        !            73:     
        !            74: }
1.1       snw        75: 
                     76: sub signon_done {
                     77:     print "[OK]\n";
                     78:     $oscar->chat_join($chatroom, 5);   
                     79:     $online = 1;
                     80: }
                     81: 
                     82: sub chat_joined {
                     83:     my($oscar, $chatname, $chat) = @_;
                     84: 
                     85:     $room = $chat;
                     86:     bless $room, "Net::OSCAR::Connection::Chat";
                     87: }
                     88: 
                     89: sub chat_buddy_in {
                     90:     my ($oscar, $who, $chat, $buddy) = @_;
                     91: 
                     92:     $seen{$who} = localtime();
                     93:     
                     94:     if($who ne $botsn) {
                     95:         push(@congregants, $who);
                     96:         print "[$who] has joined\n";        
                     97:     }
                     98:     else {
                     99:         print "[$who] has joined (ignoring bot)\n";
                    100:     }
                    101: 
                    102:     if(time() - $start_time > 2) {
                    103:         my @phrases = ('Welcome to [room], [user]! :-)',
                    104:                        'How\'s it going, [user]?',
                    105:                        'Hey [user]! Bring any snacks?',
                    106:                        'Heya [user]! Hope your day is going well!',
                    107:                        'Ooo, [user] has joined [room]! Now the party can start!');
                    108:                 
                    109:         my $phrase = $phrases[rand @phrases];
                    110:         $phrase =~ s/\[user\]/$who/g;
                    111:         $phrase =~ s/\[room\]/$chatroom/g;       
                    112:         my $phrasefix = "<div id=convobot></div>$phrase";
                    113:         $chat->chat_send($phrasefix);
                    114:     }
                    115:     else {
                    116:         print "Not sending greeting for 2 seconds after startup\n";
                    117:     }
                    118: }
                    119: 
                    120: sub chat_buddy_out {
                    121:     my ($oscar, $who, $chat) = @_;
                    122:     my $index = 0;
                    123: 
                    124:     $index++ until $congregants[$index] eq $who;
                    125:     splice(@congregants, $index, 1);
                    126: 
                    127:     print "$who has left\n";
                    128: }
                    129: 
                    130: sub chat_im_in {
                    131:     my($oscar, $who, $chat, $message) = @_;
                    132: 
                    133:     my $hs = HTML::Strip->new();
                    134:     my $rawcmd = $hs->parse($message);
                    135:     my @cmd = split(' ', $rawcmd);
                    136: 
                    137:     $seen{$who} = localtime();
                    138:     
                    139:     if($cmd[0] eq "!seen") {
                    140:         if(exists($cmd[1])) {
                    141:             if(exists($seen{$cmd[1]})) {
                    142:                 $chat->chat_send("I last saw $cmd[1] at $seen{$cmd[1]}");
                    143:             }
                    144:             else {
                    145:                 $chat->chat_send("I've never seen $cmd[1]");
                    146:             }
                    147:         }
                    148:         else {
1.2       snw       149:             $chat->chat_send("Syntax: !seen <em>screenname</em>");
1.1       snw       150:         }
                    151:     }
                    152:     
                    153:         
                    154:     
                    155:     $last_chat_received = time();    
                    156: 
                    157:     print "chat received from $who; resetting idle counter\n";
                    158:     
                    159: }
                    160: 
                    161: sub send_idle_message {
                    162: 
                    163:     my @phrases = ('Hey [user]! How are you today?',
                    164:                    'I think [user] should bring us some pizza!',
                    165:                    'What\'s everyone up to here?',
                    166:                    'My, what a beautiful day for a chat here in [room]!',
                    167:                    '[user] always has the most interesting things to say.',
                    168:                    'Remember that time [user] was talking here in [room]?',
                    169:                    'What do all you [room] chatters think about pie?',
                    170:                    '[room] seems dead :\'(. That makes me sad! Maybe [user] has something interesting to say?');
                    171: 
                    172:     my $congregant = $congregants[rand @congregants];
                    173:     my $phrase = $phrases[rand @phrases];
                    174:     $phrase =~ s/\[user\]/$congregant/g;
                    175:     $phrase =~ s/\[room\]/$chatroom/g;    
                    176:     my $phrasefix = "<div id=convobot></div>$phrase";
                    177:     
                    178:     if(ref($room) eq "Net::OSCAR::Connection::Chat") {
                    179:         $room->chat_send($phrasefix);
                    180:         $last_chat_received = time();
                    181:     }
                    182: }
                    183: 
                    184: $oscar->set_callback_signon_done(\&signon_done);
                    185: $oscar->set_callback_chat_joined(\&chat_joined);
                    186: $oscar->set_callback_chat_buddy_in(\&chat_buddy_in);
                    187: $oscar->set_callback_chat_buddy_out(\&chat_buddy_out);
                    188: $oscar->set_callback_chat_im_in(\&chat_im_in);
                    189: 
                    190: print "ChivaNet Conversation Bot v0.0.1\n";
                    191: print " Copyright (C) 2025 Coherent Logic Development LLC\n\n";
                    192: 
                    193: print "bot:  attempting to sign in... ";
                    194: $oscar->signon(%signon);
                    195: 
                    196: while(1) {
                    197:     $oscar->do_one_loop();
                    198:     $chat_idle_seconds = time() - $last_chat_received;
                    199:     
                    200:     if($chat_idle_seconds > $idlemax) {
                    201:         send_idle_message();
                    202:     }
                    203: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>