2010-10-08 27 views
4

Je dois configurer un bot jabber, en utilisant python, qui enverra des messages basés sur la disponibilité en ligne/hors ligne de plusieurs contacts.Jabber bot - comment avoir la disponibilité des contacts?

J'ai examiné pyxmpp et xmpppy, mais je n'ai trouvé aucun moyen (au moins rien de plus simple) de vérifier l'état d'un contact donné.

Des pointeurs sur la façon d'y parvenir?

Idéalement, je voudrais quelque chose comme par exemple. bot.status_of("[email protected]") retourner "online"

Répondre

2

Je ne pense pas que ce soit possible comme vous le souhaitez car la présence de contacts (qui contient les informations sur leur disponibilité) est reçue de manière asynchrone par le bot.

Vous devrez écrire une fonction de gestionnaire de présence et l'enregistrer avec la connexion. Cette fonction sera appelée chaque fois qu'une présence est reçue d'un contact. Le paramètre de l'appel vous dira si le contact est en ligne ou non. En fonction de cela, vous pouvez envoyer le message au contact.

En utilisant xmpppy vous faites quelque chose comme ceci:

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: Je ne l'ai pas testé le code mais il devrait être quelque chose de très semblable à cela.

0

Ce que vous voulez est fait via un <presence type="probe"/>. Ceci est fait au nom du client, et ne devrait pas être fait par eux (selon la RFC pour XMPP IM). Comme il s'agit d'un bot, vous pouvez implémenter la sonde de présence et recevoir la présence actuelle d'une entité donnée. N'oubliez pas d'envoyer la sonde au JID (sans ressource), car le serveur répond au nom des clients pour les sondes de présence. Cela signifie que votre flux de travail ressemblera:

<presence/> // I'm online!          BOT 
    <presence from="[email protected]/balcony"/>     RESPONSE 
    <presence from="[email protected]/hallway"/> // and so on... RESPONSE 
<presence type="probe" to="[email protected]"/>    BOT 
    <presence from="[email protected]/hallway">     RESPONSE 
    <status>Huzzah!</status> 
    <priority>3</priority> 
    </presence> 

Jetez un oeil à cette partie de la RFC pour des informations plus détaillées sur la façon dont votre flux d'appels doit se comporter.

0

Ce que vous devez faire est:

  1. Connect.
  2. Déclarez un gestionnaire de présence. Ce gestionnaire maintient un cache de la présence de chaque contact (voir détails ci-dessous)
  3. Envoie une présence initiale au serveur, ce qui provoquera la réception des statuts de présence de tous vos contacts en ligne, ce qui déclenchera à son tour le gestionnaire.
  4. La méthode status_of() lit le cache et déduit immédiatement l'état de présence du contact.

Maintenant, cela dépend des informations de présence dont vous avez besoin. Par souci de simplicité, supposons que vous ayez juste besoin d'une valeur "en ligne"/"hors ligne". Le cache serait un dictionnaire dont les clés sont les JID nus (sans ressource) et les valeurs sont un ensemble de ressources connectées pour ce JID.Par exemple:

{'[email protected]': set(['work', 'notebook']), '[email protected]': set(['gtalk'])} 

Maintenant, lorsque vous recevez une présence "disponible" à partir d'un certain JID/ressource:

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

Réciproquement, lorsque vous recevez une présence "non disponible":

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] 

Et maintenant:

def is_online(jid): 
    return jid in cache 

Bien sûr, si vous souhaitez des informations plus détaillées, vous pouvez gérer non seulement la liste des ressources disponibles pour un contact mais également le statut, le message d'état, la priorité, etc. de chaque ressource.