A More Sensitive Mail Notifier04/13/2001
In the first article in this series, Incoming Mail Notifier, we looked at a simple script that parsed an e-mail message, connected to a Jabber server and sent a message to a Jabber client. That article ended with a couple of questions:
- What if the user to notify is not connected when the notification is sent?
- What if the user is connected, but temporarily doesn't want to be disturbed by notification messages?
The first one is straightforward to answer: Jabber is a store-and-forward system. That means that if the intended recipient of a message is unreachable (whether the recipient is registered on the same Jabber server as the sender or on a different Jabber server) the Jabber server will store the message and send it the next time the recipient connects.
So our existing notify script can happily pump out messages destined for its recipient without worrying whether they are connected or whether the message will get through that instant. In other words, we're creating a situation where the recipient could receive a mass of notifications when logging on after a long absence; the sheer number of messages would make this experience less useful than originally intended. This is one flavor of insensitivity that we want to address.
Even if the user is connected, it might not always be appropriate to send messages. The user might be away from the computer for an extended period (even though the workstation is on and the Jabber client connected) or might simply not want to be interrupted (although as we've already discussed, on a Jabber client that supports them, arrival of "normal" type messages can be fairly unobtrusive).
As it stands, our script will send notifications whether the recipient wants them or not. It turns out that we can address this and the other flavors of insensitivity at the same time.
To address the issues described, we need the script to become sensitive to presence. Presence is a Jabber term that encompasses the connectedness and availability of a Jabber user (or more precisely, of a Jabber ID, or JID).
When you connect, your presence is set by default to "normal," which means "online and available." In a similar way that "chat" type messages are related to "normal" type messages (see the Incoming Mail Notifier"Jabber and Message Types" section of the first article, Incoming Mail Notifier for more details), "normal" presence has a sister, "chat," which means the user is free to chat.
At the moment, some Jabber clients don't support the distinction between "normal" and "chat," but these two similar types (both "available" in the widest sense) will lend themselves to allowing clients to negotiate connectivity and availability on a slightly finer level than simply "are you available or not?"
Jabber defines five presence options:
- Free for Chat (chat)
- Away (away)
- Extended Away (xa)
- Do Not Disturb (dnd)
We've mentioned the two "available" presences already - Normal and Chat; the other three - Away, Extended Away and Do Not Disturb - represent the opposite in a rough sense: "not available (although still connected)."
Although your presence is set for you by default to "normal" when you start your Jabber client and connect to a Jabber server, you can change your presence information. Figure 1 shows a popup window from WinJab that allows me to change my presence setting.
|Figure 1: WinJab's Presence settings|
Show and Status
The "Show Me As" box contains the choice of the five presence settings. Notice also the space for a status message. Presence is actually made of two parts: a mandatory "show" setting (that is, the presence status) and an optional "status" setting, which can carry some text that could be interpreted and used by a Jabber client so that my colleagues could, for example, know that the reason I had set my presence to Extended Away was the fact that I'd gone to lunch.
DJ Adams is a featured speaker at the upcoming O'Reilly Open Source Convention in San Diego, CA, July 23 - 27, 2001. Take this opportunity to rub elbows with open source leaders while relaxing in the beautiful setting of the beach-front Sheraton San Diego Hotel and Marina. For more information, visit our conference home page. You can register online.
We know that XML underlies the Jabber architecture. In the first article we learned about message containers - structures that convey message types such as "normal" and "chat." These structures are XML. There is a Jabber XML structure that conveys presence information, too. The lunch example above would look like this:
<presence> <status>Gone for a pub lunch</status> <show>xa</show> </presence>
In other words, the mandatory section is the <show/> element and the optional section is the <status/> section. Actually, the mandatory section isn't really mandatory, as the simplest presence XML message is this:
which represents "normal" presence (show) with no specific status message. As you might have guessed, this is the presence message that is sent by your client to the Jabber server when you start it and connect. And it is the "normal" presence that is taken as default if no show is specified. (This is why there's no keyword in brackets for the Normal presence above.)
When you change your presence (as with the WinJab popup shown in Figure 1), a new presence message is sent to the Jabber server.
There is actually another presence type, "unavailable," which is set by the Jabber server if you disconnect.
"Set by the Jabber server - for whose benefit?" you might ask. Indeed. We've only really been talking about sending presence information from the client to the server. But it's not much use if it just sits there - and judging from the little icons changing as different users log on and off, it seems obvious that presence information is meant to be sent to other clients.
Presence information is set, and sent to the Jabber server, to be distributed to certain other Jabber users. But it's not a free-for-all. For two big reasons:
- I don't want my client be notified of presence changes for the world and his dog.
- I don't want the world and his dog to know that I exist, and am (or not) available.
So Jabber has the concept of presence subscription, not unlike AOL Instant Messenger's Buddy Lists. If fred@yak wants to know when jim@yak comes online, or otherwise changes his presence, fred@yak must subscribe to jim@yak's presence.
Request and Response
The presence subscription takes the form of a request and a response (from the client's perspective). fred@yak adds jim@yak to his user list (the Jabber term is Roster) and at the same time a presence subscription request is sent from fred@yak to jim@yak. This request is sent via the Jabber server. The request says:"Hi, I'm fred@yak, and I'd like to be on the list of people that the Jabber server relays your presence to when you set or change it; can I be, please?"
jim@yak can reply yes or no. Usually, when proffering such a request to jim, jim's Jabber client will offer him the chance not only to say yes or no, but also to add fred@yak to his roster and send a presence subscription request to fred@yak, if he isn't already there.
The E-mail Notification Example
|Figure 2: notify@yak's roster in JabberIM|
To recap, who are the Jabber IDs that are partaking in our e-mail notification script example? Well, there's me - dj@yak - and I want to receive the notifications, and there's the notify.pl script, which runs as user notify@yak. I mentioned in the first article that for speed I created the notify@yak JID for notify.pl to use. I used a normal Jabber client (JabberIM) to create a new account on the Jabber server on yak.
To make the notification script "sensitive" to dj@yak's availability, notify@yak needs to add dj@yak to its roster and send a presence subscription request to dj@yak, which dj@yak must approve. Again, for speed, I have done this manually using a normal Jabber client (as opposed to coding something in Perl to use Net::Jabber for a one-off exercise), and when connected to the Jabber server with the JabberIM client, the notify@yak's roster looks like this:
"dj" (which in this case is the nickname for dj@yak) is shown in the list of users, which means that dj@yak has approved a presence subscription request from notify@yak and is now listed in the roster. This is the subscription state that we need to have for notify@yak (relating to dj@yak, or whichever JID is to be the recipient of the notifications) for the sensitivity to work.
Modifications to the Script
What we need to do is check for the dj@yak's presence before deciding whether to create and send a message. If dj@yak is "available," which we will define in this example as having a presence (Show) of "normal" or "chat," then we will send the notification. Otherwise, we won't.
Pages: 1, 2