#!/usr/bin/perl -w
# $Id: message_monitor.pl 285 2003-01-15 12:55:55Z ralphm $
use strict;
use open ':utf8';
use Jabber::Connection;
use Jabber::NodeFactory;
use Jabber::NS qw(:all);
use DBI;
use XML::Simple;
use Getopt::Long;
# Fetch command-line options
my %optctl = ();
$optctl{config} = "";
&GetOptions(\%optctl, "config=s");
$optctl{config} = undef unless ($optctl{config} ne "");
# Read config file
my $config = XMLin($optctl{config});
# Create a new node factory
my $nf = new Jabber::NodeFactory;
# Create a new db connection
my ($dbh, $sth);
&db_connect;
# Update process list entry
$dbh->do("DELETE FROM process_list WHERE name='message_monitor'");
$dbh->do("INSERT INTO process_list (name, pid) VALUES ('message_monitor', $$)");
# Open connection to Jabber server
my $c = new Jabber::Connection(
server => $config->{jabber}->{server},
log => 1,
debug => 1,
);
$c->connect or die "oops: ".$c->lastError;
# Register various handlers
$c->register_handler('message', \&message);
$c->register_beat(5, \&send_queued_messages);
# Identify and authenticate with the server
$c->auth($config->{jabber}->{username},
$config->{jabber}->{password},
$config->{jabber}->{resource});
# Send presence
$c->send('1');
# Start processing loop
$c->start();
#
# db_connect - connect to the database
#
sub db_connect {
$dbh = DBI->connect("dbi:Pg:dbname=".$config->{database}->{name})
or die "Cannot connect to database ($!)\n";
}
#
# getdata - return the data inside the element with name $name or empty
#
sub getdata {
my $node = shift;
my $name = shift;
my $tag;
return ($tag = $node->getTag($name)) ? $tag->data : "";
}
#
# send_queued_messages - sends out messages stored in the database
#
sub send_queued_messages {
my ($row, $m, $sth2);
# check if we still have a valid database connection
$dbh->ping or &db_connect;
# prepare sql statements we use later on
$sth = $dbh->prepare('SELECT "id", "to", "from", "message" FROM messages '.
'WHERE incoming is null');
$sth2 = $dbh->prepare('DELETE FROM messages WHERE "id"=?');
# fetch outgoing messages
$sth->execute();
while ($row = $sth->fetchrow_hashref) {
print STDERR "Sending message to ", $row->{'to'}, ":\n";
print STDERR $row->{'message'}, "\n\n";
# create new node
$m = $nf->newNode('message');
$m->attr('type', 'normal');
$m->attr('to', $row->{'to'});
# The 'from' value in this case is a session id. This way replies
# can be directed to the other party
if ($row->{'from'}) {
print STDERR $row->{'from'} . "\n";
$m->attr('from', $config->{jabber}->{username} . '@' .
$config->{jabber}->{server} . '/' . $row->{'from'});
}
$m->insertTag('body')->data($row->{'message'});
# send out the message
$c->send($m);
# delete the message from the queue
$sth2->execute($row->{'id'});
}
}
#
# message - stores incoming messages in the database
#
sub message {
my $node = shift;
my $to = $node->attr('to');
my $from = $node->attr('from');
my $message = getdata($node, 'body');
print STDERR "Received message from $from to $to:\n";
print STDERR "$message\n";
print STDERR "\n";
if ($to =~ /^([^\/]+)\/(.+)/) {
# check if we still have a valid database connection
$dbh->ping or &db_connect;
# store the message
$sth = $dbh->prepare(
'INSERT INTO messages ("to", "from", "message", "incoming") '.
'VALUES (?,?,?,?)'
);
$sth->execute($2, $from, $message, 'Y');
}
}