每一次产品发布或故障支持,都需要将相关人员拉到同一个Skype群聊会话,以便讨论、测试、支持。如果每次都需要手动做这些动作是比较累;如果复用已有会话,又会影响本次无关人员。于是有了这样一个需求:在Web后台定义相关组员及关联关系,在Web前台点击即可以创建或加入相关会话。这要求提供一个HTTP的接口,接收会话人员及主题,创建聊天室。搜了一圈,发现SkPy这个库最简单,支持创建会话,发送/接收消息,事件监听等等,其他的库要么功能太简单不满足,要么需要安装Skype客户端,要么不支持最新(live)注册的Skype用户,决定使用这个来开发。由于只是一个简单的HTTP接口,决定使用web.py。
首先安装SkPy和web.py,注意如果是CentOS 6,Python certifi版本只能是2015.04.28,否则会报错
sudo pip install SkPy sudo pip install web.py #you need to do follow steps on Centos 6.x, to make requests works sudo pip uninstall -y certifi sudo pip install certifi==2015.04.28
web.py只要单个文件就可以工作了,创建chat.py如下
import web from skpy import Skype from skpy import SkypeAuthException import logging import hashlib import os.path import io urls = ( '/', 'index', '/chat', 'chat' ) ''' try: import http.client as http_client except ImportError: # Python 2 import httplib as http_client http_client.HTTPConnection.debuglevel = 1 logging.basicConfig() logging.getLogger().setLevel(logging.DEBUG) requests_log = logging.getLogger("requests.packages.urllib3") requests_log.setLevel(logging.DEBUG) requests_log.propagate = True ''' class SkypeService: def __init__(self): self.username = '<skype account>' self.password = '<skype password>' self.token_file="/tmp/tokens-app" self.skype = Skype(connect=False) self.skype.conn.setTokenFile(self.getTokenFile()) def getTokenFile(self): if not os.path.isfile(self.token_file): with io.open(self.token_file, 'a') as file: file.close() return self.token_file def connect(self): try: self.skype.conn.readToken() except SkypeAuthException: self.skype.conn.setUserPwd(self.username, self.password) self.skype.conn.getSkypeToken() def creatChatRoom(self, member, topic): ch = self.skype.chats.create(members=member) ch.setTopic(topic) return ch def getShardLink(self, channel): return channel.joinUrl def createAndGetSharedLink(self, member, topic): self.connect() ch = self.creatChatRoom(member, topic) # ch.sendMsg("welcome") # return {"id": ch.id, "url": self.getShardLink(ch)} return self.getShardLink(ch) def getConversationIdByUrl(self, url): id = self.skype.chats.urlToIds(url)["Resource"] return id def getChatroomByUrl(self, url): id = self.getConversationIdByUrl(url) ch = getChatroomByConversationId(id) return ch def getChatroomByConversationId(self, id): ch = self.skype.chats.chat(id) return ch def sendMessageByConversationId(self, id, message): ch = self.getChatroomByConversationId(id) return ch.sendMsg("Hello world!") def getMessagesByConversationId(self, id): ch = self.getChatroomByConversationId(id) return ch.getMsgs() class Storage: def __init__(self): self.cache_path = '/tmp/' def set(self, key, value): cache_file = self.cache_path + key try: with io.open(cache_file, 'w') as file: file.write(value) except: raise Exception('file: {0} write failure'.format(cache_file)) return True def get(self, key): cache_file = self.cache_path + key try: with io.open(cache_file) as file: value = file.read() except: raise Exception('file: {0} not exists'.format(cache_file)) return value class index: def GET(self): return "Hello, world!" class chat: def GET(self): url = web.ctx.home + web.ctx.path + web.ctx.query key = hashlib.md5(url).hexdigest() storage = Storage() try: join_url = storage.get(key) except: param = web.input() users = param.user member = tuple(users.split(',')) topic = param.topic sk = SkypeService() join_url = sk.createAndGetSharedLink(member, topic) storage.set(key, join_url) return join_url if __name__ == "__main__": app = web.application(urls, globals()) app.run()
然后运行chat.py,默认监听8080端口
python chat.py [port]
在浏览器访问,
http://127.0.0.1:8080/chat?user=user1,user2&topic=19.5Release
即可以创建一个聊天会话,并且返回join url,点击这个URL会尝试打开Skype应用。注意这个会话默认是开放的,允许任何人加入
https://join.skype.com/LRRUuan7kNH3
去掉logging注释,可以看到API调用的过程,作者也作了详细的协议文档,可以看出登录流程相当复杂,也可以根据这个开放出其他语言的SDK。
注意这个bot运行的是个人账号,使用的是与web.skype.com相同的HTTP API,最好是在Skype 开发者平台上注册,官方也提供了NodeJS的SDK。
之前许多QQ机器人使用都是Web QQ的接口,目前已关闭。同时官方的API,发现并没有创建任意群聊的API。对比国外软件,国内的API真的是不开放。国外公司甚至有专门的API Platform团队,负责API开发开放,以及与第三方平台的集成。
参考连接:
SkPy