Extensible Messaging and Presence Protocol module for Drupal Readme ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ About ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This module provides Drupal with an API though which it possible to send your site users instant messages. It is based around the xmpplib library, which you can download from http://hg.mxwerx.com/xmpplib. It is recommended that you read at least some of the library documentation before using this module, as it provides valuable information on how the library works. Furthermore, you should have a basic understanding of the underlying protocol and the interaction between XMPP clients and servers. The API provided by this module aims to be as simple as possible. My goal was to make sending IMs no more difficult than sending e-mail. However, you are not limited to using just this API. If you require more advanced features you can always get access to the underlying client and use it directly. Please see library documentation for info on how to do that. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It is recommended that you use this module in combination with a dedicated XMPP server. See jabber.org for a complete list of available server software. If you are unable to run your own server you may use the built-in one as an alternative. The built-in server is considered experimental and may be removed completely from future releases. Use it with caution. Once you have the module installed and enabled, give yourself permission to "administer xmpp", then go into "XMPP Settings" and configure the client. Most of the configuration should be straightforward as long as you understand how XMPP works. A few things are worth mentioning, however. First, to use an external server you typically only need to specify your username and password. If you need to, you can manually set the TCP host and port settings, as well as what encryption to use. Use DNS option is there to allow the client to resolve _xmpp-client._tcp. SRV records. You can disable it to save some time/bandwidth and instead specify the server by hand. If you use the built-in server you should not provide a password. When the module is installed it generates a random sha1 hash which is used to secure the server. This hash is passed by the client in its initial GET request when it tries to activate the server. Without it, the server does not activate and no messages may be sent. Since both the server and the client share the same database, both initially have access to this hash. The only reason you may need to change it is if you want to share the built-in server with another Drupal site. In this case, you can either set your own secret in the server configuration, or use the default one. When ready, set it as the client password for each site that requires access to that server. The URL that you need to provide for the WebTCP transport typically consists of the path to your Drupal site followed by "/xmpp/server". This is the node that the server listens on for activation requests. For example, if I have my Drupal site installed at http://mxwerx.com/drupal/. Then I would set the URL to http://mxwerx.com/drupal/xmpp/server. Assuming that the server is enabled, and the client password matches server secret, the client should be able to use this URL to activate the server and transmit messages. Even though the client activates the built-in server via a URL, all communications take place over a separate TCP connection. In the server configuration you determine which ports the client can use for this. The number of ports in the range effectively sets the maximum number of concurrent client connections. It must be possible for the client to connect to one of these ports given the port number and domain portion of the configured WebTCP URL. In my example, the client would try to reach the server by resolving mxwerx.com via DNS and using one of the configured ports. Which one is determined at random by the server. If your network configuration prevents this from working, you will not be able to use the built-in server. In addition to this, port 5269 must be open to all outside connections in order to perform XMPP dialback. The ports mentioned here are only in use when needed. At all other times there are no processes listening on them. Only the xmpplib client is able to activate the server and use it to transmit messages. Remember that the domain used by the built-in server and client username needs to point back to your server. Ideally you should create a new _xmpp-server._tcp. SRV DNS record that will point to the address of your server. However, a regular A record should also work. As long as other servers are able to resolve your domain and connect to port 5269, the built-in server should be able to route outgoing messages. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sending messages ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The simplest way to have Drupal send an IM is to use the xmpp_message function. It requires only the JID of the person receiving the messages, and the message itself. This function will first check presence subscription status for the target JID, connect to the server, and finally send the message. Some XMPP services like Google Talk will reject your messages unless you have a valid subscription to the user's presence status. The module keeps a table in the database (xmpp_presence) to remember which subscription requests have been sent. If no previous subscription exists, a new request is sent to be approved by the user. Until the user approves that request no messages will get through. In addition to this, I have noticed in my testing that with Google Talk you actually need to disconnect and reconnect to your account before the subscription is approved. However, this may be a bug in the client I was using. Either way, once the server has been told to allow the subscription request you should be able to send messages to that user. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Module API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When the module is installed, the following functions become available to all other Drupal components. Using them you should be able to send instant messages to your site users. xmpp_get_session() Returns an instance of the client (XMPP_Session object). On the first call this function will establish a new connection to the configured server. Once the connection is ready, all Drupal components share it in order to send IMs. In general, you only need to use this function if you want to get direct access to the client. xmpp_get_jid($uid) Translates user id to Jabber ID which was set in the user's profile. If $uid parameter is left unspecified, returns JID of the current user. You may also pass multiple user ids as an array in order to translate all of them. Doing so reduces the number of SQL queries that need to be performed. In this case, the returned value will be an array that maps each UID to the corresponding JID. Any missing UIDs imply that this user does not have an associated JID in their profile. xmpp_message($jid, $message) Send an IM to the specified JID. First parameter can be either set directly or obtained via xmpp_get_jid function. The second parameter is the IM to send. Returns true if the IM was sent, false otherwise. A return value of true does not imply that the user received your IM. It simply means that the IM was submitted to the local server for delivery. xmpp_presence_subscribe($jid) Several servers (including those used by Google Talk) require an authorized presence subscription before IMs sent from your site will reach their destination. This function is automatically called by xmpp_message for every new JID, but it can also be called manually. xmpp_start_buffer() When sending multiple IMs in a row, it is best to use this command to delay transmitting any data to the connected host. Since instant messages are usually short, sending a network packet for each IM wastes time and bandwidth. This function will hold off sending any data until xmpp_end_buffer() is called. xmpp_end_buffer() Send all buffered stanzas to the connected host. xmpp_last_error() Returns the last error that was triggered by one of the module components. You can use this function to determine what went wrong in the event that any xmpp_* functions fail to execute properly.