本篇博客使用Django框架,搭配uWsgi和Nginx,结合着Postman API调试工具,实现了微信公众号用户消息自动回复的功能,并成功部署到腾讯云服务器上。
在上篇博客中,我们已经配置好了腾讯云服务器,并能够进行简单的交互。
URL: http://服务器公网IP/wx
Token: 自己设置一条字符串
EncodingAESKey: 随机生成就可
消息加解密方式: 为方便调试,暂时选择明文模式
上述信息填写完后,选择提交会触发一个GET
请求来验证Token,验证的逻辑图如下:
下面我们在项目目录中的views.py
文件中来实现这个逻辑,代码如下:
from django.http import HttpResponse
import hashlib
# Create your views here.
def TencentView(request):
if request.method == 'GET':
# 解析参数
data = request.GET
if len(data) == 0:
return HttpResponse(content="hello, this is WeChat view")
signature = data.get(key='signature', default='')
timestamp = data.get(key='timestamp', default='')
nonce = data.get(key='nonce', default='')
echostr = data.get(key='echostr', default='')
# 请按照公众平台官网\基本配置中信息填写
token = "xxxxxxxxxxxxxxxxxx"
list_para = [token, timestamp, nonce]
list_para.sort()
list_str = ''.join(list_para).encode('utf-8')
sha1 = hashlib.sha1()
sha1.update(list_str)
# map(sha1.update, list_para)
# 加密
hashcode = sha1.hexdigest()
print("/GET func: hashcode: {0}, signature: {1}".format(hashcode, signature))
if hashcode == signature:
return HttpResponse(content=echostr)
else:
return HttpResponse(content='验证失败')
elif request.method == 'POST':
pass
这里有一个坑,官方给的示例使用Python2写的,但Python2的hashlib加密与Python3中的不一样,Python3需要先进行
utf-8
编码。
上述配置无误后,再次提交就会验证成功,如果仍未成功,请检查一下加密结果是否出错了,若token验证成功,会自动返回基本配置的主页面,点击启动按钮。
粉丝给公众号发送文本消息:“hello”,在开发者后台,收到公众平台发送的xml
如下:
<xml>
<ToUserName>ToUserName>
<FromUserName>FromUserName>
<CreateTime>1460537339CreateTime>
<MsgType>MsgType>
<Content>Content>
<MsgId>6272960105994287618MsgId>
xml>
字段说明如下:
字段 | 作用 |
---|---|
ToUserName |
公众号 |
FromUserName |
粉丝号 |
CreateTime |
微信公众平台记录粉丝发送该消息的具体时间 |
MsgType |
消息类型,有text 、image 、voice 等 |
Content |
消息内容 |
MsgId |
公众平台为记录识别该消息的一个标记数值,微信后台系统自动产生 |
公众号想回复给粉丝一条文本消息,内容为“test”, 那么开发者发送给公众平台后台的xml
内容如下:
<xml>
<ToUserName>ToUserName>
<FromUserName>FromUserName>
<CreateTime>1460541339CreateTime>
<MsgType>MsgType>
<Content>Content>
xml>
假如服务器无法保证在五秒内处理回复,则必须回复“success”或者“”(空串),否则微信后台会提示“该公众号暂时无法提供服务,请稍后再试”。
消息接收-回复流程图如下:
下面我们继续在项目目录中的views.py
文件中来实现这个流程,增添代码如下:
from xml.etree import ElementTree
import time
class ParseXmlMsg(object):
def __init__(self, xmlData):
self.ToUserName = xmlData.find('ToUserName').text
self.FromUserName = xmlData.find('FromUserName').text
self.CreateTime = xmlData.find('CreateTime').text
self.MsgType = xmlData.find('MsgType').text
self.MsgId = xmlData.find('MsgId').text
if self.MsgType == 'text':
self.Content = xmlData.find('Content').text.encode('utf-8')
elif self.MsgType == 'image':
self.PicUrl = xmlData.find('PicUrl').text
self.MediaId = xmlData.find('MediaId').text
class TextMsg(object):
def __init__(self, toUserName, fromUserName, content):
# 私有对象,禁止外部访问
self.__dict = dict()
self.__dict['ToUserName'] = toUserName
self.__dict['FromUserName'] = fromUserName
self.__dict['CreateTime'] = int(time.time())
self.__dict['Content'] = content
def send(self):
XmlForm = """
{CreateTime}
"""
return XmlForm.format(**self.__dict)
class ImageMsg(object):
def __init__(self, toUserName, fromUserName, mediaId):
self.__dict = dict()
self.__dict['ToUserName'] = toUserName
self.__dict['FromUserName'] = fromUserName
self.__dict['CreateTime'] = int(time.time())
self.__dict['MediaId'] = mediaId
def send(self):
XmlForm = """
{CreateTime}
"""
return XmlForm.format(**self.__dict)
另外还需要在elif
语句中增加以下代码:
elif request.method == 'POST':
# 解析发送过来的body
webData = request.body
# print("Post webdata is ", webData)
xmlData = ElementTree.fromstring(webData)
recMsg = ParseXmlMsg(xmlData)
if recMsg.MsgType == 'text':
toUser = recMsg.FromUserName
fromUser = recMsg.ToUserName
content = 'test'
replyMsg = TextMsg(toUser, fromUser, content)
return HttpResponse(content=replyMsg.send())
elif recMsg.MsgType == 'image':
print('暂时不做处理')
return HttpResponse(content='success')
为了调试方便,我们可以在本地启动项目,然后通过Postman来发送-接收xml
消息,调试完毕无误后再上传到服务器。
# 在启动之前,先注释掉settings.py文件中的一行代码,关闭CSRF验证
# 否则POST时会触发CSRF验证失败
# 'django.middleware.csrf.CsrfViewMiddleware'
python manage.py runserver
POST
请求,在Body
菜单栏中填入我们需要发送的xml
消息,具体·配置信息如下图所示Send
发送,在下方响应信息栏中我们就会收到返回的信息
发送的消息为“hello”,收到的信息为“test”,说明很OK,然后将代码上传到服务器。
上传服务器后记得重启一下
uWsgi
和Nginx
哦!
微信公众平台提供了一个在线测试平台,通过这个平台可以模拟粉丝与公众号的互动。
FromUserName
在配置微信公众号时,基本配置菜单栏那里可以看到。
配置无误后,点击下方检查问题
按钮,不出意外的话,你会得到以下信息:
OK!很nice!!!