Jabber bot - how to get the availability of contacts?

本秂侑毒 提交于 2019-12-12 08:14:33

问题


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 looking 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"


回答1:


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.




回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/3890726/jabber-bot-how-to-get-the-availability-of-contacts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!