jabber.el manual
****************

This manual is for jabber.el, version 0.5.

Copyright © 2004 Magnus Henoch, Tom Berger.

     Permission is granted to make and distribute verbatim copies or modified versions of this manual, provided the copyright notice and this permission notice are preserved on all copies.

Introduction
************

jabber.el is a Jabber client running under Emacs.  For more information on the open-protocol instant messaging network Jabber, please visit http://www.jabber.org.

As a Jabber client, jabber.el is mostly just a face in the crowd, except that it uses buffers where GUI clients have windows.  There is a roster buffer, and to chat with someone you open a chat buffer, and there are browse buffers (increasingly inexactly named) for interaction with servers and services.  Then again, jabber.el delivers excellent console performance and customizable hooks (if you have speech synthesizer software, hook it up to your presence alerts).

Main unfeatures of jabber.el are SASL, SSL and TLS.  Beyond that, there is nearly no support for advanced MUC features required for moderation and other things.

Contact
=======

jabber.el is developed by Tom Berger (e-mail object@intellectronica.net, JID object@jabber.org.uk) and Magnus Henoch (e-mail mange@freemail.hu, JID legoscia@charente.de).  There is a web page at http://intellectronica.net/emacs-jabber/, and a Sourceforge project page at http://sourceforge.net/projects/emacs-jabber.

Basic operation
***************

This chapter is intended as an introduction to basic usage of jabber.el.  If you have used Jabber before and are familiar with the terminology, you might find it a bit too basic --- in that case, just skim it, making sure to pick up the commands mentioned.

Connecting
==========

I'll assume that you have already successfully installed jabber.el; if not, consult the README file.  Also, make sure you have (require 'jabber) in your .emacs.

Now, type M-x jabber-customize.  This brings up a customize buffer for jabber.el.  The most important variables to customize are jabber-username and jabber-server.  If for some reason the JID of your server is not the same as its network name, change jabber-network-server also.  Save your changes, and type M-x jabber-connect to connect.

If you do not yet have a Jabber account, you can register one.  Enter your desired username for jabber-username and the server you wish to use for jabber-server, save, and type C-u M-x jabber-connect.  If the server supports in-band registration, you will be presented with a registration form to fill out and send. There you will have to enter your username again.  Enter the same username in both places, otherwise jabber.el will be confused.

If you successfully connect, jabber.el will download your roster and display it in a buffer called *-jabber-*.

Now that you are connected, you can send initial presence.  This means sending a notification of you being online to everyone on your roster.  You don't have to do that, and if you don't no-one can see that you are online.  This is usually not what you want, but it is occasionally useful.  To send presence, type M-x jabber-send-presence.  You will be asked three questions; the defaults will do for now.  See Presence, for more information.

To disconnect, type M-x jabber-disconnect.

Chatting
========

In the roster display, you can access several menus through keystrokes or mouse clicks.  You can bring one big menu up by pressing the second mouse button, or you can bring up the ``chat menu'' by typing C-c C-c.  If you do the latter while point is on a roster entry, that entry will be the default value when you are asked for whom to chat with.

Now, try opening a chat with someone.  In the default configuration, you will hear a beep and see ``Message from PERSON'' in the echo area.  This is exactly the same message you receive if the other person sends a message to you.  In any case, go to the buffer *-jabber-chat-:-PERSON-* and start chatting.  Most normal keystrokes open the minibuffer where you can type a message.

Presence
========

``Presence'' is the Jabber term for letting other people know that you are online, and additionally how ``available'' you are.  There are three elements to presence: availability status (called ``show''), status message, and priority.

Your show status may either be empty (meaning simply ``online''), or one of away, xa, dnd and chat, meaning ``away'', ``extended away'' (i.e. away for an extended period), ``do not disturb'', and ``free for chat'', respectively.  This information is available to everyone subscribing to your presence, but technically it does not restrict anyone's actions.  You can chat with people even if you claim to be away.

The status message is a short text complementing your show status, such as ``at home'', ``working'', ``phone'', ``playing games'' or whatever you want.  It is sent to everyone subscribing to your presence, but not all clients prominently display it to the user.

The priority is only interesting if you are running more than one Jabber client at a time accessing the same account.  In that case, messages sent to you without an indication of which client to send to are sent to the client with the highest priority.

To set your presence, use the function jabber-send-presence. It can be called both interactively and in Lisp code.  For the latter case, use something like (jabber-send-presence "away" "idle for 10 minutes" 10).

With jabber.el, you can set your presence remotely.  Ad-Hoc Commands.

Presence subscription
=====================

Having permission to view the presence status of a person is called subscribing to his presence.  Presence subscription between two persons can be asymmetric.

When jabber.el receives a presence subscription request, it will present it to you in an alert requiring immediate response, and offer you to send a subscription request back to that person.

To request subscription to someone, type M-x jabber-send-subscription-request.  You will be prompted for the JID to send it to.  This command can also be accessed through the Roster menu, by typing C-c C-r in the roster buffer.

The roster buffer
=================

The roster buffer is called *-jabber-*.  It simply contains a list of the contacts on your roster.

In the roster buffer, any command which requires a JID will default to the JID under point when called.  These commands can be called through either keyboard menus or mouse menus.  To open a menu with the mouse, simply press the second mouse button over the JID in question. (For some reason, mouse menus don't work in XEmacs. Patches welcome.)  This will bring up a menu with all available actions.  The keyboard menus are split into categories: Chat, Roster, Information, MUC (Multi-User Chat, or groupchat) and Services, opened by C-c C-c, C-c C-r, C-c C-i, C-c C-m and C-c C-s, respectively.

You can call jabber-display-roster to redisplay your roster according to changed preferences (see Customizing the roster buffer).  This will not refetch your roster from the server. Refetching the roster is usually not needed, since updates are pushed to clients automatically.

You can choose not to have the roster updated automatically on presence changes (see Presence alerts).  In that case, you need to call jabber-display-roster manually.

Groupchat
*********

The groupchat menu can be accessed by typing C-c C-m in the roster buffer.  You can also type the commands directly, as will be shown here.

To join a groupchat, type M-x jabber-groupchat-join.  You will be prompted for the groupchat to join, and your nickname in the groupchat.  This nickname doesn't need to have any correlation to your JID; in fact, groupchats are usually (but not always) configured such that only moderators can see your JID.

Groupchat messages will be displayed in a buffer called *-jabber-groupchat-:-GROUPCHAT-*.  It works much like the chat buffer.

To leave a groupchat, type M-x jabber-groupchat-leave.

If you are the owner of a groupchat, you can change its configuration by typing M-x jabber-groupchat-get-config.  A configuration form will be rendered in new buffer.

Currently, there is no user-friendly way to see which people are in a groupchat.  A possible workaround is to add the groupchat to your roster before you join it; that way the participants will show up as resources of a user.

Services
********

Not every Jabber entity is a physical person.  There are many automatic entities, called servers, services, components, agents, transports and other names.  The use of these is described here.

The functions described in this chapter use browse buffers. Browse buffers are named *-jabber-browse-:-SERVICE-*, sometimes with a numerical suffix.  They have the same keybindings as the roster buffer, and if you call a function operating on a JID while point is over a JID, that JID will be the default value, so you don't have to type it or copy it yourself.

Service discovery and browsing
==============================

To find services you want to use, you need to discover them first. This can be done with either service discovery or browsing.  Service discovery is the newer and preferred protocol, while browsing is still used by much software.  The use of both is very similar.

The most common use of service discovery is to browse your home server, to see what services are provided locally.  Note, however, that this is no restriction; you can use services from all over the network.

To start browsing, type M-x jabber-get-browse and enter the JID you want to browse.  For service discovery there are two commands, jabber-get-disco-items and jabber-get-disco-info, depending on whether you want information about that specific JID or about services related to it, respectively.

These commands can be accessed from the Info menu, which is opened by typing C-c C-i.

Registering
===========

Some services, in particular user directories and gateways to legacy IM systems, require registration.  To register with such a service, either type M-x jabber-get-register or select it from the Service menu, which is opened by typing C-c C-s.  You have to know the service's JID, possibly from service discovery. (see Service discovery and browsing)

This is also the way to change your registration details, e.g. your password --- just ask to register with that service again.  To change the password of your Jabber account, ask to register with your Jabber server.

Please note that any passwords sent in this way will be sent in cleartext to your Jabber server, as jabber.el doesn't support encryption yet, and possibly sent in cleartext from your server to the server hosting the service.

jabber.el will then request a registration form from that service.  If for some reason the service does not answer (maybe network problems, or some services neither support registration nor report errors about that) that will be the last thing you saw about it.  jabber.el will not report timeout errors, but rather simply wait until you shut it down.

Once the response arrives, the form will be rendered in a browse buffer.  Just fill out the fields, and hit Submit.  You will receive confirmation of your registration in the echo area.

To cancel an existing registration (and also for cancelling your Jabber account, if you sent a registration request to your server), hit Cancel.  The unregistration will be confirmed in the echo area.

Searching
=========

Some services, notably user directories and gateways to legacy IM systems, allow searching.  Searching in Jabber generally means searching for someone's JID, but the protocol is general enough to support most databases.

To search a service, either type M-x jabber-get-search or select it from the Service menu, which is opened by typing C-c C-s.

Just like with registration, this command sends a request for a search form, and displays it if and when the response arrives.  Enter your search and submit it.  Search results will be displayed in a different browse buffer.

Ad-Hoc Commands
===============

jabber.el supports a subset of JEP-0050, the standard for Ad-Hoc Commands.  As the name implies, this can be used for just about anything.  However, at the time of this writing it seems that jabber.el is the only implementation.

Currently, ad-hoc commands are used for setting presence remotely.  If you realize that you forgot to set your client to ``away'' with a low priority, you can do it remotely. (Most Jabber servers support kicking a client off the net by logging in with another client with exactly the same resource.)

The commands for executing ad-hoc commands are available under the Service menu, which is opened by typing C-c C-s.

To find which commands are available, run ``Request command-list'' (jabber-ahc-get-list). (This is the same thing as a disco items request to the node http://jabber.org/protocol/commands.)

To run a command from the list, put point over it and run ``Execute command'' (jabber-ahc-execute-command), accepting the defaults for JID and node.  (If you already know those, you could of course enter them yourself)  The form you get should hopefully be self-explanatory.

jabber.el currently doesn't parse <action/> tags, which will cause confusing behaviour for multi-step commands.

Customization
*************

jabber.el is intended to be customizable for many tastes.  After all, this is Emacs.  To open a customization buffer for jabber.el, type M-x jabber-customize.

Connection settings
===================

jabber-username is the username part of your JID.

jabber-server is the JID of your server, i.e. the hostname part of your JID.  This is usually, but not necessarily, the same as the hostname of the server.

jabber-network-server is the hostname or IP address of your server.  If it is set to nil, jabber.el will use the name in jabber-server.

jabber-port is the TCP port of the server to connect to.  This is 5222 in almost all cases.

jabber-password is your password.  You have the option to set it here, in which case it will be stored in cleartext in your .emacs file.  If this is set to nil, you will be prompted for your password every time you connect.

jabber-resource is the resource you want to log in under.  This only matters if you are connected to the same account from different clients or different computers, since each connection must have a unique resource.  You might want to set this to your hostname.

jabber-default-priority is the default priority sent with your presence.  Regardless of what you have here, you can change your priority during a session with jabber-send-presence. See Presence, for more information on priority.

jabber-nickname is your default nickname for groupchats.

jabber-debug-log-xml activates XML logging.  All XML stanzas sent and received are logged in the buffer *-jabber-xml-log-* in list format.  See XML representation.

Customizing the roster buffer
=============================

jabber-debug-roster toggles debug output in the roster.  This means that you can see the properties of each contact.

jabber-sort-order controls how roster items are sorted by presence.  It is a list containing strings corresponding to show status (see Presence) or nil, which represents offline.

jabber-show-resources controls when your contacts' resources are shown in the roster buffer.  The default is to show resources when a contact has more than one connected resource.

Customizing alerts
==================

When an event happens (currently including presence changes, incoming messages, and completed queries) you will usually want to be notified.  Since tastes in this area vary wildly, these alerts are implemented as hooks, so you can choose which ones you want, or write your own if none fit.

Actually, if you don't want to write your own, stop reading this section and just read Standard alerts.

Many kinds of alerts consist in displaying a text message through a certain mechanism.  This text message is provided by a function which you can rewrite or replace.  If this function returns nil, no message is displayed, and non-textual alerts refrain from action.

The hooks take different arguments depending on category.  However, they all have in common that the last argument is the result of the message function.  The message function for each category takes the same arguments as the corresponding hooks, except for that last argument.

Alert hook contributions are very welcome.  Either submit them to the Sourceforge patch tracker, or contact us directly.

Standard alerts
---------------

Six alerts are already written for all three alert categories.  These all obey the result from the corresponding message function.

The beep alerts simply sound the terminal bell by calling ding.  They are enabled by default.

The echo alerts display a message in the echo area by calling message.  They are enabled by default.

The switch alerts switch to the buffer where the event occurred (chat buffer for incoming messages, roster buffer for presence changes, browse buffer for completed queries).  They are disabled by default.  Take care when using them, as they may interrupt your editing.

The display alerts display but do not select the buffer in question, using the function display-buffer.  See Choosing a Window for Display (GNU Emacs Lisp Reference Manual), for information about customizing its behaviour.

The wave alerts play a sound file by calling play-sound-file.  No sound files are provided.  To use this, enter the names of the sound files in jabber-alert-message-wave, jabber-alert-presence-wave and jabber-alert-info-wave, respectively.

The screen alerts send a message through the Screen terminal manager (see http://www.gnu.org/software/screen/).  They do no harm if called when you don't use Screen.

The ratpoison alerts send a message through the Ratpoison window manager (see http://ratpoison.sourceforge.net/).  They do no harm if used when you're not running X, but if you are running X with another window manager, the ratpoison processes will never exit. You can look at them with list-processes. (In jabber.el 0.4, ratpoison alerts were sent synchronously, which meant that Emacs would stall if ratpoison wasn't there to answer.)

All these functions are in the jabber-alert.el file.  You can use them as templates or inspiration for your own alerts.

Presence alerts
---------------

Set jabber-alerts-presence-message-function to your desired function.  This function should look like:

     (FUNCTION WHO OLDSTATUS NEWSTATUS STATUSTEXT)

WHO is the JID symbol (see Roster structure), OLDSTATUS and NEWSTATUS are the previous and current stati, respectively, and STATUSTEXT is the status message if provided, otherwise nil.

NEWSTATUS can also be one of "subscribe", "subscribed", "unsubscribe" and "unsubscribed".

The default function, jabber-presence-default-message, returns nil if OLDSTATUS and NEWSTATUS are the same, and in other cases constructs a message from the given data.

All presence alert hooks take the same arguments plus the additional PROPOSED-ALERT, which is the result of the specified message function.  This last argument is usually the only one they use.

Message alerts
--------------

Set jabber-alerts-message-function to your desired function. (Logically it should be jabber-alerts-message-message-function, but that would be really ugly.)  This function should look like:

     (FUNCTION FROM BUFFER TEXT)

FROM is the JID symbol (see Roster structure), BUFFER is the buffer where the message is displayed, and TEXT is the text of the message.

The default function, jabber-message-default-message, returns ``Message from PERSON'', where PERSON is the name of the person if specified in the roster, otherwise the JID.

All message alert hooks take the same arguments plus the additional PROPOSED-ALERT, which is the result of the specified message function.

Info alerts
-----------

Info alerts are sadly underdeveloped.  The message function, jabber-alerts-info-message-function, takes two arguments, INFOTYPE and BUFFER.  BUFFER is the buffer where something happened, and INFOTYPE is either 'roster for roster updates, or 'browse for anything that uses the browse buffer (basically anything except chatting).

The info alert hooks take an extra argument, as could be expected.

Hacking and extending
*********************

This part of the manual is an attempt to explain parts of the source code.  It is not meant to discourage you from reading the code yourself and trying to figure it out, but as a guide on where to look.  Knowledge of Jabber protocols is assumed.

XML representation
==================

The XML representation is the one generated by xml.el in Emacs, namely the following.  Each tag is a list.  The first element of the list is a symbol, the name of which is the name of the tag.  The second element is an alist of attributes, where the keys are the attribute names in symbol form, and the values are strings.  The remaining elements are the tags and data contained within the tag.

For example,

     <foo bar='baz'>
     <frobozz/>Fnord
     </foo>

is represented as

     (foo ((bar . "baz")) (frobozz nil "") "Fnord
     ")

Note the empty string as the third element of the frobozz list.  It is not present in newer (post-21.3) versions of xml.el, but it's probably best to assume it might be there.

Roster structure
================

Roster entries are contained in the list *jabber-roster*.

A roster entry is a symbol.  Its name is the JID, and it is interned in jabber-jid-obarray.  A roster entry can have the following properties:

xml
     The XML tag received from the server on roster update

name
     The name of the roster item (just like the XML attribute)

subscription
     The subscription state (also copied)

ask
     The ask state (copied)

groups
     A list of strings (possibly empty) containing all the groups the contact is in

connected
     Boolean, true if any resource is connected

show
     Presence show status for highest-priority connected resource

status
     Presence status message for highest-priority connected resource

resources
     Alist.  Keys are strings (resource names), values are plists with properties connected, show, status and priority.

Incoming presence information is inserted in resources, and the information from the resource with the highest priority is inserted in show and status by the function jabber-prioritize-resources.

Listening for new requests
==========================

To listen for new IQ requests, add the appropriate entry in jabber-iq-get-xmlns-alist or jabber-iq-set-xmlns-alist. The key is the namespace of the request, and the value is a function that takes one argument, the entire IQ stanza in list format. jabber-process-iq reads these alists to determine which function to call on incoming packets.

For example, the Ad-Hoc Commands module contains the following:

     (add-to-list 'jabber-iq-set-xmlns-alist
     	     (cons "http://jabber.org/protocol/commands" 'jabber-ahc-process))

To send a response to an IQ request, use (jabber-send-iq SENDER "result" QUERY nil nil nil nil ID), where QUERY is the query in list format.  jabber-send-iq will encapsulate the query in an IQ packet with the specified id.

To return an error to the Jabber entity that sent the query, use jabber-signal-error.  The signal is caught by jabber-process-iq, which takes care of sending the error.

Sending new requests
====================

To send an IQ request, use jabber-send-iq.  It will generate an id, and create a mapping for it for use when the response comes.  The syntax is:

     (jabber-send-iq TO TYPE QUERY
                     SUCCESS-CALLBACK SUCCESS-CLOSURE
                     FAILURE-CALLBACK FAILURE-CLOSURE)

Both callbacks take two arguments, the IQ stanza returned and the closure item mentioned here.

Two standard callbacks are provided.  jabber-report-success takes a string as closure item, and reports success or failure in the echo area.  jabber-process-data prepares a browse buffer.  If its closure argument is a function, it calls that function with point in this browse buffer.  If it's a string, it prints that string along with the error message in the IQ response.  If it's anything else (e.g. nil), it just dumps the XML in the browse buffer.

Examples follow.  This is the hypothetical Jabber protocol ``frob'', for which only success report is needed:

     (jabber-send-iq "someone@somewhere.org" "set"
                     '(query ((xmlns . "frob")))
                     'jabber-report-success "Frobbing"
                     'jabber-report-success "Frobbing")

This will print ``Frobbing succeeded'' or ``Frobbing failed: reason'', respectively, in the echo area.

The protocol ``investigate'' needs to parse results and show them in a browse buffer:

     (jabber-send-iq "someone@somewhere.org" "get"
                     '(query ((xmlns . "investigate")))
                     'jabber-process-data 'jabber-process-investigate
                     'jabber-process-data "Investigation failed")

Of course, the previous example could have used jabber-report-success for the error message.  It's a matter of UI taste.

Service discovery
=================

Your new handlers will likely want to advertise their existence through service discovery.

To have an additional feature reported in response to disco info requests, add a string to jabber-advertised-features.

By default, the service discovery functions reject all requests containing a node identifier with an ``Item not found'' error.  To make them respond, add the appropriate entries to jabber-disco-items-nodes and jabber-disco-info-nodes. Both variables work in the same way.  They are alists, where the keys are the node names, and the values are lists of two items.

The first item is the data to return --- either a list or a function taking the entire IQ stanza and returning a list, this list containing the XML nodes to include in the <query/> node in the response.

The second item is the access control function.  An access control function receives the JID as its only argument, and returns non-nil if access is to be granted.  If nil is specified instead of a function, access is always granted.  One such function is provided, jabber-my-jid-p, which grants access for JIDs where the username and server (not necessarily resource) are equal to those of the user.

Stanza chains
=============

If you really need to get under the skin of jabber.el, you can add functions to the lists jabber-message-chain, jabber-iq-chain and jabber-presence-chain.  Normally those lists contain only the functions jabber.el needs to do its job, i.e. jabber-process-message, jabber-process-iq and jabber-process-presence, respectively.

The functions in these lists will be called in order when an XML stanza of the corresponding type arrives, with the entire XML stanza passed as the only argument.  Earlier functions can modify the stanza to change the behaviour of downstream functions.