[PYTHON] Explication et implémentation du protocole XMPP utilisé dans Slack, HipChat et IRC

La caractéristique commune d'ICQ, IRC, Yahoo Messenger, HipChat, Slack et Google Talk, qui sont familiers dans "Ao", est qu'ils utilisent tous le protocole XMPP basé sur XML pour la communication. Les services de messagerie instantanée évoluent rapidement, donc je pense qu'il est important de garder la partie principale inchangée.

En parlant du protocole XMPP, vous pouvez créer un bot qui peut utiliser la plupart des services de messagerie. Dans cet article, nous allons implémenter un Bot prenant en charge plusieurs services de messagerie à l'aide de la bibliothèque Jabber qui a développé et publié XMPP.

Quoi faire

Un bot qui est connecté à la fois à HipChat et à Slack lorsqu'il démarre, et qui déploie et exécute des commandes lorsqu'il parle. Un cas particulier d'utilisation de Slack à l'étranger et HipChat au Japon s'est produit et il a été décidé de le développer. ~~ C'est dur pendant la période de transition ~~ Je pense qu'il est bon d'introduire de nouvelles choses les unes après les autres.

■ Slack スクリーンショット 2015-11-30 18.02.01.png

スクリーンショット 2015-11-30 16.14.11.png

■ HipChat スクリーンショット 2015-11-30 16.16.15.png

Un aperçu du protocole XMPP en 2 minutes

■ Les spécifications sont publiées sur rfc3920. ■ Protocole de communication basé sur XML développé par Jabber ■ L'ensemble de 5 informations suivantes requises pour la connexion スクリーンショット 2015-11-30 17.37.57.png

Le format de communication est XML


Server: <stream>
<message>...</message>
Client: <stream>
<message>...</message>
Server: <message>...</message>
Client: <message>...</message>
Server: <message>...</message>
Client: <message>...</message>
Server: </stream>
Client: </stream>

■ Pour utiliser avec Slack, activez XMPP Gate Way dans Admin et payez avec chaque compte ■ Dans HipChat, il peut être utilisé avec les paramètres par défaut.

XMPP a été créé par Jabber

Vous pouvez facilement implémenter un Bot qui parle XMPP en utilisant la bibliothèque Jabber jabberbot.

install

install


pip install jabberbot
pip install xmpppy
pip install lazy-reload
pip install requests
pip install simplejson

Bot pour Slack et HipChat

bot.py


# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals

import sys
import time
import traceback
import logging
from jabberbot import botcmd, JabberBot, xmpp
import multiprocessing as mp


class ChatBot(JabberBot):
    """
    XMPP/Connectez-vous au service de messagerie de HipChat à l'aide du bot Jabber
    """

    _content_commands = {}
    _global_commands = []
    _command_aliases = {}
    _all_msg_handlers = []
    _last_message = ''
    _last_send_time = time.time()
    _restart = False

    def __init__(self, config):
        self._config = config
        channel = config['connection']['channel']
        username = u"%s@%s" % (config['connection']['username'],
                               config['connection'].get('host',
                                                        config['connection']['host']))
        self._username = username
        super(ChatBot, self).__init__(
            username=username,
            password=config['connection']['password'])

        self.PING_FREQUENCY = 50  # timeout sec
        self.join_room(channel, config['connection']['nickname'])
        self.log.setLevel(logging.INFO)

    def join_room(self, room, username=None, password=None):
        """
Rejoindre la salle de chat
        """
        NS_MUC = 'http://jabber.org/protocol/muc'
        if username is None:
            username = self._username.split('@')[0]
        my_room_JID = u'/'.join((room, username))
        pres = xmpp.Presence(to=my_room_JID)
        if password is not None:
            pres.setTag(
                'x', namespace=NS_MUC).setTagData('password', password)
        else:
            pres.setTag('x', namespace=NS_MUC)

        #Ne pas lire l'historique des messages lors de l'inscription
        pres.getTag('x').addChild('history', {'maxchars': '0',
                                              'maxstanzas': '0'})
        self.connect().send(pres)


    def callback_message(self, conn, mess):
        """
Exécuté lors de la réception d'un message
        """
        _type = mess.getType()
        jid = mess.getFrom()
        props = mess.getProperties()
        text = mess.getBody()
        username = self.get_sender_username(mess)

        print "callback_message:{}".format(text)
        print _type
        # print jid
        print props
        print username
        super(ChatBot, self).callback_message(conn, mess)


        #Répondre si la demande contient une chaîne de caractères spécifique
        import time
        import random
        time.sleep(1)
        if 'Souhait' in text:
            ret = ["Ryo. Je suis désolé",
                   "S'il te plaît attend un moment",
                   "http://rr.img.naver.jp/mig?src=http%3A%2F%2Fimgcc.naver.jp%2Fkaze%2Fmission%2FUSER%2F20141001%2F66%2F6169106%2F58%2F186x211xe15ffb8d1f6f246446c89d7e.jpg%2F300%2F600&twidth=300&theight=600&qlt=80&res_format=jpg&op=r",
                   "http://e-village.main.jp/gazou/image_gazou/gazou_0053.jpeg "]
            self.send_simple_reply(mess, random.choice(ret))

        if 'punaise' in text:
            ret = ["Je vais le réparer plus tard avec ma compréhension",
                   "Reconnu",
                   "Nous vous répondrons après la réunion après cela.",
                   "La dernière version a été corrigée, je vais donc la refléter."]
            self.send_simple_reply(mess, random.choice(ret))

    def send_message(self, mess):
        """Send an XMPP message
        Overridden from jabberbot to update _last_send_time
        """
        self._last_send_time = time.time()
        self.connect().send(mess)

def bot_start(conf):
    print "++++++++"
    print conf
    print "++++++++"
    bot = ChatBot(conf)
    bot.serve_forever()


class ChatDaemon(object):
    config = None

    def run(self):
        try:
            # Start Slack Bot
            process_slack = mp.Process(target=bot_start, args=(self.config_slack,))
            process_slack.start()

            # Start HipChat Bot
            process_hipchat = mp.Process(target=bot_start, args=(self.config_hipchat,))
            process_hipchat.start()
        except Exception, e:
            print >> sys.stderr, "ERROR: %s" % (e,)
            print >> sys.stderr, traceback.format_exc()
            return 1
        else:
            return 0


def main():
    import logging
    logging.basicConfig()
    config_slack = {
        'connection': {
            'username': '{{name}}',
            'password': '{{password}}',
            'nickname': '{{name}}',
            'host': '{{TeamName}}.xmpp.slack.com',
            'channel': '{{RoomName}}@conference.{{TeamName}}.xmpp.slack.com',
        }
    }
    config_hipchat = {
        'connection': {
            'username': '{{name}}',
            'password': '{{password}}',
            'nickname': '{{nickname}}',
            'host': 'chat.hipchat.com',
            'channel': '{{RoomName}}@conf.hipchat.com',
        }
    }

    runner = ChatDaemon()
    runner.config_slack = config_slack
    runner.config_hipchat = config_hipchat
    runner.run()


if __name__ == '__main__':
    sys.exit(main())

Le bot se connecte au lancement

スクリーンショット 2015-11-30 17.34.18.png

J'ai parlé à HipChat et Slack

スクリーンショット 2015-11-30 16.38.34.png

J'ai reçu le message

スクリーンショット 2015-11-30 16.38.06.png

Paiement des informations de réglage

■ 1.Slack SLACK doit être activé pour la passerelle XMPP dans admin https://{{TeamName}}.slack.com/account/gateways

■ 2.HipChat https://{{組織名}}.hipchat.com/rooms/show/{{room_id}}

référence

rfc3920 Note technique XMPP (Jabber Protocol) Page d'introduction XMPP pour les utilisateurs généraux (provisoire)

Résumé

Si vous envisagez d'introduire un nouveau service de messagerie instantanée, cela peut rendre les ingénieurs heureux si vous vérifiez s'il prend en charge le protocole XMPP.

Si vous écrivez ʻos.subprocess ('deploy cmd hogehoge') dans la fonction callback_message`, vous pouvez implémenter n'importe quelle commande, mais je pense que vous serez plus heureux si vous utilisez un HuBot prêt à l'emploi.

Laisser Bot gérer le service de chat et écrire le code ╭ (・ ㅂ ・) و

Recommended Posts

Explication et implémentation du protocole XMPP utilisé dans Slack, HipChat et IRC
Explication de la distance d'édition et de l'implémentation en Python
Explication et mise en œuvre de SocialFoceModel
Explication du CSV et exemple d'implémentation dans chaque langage de programmation
Explication et mise en œuvre de PRML Chapitre 4
Explication et implémentation de l'algorithme ESIM
Explication et mise en œuvre du perceptron simple
Vérifier le taux de compression et le temps de PIXZ utilisé en pratique
Explication et implémentation de l'algorithme Decomposable Attention
Prédisez la quantité d'énergie utilisée en 2 jours et publiez-la au format CSV
[Introduction à Python] Une explication approfondie des types de chaînes de caractères utilisés dans Python!
Pourquoi l'implémentation Python d'ISUCON 5 a utilisé Bottle
Correction des arguments de la fonction utilisée dans map
[Explication de la mise en œuvre] Comment utiliser la version japonaise de BERT dans Google Colaboratory (PyTorch)
Utilisé depuis l'introduction de Node.js dans l'environnement WSL
Python - Explication et résumé de l'utilisation des 24 meilleurs packages
À propos des tests dans la mise en œuvre de modèles d'apprentissage automatique
Un mémorandum sur la mise en œuvre des recommandations en Python
Commandes souvent utilisées dans l'environnement de développement lors de l'implémentation de Python
[Astuces] Problèmes et solutions dans le développement de python + kivy
Obtenez des informations de l'Agence météorologique et informez Slack des avertissements météorologiques dans les 23 quartiers de Tokyo
Implémentation du tri rapide en Python
Comptez bien le nombre de caractères thaïlandais et arabes en Python
Affichage en temps réel de la progression du traitement côté serveur sur le navigateur (implémentation de la barre de progression)
Racler le calendrier de Hinatazaka 46 et le refléter dans Google Agenda
Probabilité des prix les plus élevés et les plus bas des louveteaux à Atsumori
Notifier le contenu de la tâche avant et après l'exécution de la tâche avec Fabric
[Python] J'ai expliqué en détail la théorie et la mise en œuvre de la régression logistique
[Python] J'ai expliqué en détail la théorie et la mise en œuvre de l'arbre de décision
Explication mathématique de la recherche de dichotomie et de trisection et méthode de mise en œuvre sans bogues
J'ai essayé de résumer la méthode de mise en œuvre fréquemment utilisée de pytest-mock
Obtenez le titre et la date de livraison de Yahoo! News en Python