首页 > 开发 > Python > 正文

Python快速搭建自动回复公众号

2016-04-19 20:49:43  来源:极客头条

  在之前的一篇文章 Python利用 AIML 和 Tornado 搭建聊天机器人微信订阅号 中用 aiml 实现了一个简单的英文聊天机器人订阅号。但是只能处理英文消息,现在用 图灵机器人 来实现一个中文的聊天机器人订阅号。
  这里主要介绍如何利用 Python 的 Tornado Web框架以及wechat-python-sdk 微信公众平台 Python 开发包来快速搭建微信公众号。
  完整的公众号代码 GitHub 地址:green ,由于目前此公众号有一些功能正在开发中,此完整代码会与下文所描述的代码有不一致的地方,但是自动回复的功能会一直保留。
  本文搭建的微信公众号为 Ms_haoqi,可以扫码关注后测试效果
  二维码
  自动回复效果:
自动回复
安装Python库   通过 pip 安装 wechat-python-sdk , Requests 以及 Tornado
pip install tornado pip install wechat-sdk pip install requests 订阅号申请   要搭建订阅号,首先需要在微信公众平台官网进行注册,注册网址: 微信公众平台
  目前个人用户可以免费申请微信订阅号,虽然很多权限申请不到,但是基本的消息回复是没有问题的。
服务器接入   具体的接入步骤可以参考官网上的接入指南
  本订阅号的配置为:
服务器配置
  配置里的URL为服务器提供订阅号后台的url路径,本文用到的源代码配置的是 http://server_ip/wx 其中 server_ip 是运行源代码的主机的公网ip地址。
  Token 可以设置为任意字符串。
  EncodingAESKey 可以选择随机生成。
  消息加密方式可以设置为比较简单的明文模式。
  接受并处理微信服务器发送的接入请求的关键代码为Tornado的一个Handle, wx.py :

import tornado.escape
import tornado.web

from wechat_sdk import WechatConf
conf = WechatConf(
    token='your_token', 
    appid='your_appid', 
    appsecret='your_appsecret', 
    encrypt_mode='safe',  
    encoding_aes_key='your_encoding_aes_key'  
)

from wechat_sdk import WechatBasic
wechat = WechatBasic(conf=conf)

class WX(tornado.web.RequestHandler):
    def get(self):
        signature = self.get_argument('signature', 'default')
        timestamp = self.get_argument('timestamp', 'default')
        nonce = self.get_argument('nonce', 'default')
        echostr = self.get_argument('echostr', 'default')
        if signature != 'default' and timestamp != 'default' and nonce != 'default' and echostr != 'default' \
                and wechat.check_signature(signature, timestamp, nonce):
            self.write(echostr)
        else:
            self.write('Not Open')

  此代码的作用就是验证消息是来自微信官方服务器后直接返回echostr。
  启动后台的 main.py 代码:

import tornado.web
import tornado.httpserver
from tornado.options import define, options

settings = {
            'static_path': os.path.join(os.path.dirname(__file__), 'static'),
            'template_path': os.path.join(os.path.dirname(__file__), 'view'),
            'cookie_secret': 'e440769943b4e8442f09de341f3fea28462d2341f483a0ed9a3d5d3859f==78d',
            'login_url': '/',
            'session_secret': ,
            'session_timeout': 3600,

            'port': 5601,
            'wx_token': 'weixin',
            }

web_handlers = [
        (r'/wx', wx.WX),
        ]

define(, default=settings['port'], help=, type=int)

if __name__ == '__main__':
    app = tornado.web.Application(web_handlers, **settings)
    tornado.options.parse_command_line()
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)

 tornado.ioloop.IOLoop.instance().start()   配置好程序源代码后运行,确认运行无误后再在公众号设置页面点击 提交 ,如果程序运行没问题,会显示接入成功。
接入图灵机器人   要接入图灵机器人,首先需要在官网申请API Key。
  申请到之后可以利用以下代码包装一个自动回复接口:

import json
import requests
import traceback

class TulingAutoReply:
    def __init__(self, tuling_key, tuling_url):
        self.key = tuling_key
        self.url = tuling_url

    def reply(self, unicode_str):
        body = {'key': self.key, 'info': unicode_str.encode('utf-8')}
        r = requests.post(self.url, data=body)
        r.encoding = 'utf-8'
        resp = r.text
        if resp is None or len(resp) == 0:
            return None
        try:
            js = json.loads(resp)
            if js['code'] == 100000:
                return js['text'].replace('
', '\n')
            elif js['code'] == 200000:
                return js['url']
            else:
                return None
        except Exception:
            traceback.print_exc()
            return

None 编写公众号自动回复代码   利用 wechat-python-sdk 微信公众平台 Python 开发包可以很容易地处理公众号的所有消息。
  如下为处理来自微信官方服务器的微信公众号消息的 Tornado Handler对象(此代码会获取公众号收到的用户消息并调用刚刚包装的图灵机器人API自动回复) wx.py部分代码:

import tornado.escape
import tornado.web

auto_reply = TulingAutoReply(key, url) 

class WX(tornado.web.RequestHandler):
    def wx_proc_msg(self, body):
        try:
            wechat.parse_data(body)
        except ParseError:
            print 'Invalid Body Text'
            return
        if isinstance(wechat.message, TextMessage): 
            content = wechat.message.content
            reply = auto_reply.reply(content)
            if reply is not None:
                return wechat.response_text(content=reply)
            else:
                return wechat.response_text(content=)
        return wechat.response_text(content=u'知道了')

    def post(self):
        signature = self.get_argument('signature', 'default')
        timestamp = self.get_argument('timestamp', 'default')
        nonce = self.get_argument('nonce', 'default')
        if signature != 'default' and timestamp != 'default' and nonce != 'default' \
                and wechat.check_signature(signature, timestamp, nonce):
            body = self.request.body.decode('utf-8')
            try:
                result = self.wx_proc_msg(body)
                if result is not None:
                    self.write(result)
            except IOError, e:
                return