Jabber bot - how to get contact availability?

I need to configure a jabber bot using python that will send messages based on online offline access of multiple contacts.

I looked through pyxmpp and xmpppy, but could not find a single way (at least nothing simple) to check the status of this contact.

Any pointers on how to achieve this?

Ideally, I would like something like, for example, bot.status_of(" contact1@gmail.com ") returning "online"

+4
source share
3 answers

I do not think that this is possible the way you want it, because the presence of contacts (which contains information about their availability) is received by the bot asynchronously.

You will need to write a presence handler function and register it when connected. This function will be called whenever a presence is received from the contact. The call parameter will tell you whether the contact is online or not. Depending on this, you can send a message to the contact.

Using xmpppy you do 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
source

What do you want to do with <presence type="probe"/> . This is done on behalf of the client, and SHOULD NOT execute them (according to RFC for XMPP IM). Since this is a bot, you can implement a presence probe and get the current presence of this object. Do not forget to send the traffic jam to the bare JID (sans resource), because the server responds on behalf of clients to the availability of probes. This means that your workflow will look like this:

 <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 this part of the RFC for more details on how your call flow should behave.

0
source

What you need to do:

  • Connect
  • Declare a presence handler. This handler maintains a cache for each contact presence (see Details below).
  • Send the original presence to the server, which will trigger the reception of presence statuses from all your online contacts, which in turn will call the handler.
  • The status_of () method reads the cache and immediately displays the contact's presence status.

Now it depends on what kind of presence information you need. For the sake of simplicity, let me pretend that you just need an “online” / “standalone” meaning. The cache will be a dictionary whose keys are bare (without resources) JID, and the values ​​are a set of connected resources for this JID. For instance:

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

Now that you get an “available” presence from a specific JID / resource:

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

Mutual when you get an “inaccessible” 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 to get more detailed information, you can save not only a list of available resources for the contact, but also status, status message, priority, etc. each resource.

0
source

All Articles