V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
brcehuai8
V2EX  ›  Python

微信公众号接口与 hug 框架问题

  •  
  •   brcehuai8 · 2018-03-07 10:40:15 +08:00 · 2114 次点击
    这是一个创建于 2213 天前的主题,其中的信息可能已经有所发展或是发生改变。
    老哥们好,我现在用 chatterbot 做了个聊天机器人,用 python3 hug 框架封装好 API 了,路径是 xxx/get_response?user_input=
    微信公众号的 token 验证需要返回哈希值所以机器人的应答路径用不了,重新定义了一个 get 路径,/wx_token。
    那么问题来了,我的 hug 该怎么写才能又通过微信公众平台 token 验证,又可以 get_response?user_input 呢
    这是现在 hug 的代码:
    #!/usr/bin/env python
    # coding: utf-8
    from chatterbot import ChatBot
    from chatterbot.trainers import ListTrainer
    from hug import request
    import hug

    bot = ChatBot("hugbot", read_only=True)

    bot.set_trainer(ListTrainer)

    bot.train("ListTrainer")

    @hug.get()
    def get_response(user_input):
    response = bot.get_response(user_input).text
    return {"response":response}

    @hug.get('/wx_token')
    def wx_token(signature, timestamp, nonce, echostr):
    if request.method == 'GET'
    token = 'weixin'
    data = request.args
    signature = data.get('signature','')
    timestamp = data.get('timestamp','')
    nonce = data.get('nonce','')
    echostr = data.get('echostr','')
    list = [token, timestamp, nonce]
    list.sort()
    s = list[0] + list[1] + list[2]
    #sha1 加密算法
    hascode = hashlib.sha1(s.encode('utf-8')).hexdigest()
    #如果是来自微信的请求,则回复 echostr
    if hascode == signature:
    return echostr
    else:
    return ""
    6 条回复    2018-03-08 10:25:39 +08:00
    xpresslink
        1
    xpresslink  
       2018-03-07 11:52:42 +08:00
    关注了公众号的用户输入的信息都会被微信公众号服务器 post 到这个 url 来,用 token 握手验证只在第一次.
    brcehuai8
        2
    brcehuai8  
    OP
       2018-03-07 14:27:11 +08:00
    @xpresslink 老哥。微信的 token 是 get 这个是没问题的,我把 get_response 改成 post 方法就 127.0.0.1 - - [07/Mar/2018 14:24:56] "GET /post_response?user_input=hi HTTP/1.1" 405 0 报错了,能不能详细讲解一下,谢谢
    brcehuai8
        3
    brcehuai8  
    OP
       2018-03-07 14:39:49 +08:00
    重新用 hug 写了一个只做微信 token 接口的代码
    # -*- coding:utf-8 -*-

    import hug
    from hug import request

    import hashlib


    @hug.get('/wx_token')
    def wechat():
    token = 'weixin'
    #获取输入参数
    data = request.args
    signature = data.get('signature','')
    timestamp = data.get('timestamp','')
    nonce = data.get('nonce','')
    echostr = data.get('echostr','')
    #字典排序
    list = [token, timestamp, nonce]
    list.sort()

    s = list[0] + list[1] + list[2]
    #sha1 加密算法
    hascode = hashlib.sha1(s.encode('utf-8')).hexdigest()
    #如果是来自微信的请求,则回复 echostr
    if hascode == signature:
    return echostr
    else:
    return ""


    if __name__ == '__main__':
    app.run(port=8000)
    也报这个错
    AttributeError: module 'falcon.request' has no attribute 'args'
    127.0.0.1 - - [07/Mar/2018 14:38:39] "GET /wx_token?signature=c9c860983ab4bc4322a39023a14d7dc7d3ecc888&echostr=8708986455401151215&timestamp=1520404719&nonce=786176401 HTTP/1.1" 500 59
    brcehuai8
        4
    brcehuai8  
    OP
       2018-03-07 16:01:30 +08:00
    换了 flask 的框架,token 倒是验证成功了,但是和机器人就不能工作了
    # -*- coding:utf-8 -*-

    from flask import Flask
    from flask import request
    from chatterbot import ChatBot
    from chatterbot.trainers import ListTrainer
    import hashlib

    app = Flask(__name__)
    app.debug = True

    bot = ChatBot("bot", read_only=True)

    bot.set_trainer(ListTrainer)

    bot.train("ListTrainer")

    @app.route('/get_respnse',methods=['GET','POST'])
    def response(user_input):

    if request.method == 'POST':
    response = bot.get_response(user_input).text
    return {"response":response}

    @app.route('/wx_flask',methods=['GET','POST'])
    def wechat():

    if request.method == 'GET':
    #这里改写你在微信公众平台里输入的 token
    token = 'weixin'
    #获取输入参数
    data = request.args
    signature = data.get('signature','')
    timestamp = data.get('timestamp','')
    nonce = data.get('nonce','')
    echostr = data.get('echostr','')
    #字典排序
    list = [token, timestamp, nonce]
    list.sort()

    s = list[0] + list[1] + list[2]
    #sha1 加密算法
    hascode = hashlib.sha1(s.encode('utf-8')).hexdigest()
    #如果是来自微信的请求,则回复 echostr
    if hascode == signature:
    return echostr
    else:
    return ""



    if __name__ == '__main__':
    app.run(port=8000)
    xpresslink
        5
    xpresslink  
       2018-03-07 20:24:20 +08:00
    都你说了,
    在公众平台官网的开发-基本设置页面,勾选协议成为开发者,点击“修改配置”按钮,填写服务器地址( URL )、Token 和 EncodingAESKey,其中 URL 是开发者用来接收微信消息和事件的接口 URL
    握手成功后。用户输入的文字信息会被微信服务器打包成一个 xml 文件 post 到你这人 URL 来。

    <xml> <ToUserName>< ![CDATA[toUser] ]></ToUserName>
    <FromUserName>< ![CDATA[fromUser] ]></FromUserName>
    <CreateTime>1348831860</CreateTime>
    <MsgType>< ![CDATA[text] ]></MsgType>
    <Content>< ![CDATA[this is a test] ]></Content>
    <MsgId>1234567890123456</MsgId>
    </xml>
    参数 描述
    ToUserName 开发者微信号
    FromUserName 发送方帐号(一个 OpenID )
    CreateTime 消息创建时间 (整型)
    MsgType text
    Content 文本消息内容
    MsgId 消息 id,64 位整型

    你的程序要解析这个 xml 把 content 取出来,再发给你的机器人,把回复打成 xml 包 ToUser/FromUser 对调,response 回微信服务器,要在 5 秒钟以内完成。

    你仔细看一下官方文档吧。
    https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140453
    brcehuai8
        6
    brcehuai8  
    OP
       2018-03-08 10:25:39 +08:00
    @xpresslink 谢谢老哥,我现在用 flask 的一个加工一下,token 过了,然后从微信 post 过来的请求跳转到一个 get 应答上没做好,代码如下:
    # -*- coding:utf-8 -*-

    from flask import Flask
    from flask import request
    from chatterbot.trainers import ListTrainer
    from chatterbot import ChatBot

    import hashlib

    bot = ChatBot("hugbot", read_only=True)

    bot.set_trainer(ListTrainer)

    bot.train("ListTrainer")

    app = Flask(__name__)
    app.debug = True



    @app.route('/wx_flask',methods=['GET','POST'])
    def wechat():

    if request.method == 'GET':
    #这里改写你在微信公众平台里输入的 token
    token = 'weixin'
    #获取输入参数
    data = request.args
    signature = data.get('signature','')
    timestamp = data.get('timestamp','')
    nonce = data.get('nonce','')
    echostr = data.get('echostr','')
    #字典排序
    list = [token, timestamp, nonce]
    list.sort()

    s = list[0] + list[1] + list[2]
    #sha1 加密算法
    hascode = hashlib.sha1(s.encode('utf-8')).hexdigest()
    #如果是来自微信的请求,则回复 echostr
    if hascode == signature:
    return echostr
    else:
    return ""

    if request.method == 'POST':
    if request.form['user_input']=='*':
    return redirect(url_for('get_response',username=request.form['user_input']))

    @app.route('/get_response')
    def get_response(user_input):
    response = bot.get_response(user_input).text
    return {"response":response}

    if __name__ == '__main__':
    app.run(port=8000)

    报错信息如下:

    127.0.0.1 - - [08/Mar/2018 10:24:06] "POST /wx_flask?signature=b10cc129d5ab20da719de490a06c07d388a58c03&timestamp=1520475846&nonce=1060485406&openid=oCIOX1YmRCgRvKC_DOD0TqHI50YI HTTP/1.1" 400 -
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1742 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 16:37 · PVG 00:37 · LAX 09:37 · JFK 12:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.