--- ChivanetConvoBot/convobot 2025/02/03 04:22:49 1.1 +++ ChivanetConvoBot/convobot 2025/02/03 17:31:28 1.4 @@ -9,8 +9,17 @@ # Licensed AGPL-3.0 # # $Log: convobot,v $ -# Revision 1.1 2025/02/03 04:22:49 snw -# Initial revision +# Revision 1.4 2025/02/03 17:31:28 snw +# Further MySQL work +# +# Revision 1.3 2025/02/03 15:38:12 snw +# Begin SQL work +# +# Revision 1.2 2025/02/03 04:28:34 snw +# Fix syntax message +# +# Revision 1.1.1.1 2025/02/03 04:22:49 snw +# Initial Commit # # # @@ -19,12 +28,21 @@ use Net::OSCAR; use Getopt::Long; use Data::Dumper; use HTML::Strip; +use DBI; my $idlemax = 1800; my $botsn = ''; my $botsrv = ''; my $botpw = ''; my $rasurl = ''; + +my $dbhost = ''; +my $dbname = ''; +my $dbusername = ''; +my $dbpw = ''; +my $dbconn = ''; +my $autogreet = 'off'; + my $chatroom = ''; my $online = 0; my $chat_idle_seconds = 0; @@ -32,30 +50,55 @@ my $last_chat_received = time(); my $start_time = time(); my @congregants = (); -my %seen = (); -GetOptions("aimsn=s" => \$botsn, - "aimhost=s" => \$botsrv, - "aimpw=s" => \$botpw, - "idlemax=s" => \$idlemax, - "chatroom=s" => \$chatroom) - or die("error in command line arguments"); +$oscar = Net::OSCAR->new(); -%signon = ( - screenname => $botsn, - password => $botpw, - host => $botsrv, -); +sub get_seen_status { + my($sn, $chat) = @_; -$oscar = Net::OSCAR->new(); -#$room = Net::OSCAR::Connection::Chat; + my $sth = $dbh->prepare("SELECT * FROM seen WHERE aim_server=? AND aim_sn=? AND aim_chatroom=? AND sn=?"); + $sth->execute($botsrv, $botsn, $chatroom, $sn); + + if($sth->rows > 0) { + my $hashref = $sth->fetchrow_hashref(); + $chat->chat_send("I last saw $sn on $hashref->{seen_time}."); + } + else { + $chat->chat_send("I have never seen $sn."); + } + +} + +sub update_seen_status { + my($sn) = @_; + + my $del = $dbh->prepare("DELETE FROM seen WHERE aim_server=? AND aim_sn=? AND aim_chatroom=? AND sn=?"); + $del->execute($botsrv, $botsn, $chatroom, $sn); + + my $ins = $dbh->prepare("INSERT INTO seen (aim_server, aim_sn, aim_chatroom, sn, seen_time) VALUES (?, ?, ?, ?, ?"); + $ins->execute($botsrv, $botsn, $chatroom, $sn, localtime); +} sub signon_done { print "[OK]\n"; - $oscar->chat_join($chatroom, 5); + print "Joining $chatroom..."; + $oscar->chat_join($chatroom, 5); + print "[OK]\n"; $online = 1; } +sub oscar_error { + my($oscar, $connection, $error, $description, $fatal) = @_; + + if($fatal != 0) { + die "\nFatal OSCAR error: $description\n"; + } + else { + print "\nRecoverable OSCAR error: $description\n"; + } + +} + sub chat_joined { my($oscar, $chatname, $chat) = @_; @@ -66,7 +109,7 @@ sub chat_joined { sub chat_buddy_in { my ($oscar, $who, $chat, $buddy) = @_; - $seen{$who} = localtime(); + update_seen_status($who); if($who ne $botsn) { push(@congregants, $who); @@ -76,21 +119,24 @@ sub chat_buddy_in { print "[$who] has joined (ignoring bot)\n"; } - if(time() - $start_time > 2) { - my @phrases = ('Welcome to [room], [user]! :-)', - 'How\'s it going, [user]?', - 'Hey [user]! Bring any snacks?', - 'Heya [user]! Hope your day is going well!', - 'Ooo, [user] has joined [room]! Now the party can start!'); - - my $phrase = $phrases[rand @phrases]; - $phrase =~ s/\[user\]/$who/g; - $phrase =~ s/\[room\]/$chatroom/g; - my $phrasefix = "
$phrase"; - $chat->chat_send($phrasefix); - } - else { - print "Not sending greeting for 2 seconds after startup\n"; + + if($autogreet eq "on") { + if(time() - $start_time > 2) { + my @phrases = ('Welcome to [room], [user]! :-)', + 'How\'s it going, [user]?', + 'Hey [user]! Bring any snacks?', + 'Heya [user]! Hope your day is going well!', + 'Ooo, [user] has joined [room]! Now the party can start!'); + + my $phrase = $phrases[rand @phrases]; + $phrase =~ s/\[user\]/$who/g; + $phrase =~ s/\[room\]/$chatroom/g; + my $phrasefix = "
$phrase"; + $chat->chat_send($phrasefix); + } + else { + print "Not sending greeting for 2 seconds after startup\n"; + } } } @@ -111,19 +157,14 @@ sub chat_im_in { my $rawcmd = $hs->parse($message); my @cmd = split(' ', $rawcmd); - $seen{$who} = localtime(); + update_seen_status($who); if($cmd[0] eq "!seen") { if(exists($cmd[1])) { - if(exists($seen{$cmd[1]})) { - $chat->chat_send("I last saw $cmd[1] at $seen{$cmd[1]}"); - } - else { - $chat->chat_send("I've never seen $cmd[1]"); - } + get_seen_status($cmd[1], $chat); } else { - $chat->chat_send("Syntax: !seen "); + $chat->chat_send("Syntax: !seen screenname"); } } @@ -163,10 +204,46 @@ $oscar->set_callback_chat_joined(\&chat_ $oscar->set_callback_chat_buddy_in(\&chat_buddy_in); $oscar->set_callback_chat_buddy_out(\&chat_buddy_out); $oscar->set_callback_chat_im_in(\&chat_im_in); +$oscar->set_callback_error(\&oscar_error); print "ChivaNet Conversation Bot v0.0.1\n"; print " Copyright (C) 2025 Coherent Logic Development LLC\n\n"; +GetOptions("aimsn=s" => \$botsn, + "aimhost=s" => \$botsrv, + "aimpw=s" => \$botpw, + "idlemax=s" => \$idlemax, + "chatroom=s" => \$chatroom, + "dbhost=s" => \$dbhost, + "dbname=s" => \$dbname, + "dbusername=s" => \$dbusername, + "dbpw=s" => \$dbpw, + "autogreet=s" => \$autogreet) + or die("error in command line arguments"); + +%signon = ( + screenname => $botsn, + password => $botpw, + host => $botsrv, +); + +print "AIM Server: $botsrv\n"; +print "AIM Screen Name: $botsn\n"; +print "Chat Room: $chatroom\n"; +print "DB Host: $dbhost\n"; +print "DB Name: $dbname\n"; +print "DB Username: $dbusername\n"; +print "Idle before ping: $idlemax\n"; +print "Auto-Greet: $autogreet\n\n"; + +print "Connecting to database $dbname\@$dbhost..."; + +my $dsn = "DBI:mysql:database=$dbname;host=$dbhost;port=3306;mysql_connect_timeout=5;"; +my $dbh = DBI->connect($dsn, $dbusername, $dbpw, {RaiseError => 1}); +die "Failed to connect to MySQL database: DBI->errstr()" unless $dbh; + +print "[OK]\n"; + print "bot: attempting to sign in... "; $oscar->signon(%signon);