开发者

Jabber bot - how to get the availability of contacts?

I need to set up a jabber bot, using python, that will send messages based on the online/offline availability of several contacts.

I've been lookin开发者_运维百科g into pyxmpp and xmpppy, but couldn't find any way (at least nothing straightforward) to check the status of a given contact.

Any pointers on how to achieve this?

Ideally I would like something like e.g. bot.status_of("contact1@gmail.com") returning "online"


I don't think it is possible in the way you want it because the presence of contacts (which contains the information about their availability) is received asynchronously by the bot.

You will have to write a presence handler function and registered it with the connection. This function will get called whenever a presence is received from a contact. The parameter of the call will tell you if the contact is online or not. Depending upon it you can send the message to the contact.

Using xmpppy you do it something like this:

def connect(jid, password, res, server, proxy, use_srv):
    conn = xmpp.Client(jid.getDomain())

    if not conn.connect(server=server, proxy=proxy, use_srv=use_srv):
        log( 'unable to connect to server.')
        return None

    if not conn.auth(jid.getNode(), password, res):
        log( 'unable to authorize with server.')
        return None

    conn.RegisterHandler( 'presence', callback_presence)
    return conn

conn = connect(...)

def callback_presence(sess, pres):
    if pres.getStatus() == "online":
        msg = xmpp.Message(pres.getFrom(), "Hi!")
        conn.send(msg)

PS: I have not tested the code but it should be something very similar to this.


What you want is done via a <presence type="probe"/>. This is done on behalf of the client, and SHOULD not be done by them (as per the RFC for XMPP IM). Since this is a bot, you could implement the presence probe, and receive the current presence of a given entity. Remember to send the probe to the bare JID (sans resource), because the server responds on behalf of clients for presence probes. This means your workflow will look like:

<presence/> // I'm online!                                        BOT
  <presence from="juliet@capulet.org/balcony"/>                   RESPONSE
  <presence from="romeo@montague.net/hallway"/> // and so on...   RESPONSE
<presence type="probe" to="benvolio@montague.net"/>               BOT
  <presence from="benvoio@montague.net/hallway">                  RESPONSE
     <status>Huzzah!</status>
     <priority>3</priority>
  </presence>

Take a look at that portion of the RFC for more in depth information on how your call flow should behave.


What you need to do is:

  1. Connect.
  2. Declare a presence handler. That handler maintains a cache of every contact's presence (see details below)
  3. Send initial presence to the server, which will provoke the reception of presence statuses from all of your online contacts, which will in turn trigger the handler.
  4. The status_of() method reads the cache and deduces the contact's presence status immediately.

Now, it depends on what presence information you need. For the sake of simplicity, let's pretend you just need an "online"/"offline" value. The cache would be a dictionary whose keys are the bare (no resource) JIDs, and the values are a set of connected resources for this JID. For example:

{'foo@bar.com': set(['work', 'notebook']), 'bob@example.net': set(['gtalk'])}

Now, when you receive an "available" presence from a certain JID/resource:

if jid not in cache:
    cache[jid] = set()
cache[jid].add(resource)

Reciprocally, when you receive an "unavailable" presence:

if jid in cache: # bad people send "unavailable" just to make your app crash
    cache[jid].discard(resource)
    if 0 == len(cache[jid]):
        del cache[jid]

And now:

def is_online(jid):
    return jid in cache

Of course, if you want more detailed information, you could maintain not only the list of available resources for a contact but also the status, status message, priority, etc. of each resource.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜