Python中微信公众号接口与hug框架如何结合使用?

老哥们好,我现在用 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 ""
Python中微信公众号接口与hug框架如何结合使用?


7 回复

关注了公众号的用户输入的信息都会被微信公众号服务器 post 到这个 url 来,用 token 握手验证只在第一次.


要结合微信公众号接口和Hug框架,关键在于处理微信服务器的验证请求和消息/事件的路由。Hug的异步特性很适合处理微信的HTTP回调。

核心步骤:

  1. 在微信公众号后台配置服务器URL(指向你的Hug应用)
  2. 实现GET请求处理用于微信服务器验证
  3. 实现POST请求处理接收用户消息和事件

示例代码:

import hug
import xml.etree.ElementTree as ET
from hashlib import sha1
import time

# 微信配置
WECHAT_TOKEN = 'your_token_here'

@hug.get('/wechat')
async def wechat_verify(signature: hug.types.text, 
                        timestamp: hug.types.text,
                        nonce: hug.types.text,
                        echostr: hug.types.text):
    """处理微信服务器验证"""
    # 验证签名
    params = [WECHAT_TOKEN, timestamp, nonce]
    params.sort()
    sign = sha1(''.join(params).encode()).hexdigest()
    
    if sign == signature:
        return echostr
    return '验证失败'

@hug.post('/wechat')
async def wechat_message(body):
    """处理微信消息和事件"""
    xml_data = await body.read()
    root = ET.fromstring(xml_data)
    
    msg_type = root.find('MsgType').text
    from_user = root.find('FromUserName').text
    to_user = root.find('ToUserName').text
    
    response = ET.Element('xml')
    ET.SubElement(response, 'ToUserName').text = from_user
    ET.SubElement(response, 'FromUserName').text = to_user
    ET.SubElement(response, 'CreateTime').text = str(int(time.time()))
    
    if msg_type == 'text':
        content = root.find('Content').text
        ET.SubElement(response, 'MsgType').text = 'text'
        ET.SubElement(response, 'Content').text = f'收到: {content}'
    elif msg_type == 'event':
        event = root.find('Event').text
        ET.SubElement(response, 'MsgType').text = 'text'
        ET.SubElement(response, 'Content').text = f'事件: {event}'
    
    return ET.tostring(response, encoding='unicode')

# 运行应用
if __name__ == '__main__':
    hug.API(__name__).http.serve()

简单说:用Hug处理微信的GET/POST请求,注意签名验证和XML消息格式。

老哥。微信的 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 报错了,能不能详细讲解一下,谢谢

重新用 hug 写了一个只做微信 token 接口的代码
# -- coding:utf-8 --

import hug
from hug import request

import hashlib


.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

换了 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”)

.route(’/get_respnse’,methods=[‘GET’,‘POST’])
def response(user_input):

if request.method == ‘POST’:
response = bot.get_response(user_input).text
return {“response”:response}

.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)

都你说了,
在公众平台官网的开发-基本设置页面,勾选协议成为开发者,点击“修改配置”按钮,填写服务器地址( 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

谢谢老哥,我现在用 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



.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’]))

.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 -

回到顶部