赞
踩
上次我们已经完成了微信公众号开发环境的搭建,并完成了服务器和微信公众号的校验。下面让我们来开始实际开发。
如果还没有微信公众号开发环境的,请参考我上一篇文章:
本篇文章的内容为带领大家打通用户与服务器的信息交流通道:用户发的消息能在服务器收到,服务器能回复消息给用户。
昨天的代码只是完成了微信公众号和服务器的校验,并没有地方处理用户的消息,下面我们来加上。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from flask import Flask, request
import hashlib
app = Flask(__name__)
##### 修改1:将昨天的校验代码封装成单独的函数 #####
def verify_wechat(request):
# 设置token,开发者配置中心使用
token = 'xxxxx' # <------ 替换成你自定义的Token
# 获取微信服务器发送过来的参数
data = request.args
signature = data.get('signature')
timestamp = data.get('timestamp')
nonce = data.get('nonce')
echostr = data.get('echostr')
# 对参数进行字典排序,拼接字符串
temp = [timestamp, nonce, token]
temp.sort()
temp = ''.join(temp)
# 加密
if (hashlib.sha1(temp.encode('utf8')).hexdigest() == signature):
return echostr
else:
return 'error', 403
##### 修改2:将服务访问路径由昨天的'/'换成'/wechatai' #####
##### 这里也可以不换路径,名字也可以你自己随意定 #####
@app.route('/wechatai', methods=['GET', 'POST'])
def wechatai():
##### 修改3:当接受到的消息为GET请求时,执行校验,如果为POST请求,则认为是用户消息,处理用户消息
if request.method == 'GET':
return verify_wechat(request)
else:
# 处理POST请求
print("user request data: ", request.data)
return "ok" # <--------- 一定要加返回值!
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80, debug=True)
如果你执行了上面的“修改2”,将访问路径改了,那需要到公众号里对服务器配置进行相应的修改,即在URL后面也加入这个路径,这样才能访问到。
- 首先确保完成了上面的环境搭建和校验成功。
- 确保你的程序已经开始运行
在配置服务器的公众号后台 —> “服务器配置” —> 点击“启用”
这样就相当于与咱们的服务器打通了,用户发的消息都会被微信服务器转发到咱们自己的服务上去,咱们就可以在自己的服务器上处理消息了。
首先你得关注这个公众号
(1)打开这个公众号页面,发送消息“test”
(2)去服务器上查看你的程序收到的消息
如果正常,你应该能在你的程序运行后台看到下面的信息。这一坨数据下文我会解释其意思,这里你先能收到它就OK了。
(1)服务器收不到用户消息:校验成功,但是用户发的消息服务器看不到。
微信公众号可以验证后台服务器(get),但却接收不到微信用户的消息及事件通知的一个可能性
下面我们来看下服务收到的用户消息内容:
b'<xml><ToUserName><![CDATA[gh_fa8fa31]]></ToUserName>\n<FromUserName><![CDATA[oNexy6R4Ubm8gUCr1U]]></FromUserName>\n<CreateTime>1704420739</CreateTime>\n<MsgType><![CDATA[text]]></MsgType>\n<Content><![CDATA[test]]></Content>\n<MsgId>244014308074</MsgId>\n</xml>'
可以看到这是一个xml格式的字符串。用Python将以上xml字符串格式化打印出来,格式化打印xml字符串内容的代码如下:
import xml.etree.ElementTree as ET
def printXML(xml_content):
# 创建XML元素
element = ET.XML(xml_content)
# 使用indent()函数进行格式化打印
ET.indent(element)
print(ET.tostring(element, encoding='unicode'))
调用函数打印:
python printXML(request.data)
打印如下:
<xml>
<ToUserName>gh_fa8fa31e</ToUserName>
<FromUserName>oNexy6R49UkCr1U</FromUserName>
<CreateTime>1704424380</CreateTime>
<MsgType>text</MsgType>
<Content>test</Content>
<MsgId>244099103</MsgId>
</xml>
这是一个text类型的消息,内容是test。知道用户消息的内容结构之后,现在我们就可以提取出里面的Content来做一些相应的处理了,比如回复用户消息。
先来提取用户消息中的Content内容,也就是用户发过来的文字:
(1)定义提取函数
def getUserMessageContentFromXML(xml_content):
# 解析XML字符串
root = ET.fromstring(xml_content)
# 提取数据
content = root.find('Content').text
from_user_name = root.find('FromUserName').text
to_user_name = root.find('ToUserName').text
return content, from_user_name, to_user_name
(2)调用提取函数
@app.route('/wechatai', methods=['GET', 'POST'])
def wechatai():
if request.method == 'GET':
return verify_wechat(request)
else:
# 处理POST请求
print("user request data: ", request.data)
printXML(request.data)
user_message_content, from_user_name, to_user_name = getUserMessageContentFromXML(request.data) # <--------- 这里这里这里
print("user message content: ", user_message_content)
return "ok"
重新运行程序,用户发送过来消息后,应该能解析出结果如下:
上面我们能收到用户的消息,解析出用户发送的内容。但是如何给用户回消息呢?上面函数有一个 return "ok"
,但这只是给微信服务器回的消息,并不是给用户回的消息。
其实给用户回消息很简单,只需要将上面接收到的xml字符串,改一下里面的值即可。
(1)封装一个函数用来生成给回复的xml字符串
def generate_response_xml(from_user_name, to_user_name, output_content):
# 1. 先准备好回复的xml格式,后面只需要填充里面的字段即可
output_xml = '''
<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>'''
# 2. 通过 make_response 函数封装网络返回结构体
response = make_response(output_xml % (from_user_name, to_user_name, str(int(time.time())), output_content))
response.content_type = 'application/xml'
return response
可以看到,xml的内容与接收到的基本一致,我们只需要填充里面的ToUserName
、FromUserName
、CreateTime
、Content
即可。
ToUserName
、FromUserName
:与接收到的xml保持一致CreateTime
:当前时间戳Content
:要回复给用户的内容
(2)调用函数生成回复内容的结构
@app.route('/wechatai', methods=['GET', 'POST'])
def wechatai():
if request.method == 'GET':
return verify_wechat(request)
else:
# 处理POST请求
print("user request data: ", request.data)
printXML(request.data)
user_message_content, from_user_name, to_user_name = getUserMessageContentFromXML(request.data)
print("user message content: ", user_message_content)
return generate_response_xml(from_user_name, to_user_name, "你好") # <------ 这一句代码!给用户回复一个“你好”
重新运行程序,用户发送过来消息后,在微信公众号用户对话界面,用户应该能收到“你好”的消息。
至此,我们已经打通了用户与服务器的信息交流通道,后面就是在服务器端加自己的业务逻辑了。
从今天开始,持续学习,开始搞事情。踩坑不易,欢迎关注我,围观我!
有任何问题,欢迎+vx:jasper_8017,一起讨论,共同进步!
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。