jabbot - the universal Jabber bot framework

jabbot lets you write Jabber bots in a matter of seconds. It connects to a Jabber server and translates all communication to stdin/stdout messages.

How it works

  1. connect to the Jabber server (supports SSL)
  2. daemonize (if requested)
  3. auto-authorize anyone who asks
  4. for each online JID+resource pair (the contact) start your program (the chain), with:
    • $JID - e.g. "pjf@asn.pl/Psi"
    • $PRIO - Jabbers "priority"
  5. react to events - in case...:
    • ...contact sends us a message or changes his status, pass it to stdin of the chain
    • ...we receive a message or a status change on stdout of the chain, pass it to the contact
    • ...we receive anything on stderr of the chain, log it (adding contacts name as prefix)
    • ...contacts logs out, close all file descriptors, wait 3 seconds and send a SIGKILL

Why the chain? Because the idea is to split bot implementation into many small modules connected using standard UNIX pipes (but you don't have to).

You pass a path to your bot directory as first argument to jabbot. The directory needs to contain:

  • an executable file named "bot", being your Jabber bot implementation, and
  • a directory named "fc" holding bot configuration in the Flatconf 2 format (according to schema "jabbot", delivered with sources).

Configuration

Exemplary configuration:

pjf@pjf:~/projects/jabbot$ fcc bots/joblog/fc/
Welcome to Flatconf CLI. Type ? for help.
pjf /> ls
  Jabber connection
    [text] server           Jabber server to connect to
           `asn.pl`
    [int ] port             Server port
           `5222`
    [text] login            Username to use for login
           `joblog`
    [text] password         Account password
           `blahblah`
    [text] resource         Connection resource name
           `joblog 2.0`
    [int ] prio             Resource priority
           `0`
    [bool] ssl              Use SSL
           `1`
    [text] fingerprint      Expected SSL MD5 fingerprint
           `97:17:CF:6E:02:B5:09:4A:18:D7:B3:4B:9E:96:53:2F`
    [bool] starttls         Use STARTTLS for SSL
           `0`
  Jabbot settings
    [text] name             Name to show in syslog
           `joblogd`
    [bool] oneline          Convert multiline messages to many one-liners; crop multiline status texts
           `1`

Chain input

Please note that if you want to implement your bot as a chain (modules connected with UNIX pipes), you need to pass everything you receive on stdin to stdout in each module, unless you want to do some sort of filtering (surprise, surprise - neat feature!). Dont worry about the last element in chain - the I/O protocol handles that.

I/O protocol is line-based, what means you should process whole lines.

Events that a chain can receive on stdin:

  • >m <message> - contact sent us a <message>
  • >s <s> <status text> - contact became <s>, setting his status text (so-called "description") to <status text>, which may be null; <s> is either:
    • a - available
    • w - away
    • c - chat
    • d - dnd (do not disturb)
    • x - extended away
  • >> - a multiline event start - buffer the line (appending all lines) and read until you see either ">m" or ">s" event

Example:

>m hi there
>s c my cool status :)
>> are you
>> there...
>m dude?

Means:

  • single-line message "hi there"
  • contact changes his status to "chat" with status text of "my cool status :)"
  • three-line message "are you\nthere...\ndude?"

Chain output

Chain output is very similar to the input, but you use "<" characters instead of ">" ones.

Commands that a chain can send to stdout:

  • <m <message> - send <message> to contact
  • <s <s> <status text> - directed status: set our status to <s>, using the status text of <status text> (which may be null)
    • see ">s" for explanation of <s>
    • see section 5. of RFC 3921 for explanation what is the difference between unicast (directed, with to= attribute) and broadcast presence messages - basically a unicast status will be seen by this one specific contact only
  • <b <s> <status text> - the standard Jabber status update sent to everyone - see "<s" and ">s" for details
  • << - a multiline command start - we buffer the line and read until we see either "<m", "<s" or "<b" command

Please notice the notion of "events" and "commands" - events are received on stdin of the chain, commands are emitted on the stdout.

Everything that a chain writes to stderr is logged, prefixed with contact full name.

Source code

Beta-quality code is available at http://git.asn.pl/

You may also download the 0.1 release from http://download.asn.pl/jabbot/jabbot-0.1.tar.gz

Jabbot has been written by Pawel Foremski. You may try to reach me at pjf@asn.pl.