XMPP roster retrieval with perl

Here is a simple script for returning a user’s XMPP (Jabber) roster.

Nice summary from the Roster Management doc for the python-based SleekXMPP library:

In XMPP, the presence portion of the protocol is expressed through presence subscriptions between entities. The list of all of these subscriptions is called the roster, and you may think of it as a buddy list or contact list. Manually managing the roster is usually unnecessary since it is done by the server automatically when presence subscribe or unsubscribe requests are received and accepted. However, roster entries may be placed into groups or even removed. In those cases, manual management is needed.

The main point people need to get from this is that XMPP by its very nature is a distributed system. Servers in an XMPP environment act as conduits for communications between clients. There are important implications to this. While the server keeps track of a user’s presence for the purpose of sharing it with others, the master copy of that data resides on the client. Servers and clients are in constant communication to enable the server to know the client’s (and the client’s roster) state at all times. By design changes in rosters normally flow from the client to the server and it is not possible to read the roster of another user.

Further, this client-centric approach is one step away from purely peer-to-peer communications, and in fact some developers are working on employing WebRTC over XMPP to achieve this (servers will still be necessary in most environments to provide STUN services allowing clients to communicate across firewalls and NAT’d networks).

The following is a modified version of one of the examples provided in the Net::XMPP distribution for perl.

#!/usr/bin/perl
# roster-list.pl, list a user's roster
use Net::XMPP;
use strict;
use warnings;

my $server = "chat.example.com";
my $port = "5222";
my $username = "myuser";
my $domain = "chat.example.com";
my $password = "secret";
my $resource = "perl";

my $conn = Net::XMPP::Client->new(
    debuglevel=>1, debugfile=>"$0.debug.out", debuftime=>1
);
my $status = $conn->Connect(hostname=>$server, componentname=>$domain,
                            port=>$port,
                            tls=>1
                            );
if (!(defined($status))) {
    print "ERROR:  XMPP server is down or connection was not allowed.\n";
    print "        ($!)\n";
    exit(0);
}
my @result = $conn->AuthSend(username=>$username,
                             password=>$password,
                             resource=>$resource
                            );
if ($result[0] ne "ok") {
    print "ERROR: Authorization failed: $result[0] - $result[1]\n";
    exit(0);
}
print "Logged in to $server:$port...\n";
my %roster = $conn->RosterGet();
while (my ($id, $data) = each %roster) {
    print $id, ": ",  $data->{name}, "\n";
}
$conn->Disconnect();
__END__;
This entry was posted in Development, System Administration on by .

About phil

My name is Phil Lembo. In my day job I’m an enterprise IT architect for a leading distribution and services company. The rest of my time I try to maintain a semi-normal family life in the suburbs of Raleigh, NC. E-mail me at philipATlembobrothersDOTcom. The opinions expressed here are entirely my own and not those of my employers, past, present or future (except where I quote others, who will need to accept responsibility for their own rants).