Бот Jabber - как получить доступность контактов?

Мне нужно настроить jabber-бот, использующий python, который будет отправлять сообщения, основываясь на доступности онлайн / офлайн нескольких контактов.

Я изучал pyxmpp и xmpppy, но не смог найти никакого способа (по крайней мере, ничего простого), чтобы проверить состояние данного контакта.

Любые указатели о том, как этого добиться?

В идеале я хотел бы что-то вроде, например, bot.status_of("contact1@gmail.com") возврате "online"

3 ответа

Я не думаю, что это возможно так, как вы этого хотите, потому что присутствие контактов (которые содержат информацию об их доступности) принимается ботом асинхронно.

Вам нужно будет написать функцию обработчика присутствия и зарегистрировать ее в соединении. Эта функция вызывается всякий раз, когда от контакта поступает информация о присутствии. Параметр звонка скажет вам, если контакт в сети или нет. В зависимости от этого вы можете отправить сообщение контакту.

С помощью xmpppy вы делаете это примерно так:

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: я не проверял код, но это должно быть что-то очень похожее на это.

То, что вы хотите сделать через <presence type="probe"/>, Это делается от имени клиента и НЕ ДОЛЖНО быть им выполнено (согласно RFC для XMPP IM). Поскольку это бот, вы можете реализовать датчик присутствия и получить текущее присутствие данного объекта. Не забудьте отправить зонд на пустой JID (sans-ресурс), потому что сервер отвечает от имени клиентов за зонды присутствия. Это означает, что ваш рабочий процесс будет выглядеть так:

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

Посмотрите на эту часть RFC для получения более подробной информации о том, как должен вести себя ваш поток вызовов.

Что вам нужно сделать, это:

  1. Подключение.
  2. Объявите обработчик присутствия. Этот обработчик поддерживает кэш-память о присутствии каждого контакта (подробности см. Ниже)
  3. Отправьте начальное присутствие на сервер, что вызовет получение статусов присутствия от всех ваших онлайн-контактов, что, в свою очередь, вызовет обработчик.
  4. Метод status_of() считывает кеш и немедленно определяет состояние присутствия контакта.

Теперь это зависит от того, какая информация о присутствии вам нужна. Для простоты давайте представим, что вам просто нужно значение "онлайн"/"оффлайн". Кеш будет представлять собой словарь, ключами которого являются чистые (без ресурсов) JID, а значения - это набор связанных ресурсов для этого JID. Например:

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

Теперь, когда вы получаете "доступное" присутствие от определенного JID/ ресурса:

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

Взаимно, когда вы получаете "недоступное" присутствие:

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]

И сейчас:

def is_online(jid):
    return jid in cache

Конечно, если вы хотите получить более подробную информацию, вы можете поддерживать не только список доступных ресурсов для контакта, но также статус, сообщение о состоянии, приоритет и т. Д. Каждого ресурса.

Другие вопросы по тегам