The common feature of ICQ, IRC, Yahoo Messenger, HipChat, Slack, and Google Talk, which are familiar to Ao, is that they all use the XML-based XMPP protocol for communication. Instant messaging services change rapidly, so I think it's important to keep the core part unchanged.
Speaking the XMPP protocol creates a bot that can use most message services. In this article, we will implement a bot that supports multiple message services using the library of Jabber, which developed and released XMPP.
A bot that logs in to both HipChat and Slack when it starts up, and deploys and executes commands when it talks to it. We decided to develop a special case of using Slack overseas and HipChat in Japan. ~~ It's hard during the transition period ~~ I think it's good to introduce new things one after another.
■ Slack
■ HipChat
■ The specifications are published at rfc3920. ■ XML-based communication protocol developed by Jabber ■ The following 5-piece set of information required for connection
Communication format is 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>
■ To use with Slack, enable XMPP Gate Way in Admin and pay out with each account ■ In HipChat, it can be used with the default settings.
You can easily implement an XMPP-speaking bot using the Jabber library jabberbot
.
install
install
pip install jabberbot
pip install xmpppy
pip install lazy-reload
pip install requests
pip install simplejson
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/Connect to HipChat's message service using Jabber bot
"""
_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):
"""
Join Chat Room
"""
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)
#Do not read message history when joining
pres.getTag('x').addChild('history', {'maxchars': '0',
'maxstanzas': '0'})
self.connect().send(pres)
def callback_message(self, conn, mess):
"""
Executed when a message is received
"""
_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)
#Respond if the inquiry contains a specific character string
import time
import random
time.sleep(1)
if 'Wish' in text:
ret = ["Ryo. I'm sorry",
"Please wait for a while",
"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 'bug' in text:
ret = ["I'll fix it later with my understanding",
"Recognized",
"We will respond after the meeting after this.",
"The latest version has been fixed, so I will reflect it."]
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())
■ 1.Slack SLACK must be enabled for XMPP Gateway in admin https://{{TeamName}}.slack.com/account/gateways
■ 2.HipChat https://{{組織名}}.hipchat.com/rooms/show/{{room_id}}
rfc3920 XMPP (Jabber Protocol) Technical Memo XMPP introductory page for general users (provisional)
If you are considering introducing a new instant messaging service, it may make engineers happy if you check whether it supports the XMPP protocol.
If you write ʻos.subprocess ('deploy cmd hogehoge')in the
callback_message function`, you can implement any command, but I think you will be happier if you use an off-the-shelf HuBot.
Leave the chat service to the bot and write the code ╭ (・ ㅂ ・) و