实现一个针对文本消息的收发程序。实现的业务逻辑类似与“鹦鹉学舌”,粉丝发什么内容,我们就传回给粉丝什么内容。
# coding:utf-8 import tornado.web import tornado.httpserver import tornado.ioloop import tornado.options import hashlib import xmltodict import time from tornado.web import RequestHandler from tornado.options import define, options WECHAT_TOKEN = "itcast" define("port", default=8080, type=int) class WeChatHandler(RequestHandler): """微信接入接口""" def get(self): """开发者验证接口""" signature = self.get_argument("signature") timestamp = self.get_argument("timestamp") nonce = self.get_argument("nonce") echostr = self.get_argument("echostr") tmp = [WECHAT_TOKEN, timestamp, nonce] tmp.sort() tmp = "".join(tmp) tmp = hashlib.sha1(tmp).hexdigest() if tmp == signature: self.write(echostr) else: self.write("error") def post(self): """收发消息接口""" req_xml = self.request.body req = xmltodict.parse(req_xml)['xml'] if "text" == req.get("MsgType"): resp = { "ToUserName":req.get("FromUserName", ""), "FromUserName":req.get("ToUserName", ""), "CreateTime":int(time.time()), "MsgType":"text", "Content":req.get("Content", "") } else: resp = { "ToUserName":req.get("FromUserName", ""), "FromUserName":req.get("ToUserName", ""), "CreateTime":int(time.time()), "MsgType":"text", "Content":"I love you, itcast!" } resp_xml = xmltodict.unparse({"xml":resp}) self.write(resp_xml) def main(): tornado.options.parse_command_line() app = tornado.web.Application([ (r"/wechat", WeChatHandler), ]) http_server = tornado.httpserver.HTTPServer(app) http_server.listen(options.port) tornado.ioloop.IOLoop.current().start() if __name__ == '__main__': main()
有趣的表情
QQ表情
实际是字符串转义,如 /:?、/:? 等,仍属于文本信息。
emoji
绘文字(日语:絵文字/えもじ emoji)是日本在无线通信中所使用的视觉情感符号,绘意指图形,文字则是图形的隐喻,可用来代表多种表情,如笑脸表示笑、蛋糕表示食物等。
在NTTDoCoMo的i-mode系统电话系统中,绘文字的尺寸是12x12 像素,在传送时,一个图形有2个字节。Unicode编码为E63E到E757,而在Shift-JIS编码则是从F89F到F9FC。基本的绘文字共有176个符号,在C-HTML4.0的编程语言中,则另增添了76个情感符号。
最早由栗田穰崇(Shigetaka Kurita)创作,并在日本网络及手机用户中流行。
自苹果公司发布的iOS 5输入法中加入了emoji后,这种表情符号开始席卷全球,目前emoji已被大多数现代计算机系统所兼容的Unicode编码采纳,普遍应用于各种手机短信和社交网络中。
本质是Unicode字符,也属于文本消息。
自定表情
微信的自定义表情不是文本,也不是图片,而是一种不支持的格式,微信未提供处理此消息的接口。
改写代码
微信发送的请求中会携带签名验证信息(正如验证服务器有效性一章节所示),我们需要对收到的请求进行验证是否来自微信服务器,所以在处理请求前都要按照验证算法进行检验。
class WeChatBaseHandler(RequestHandler): def prepare(self): """验证请求是否来自微信服务器""" signature = self.get_argument("signature") timestamp = self.get_argument("timestamp") nonce = self.get_argument("nonce") tmp = [WECHAT_TOKEN, timestamp, nonce] tmp.sort() tmp = "".join(tmp) tmp = hashlib.sha1(tmp).hexdigest() if tmp != signature: self.send_error(403) # 若是非法请求,返回403错误 class WeChatHandler(WeChatBaseHandler): """微信接入接口""" def get(self): """开发者验证接口""" echostr = self.get_argument("echostr") self.write(echostr) def post(self): """收发消息接口""" req_xml = self.request.body req = xmltodict.parse(req_xml)['xml'] if "text" == req.get("MsgType"): resp = { "ToUserName":req.get("FromUserName", ""), "FromUserName":req.get("ToUserName", ""), "CreateTime":int(time.time()), "MsgType":"text", "Content":req.get("Content", "") } else: resp = { "ToUserName":req.get("FromUserName", ""), "FromUserName":req.get("ToUserName", ""), "CreateTime":int(time.time()), "MsgType":"text", "Content":"I love you, itcast!" } resp_xml = xmltodict.unparse({"xml":resp}) self.write(resp_xml)