Personal Jabber Server
The following started out as an exploration of erlang
, but the side trip has proven interesting enough to merit its own entry. Accordingly, here are notes regarding the installation of a personal (or “workgroup”, if you prefer) Jabber server on a home LAN. Beware, specific user and host names are filled in, as well as a dummy password; adjust as required.
To start:
sudo apt-get install ejabberd sudo chown rubys:rubys .erlang.cookie
The first command installs the server. The second command is quite optional, but may be helpful later if you experiment with erlang
. The plus side of installing this way is that the installation is standard and will be kept up to date with the distribution. The downside is that the initial install wizard that comes with ejabberd isn’t run, so three small configuration steps are required.
First, sudo vi /etc/ejabberd/ejabberd.cfg
.
Now uncomment out one of the administrators, and set it to your preferred user id:
%{acl, admin, {user, "aleksey"}}. {acl, admin, {user, "rubys"}}.
Next, the default setup will insert what this machine knows itself by into the configuration, but what you actually want is what other machines on this LAN know this machine as, so make the following change:
{hosts, ["localhost"]}. {hosts, ["rubix"]}.
Now, write and exit that configuration file, restart the server, and add your user:
sudo /etc/init.d/ejabberd restart sudo ejabberdctl register rubys rubix password
You can now perform administration functions from any machine on your LAN thus:
http://rubix:5280/admin/ user: rubys@rubix password: password
Configuring GAIM/Pidgin
Adding the account couldn’t be easier. Accounts, Add/Edit, Add:
Protocol: | Jabber |
Screen name: | rubys |
Server: | rubix |
Resource: | Laptop |
Password: | password |
At this point, you can receive messages or add buddies.
Command line client
sendxmpp is a command line client (written in Perl). Install it, and configure your default user, server, and password information:
apt-get install sendxmpp vi ~/.sendxmpprc rubys@rubix password :x chmod 0600 .sendxmpprc
You can now send messages to yourself via:
echo -n hi | sendxmpp -r echocmd rubys@rubix
Ruby library
While Jabber (the protocol) allows Jabber IDs to be used by multiple resources (/Laptop and /echocmd are examples above), I couldn’t get this to work with the “simple” Ruby and Python libraries. No problem: since this is your server, creating new IDs are a piece of cake:
sudo ejabberdctl register george rubix password
Note: the first time you receive a message from any new Jabber ID, you will need to confirm it in your GAIM window.
Now install xmpp4r-simple:
sudo apt-get install libxmpp4r-ruby1.8 libopenssl-ruby sudo gem install xmpp4r-simple
You can now send yourself a message from irb:
require 'rubygems' require 'xmpp4r-simple' jabber = Jabber::Simple.new('george@rubix','password') jabber.deliver('rubys@rubix','hello world') jabber.disconnect
Note: if this is a program, a sleep 1
before the disconnect is handy, otherwise the message may be lost.
Python client
Install python-xmpp:
sudo apt-get install python-xmpp python-dns
Here’s it in action:
import xmpp jid=xmpp.protocol.JID('george@rubix') cl=xmpp.Client(jid.getDomain(),debug=[]) cl.connect() cl.auth(jid.getNode(),'password') cl.send(xmpp.protocol.Message('rubys@rubix','hi there')) cl.disconnect()
Uses
At the moment, I’m primarily using this for “best effort delivery” of notification of events for various background processes I have running. If I’m not online, ejabberd will apparently queue up the messages. Being able to send these messages from the command line, Python, or Ruby makes integration easy. Of course, there are plenty of other libraries spanning most of the popular languages. And anything available to these languages, are accessible via ssh or CGI or any other means you may have set up to tunnel into your LAN from the outside.
For example, Planet Intertwingly reflects my predilection for Atom 1.0 feeds. At first, I periodically spot checked feeds. Then I produced a template which produces a report every time the page is generated. Now I’ve completely automated the check so that I’m notified if any of the feeds is ever replaced by a feed of another flavor by the following small script:
require 'rexml/document' require 'rubygems' require 'xmpp4r-simple' VALIDATE = '/home/rubys/public_html/planet/validate.html' jabber = nil doc = REXML::Document.new(open(VALIDATE)) REXML::XPath.match(doc,'//tr[td[3] != "atom10"]').each do |tr| jabber = Jabber::Simple.new('planet@rubix','password') unless jabber message = "#{tr.elements['td[3]'].text}: #{tr.elements['td[2]/a'].text}" jabber.deliver 'rubys@rubix', message end sleep 2; jabber.disconnect if jabber
Another use that I haven’t explored yet: jabber-bots.