Django微信公众号消息自动回复开发指南

通过Python的中文分词库jieba和XML处理库xmltodict结合Django实现微信公众号消息自动回复。当用户通过微信公众号的对话框向后端发送消息时,微信服务器将POST消息的XML数据包推送至开发者填写的URL。具体流程如下:

图片[1]-Django微信公众号消息自动回复开发指南-山海云端论坛

首先,用户发送文本消息:“欢迎进入公众号交流”,在开发者后台收到公众平台发送的XML如下:

<code><xml></code><code> <ToUserName><![CDATA[公众号]]></ToUserName></code><code> <FromUserName><![CDATA[粉丝号]]></FromUserName></code><code> <CreateTime>1460537339</CreateTime></code><code> <MsgType><![CDATA[text]]></MsgType></code><code> <Content><![CDATA[欢迎进入公众号交流]]></Content></code><code> <MsgId>6272960105994287618</MsgId></code><code></xml></code>

说明:

  • CreateTime是微信公众平台记录粉丝发送消息的具体时间。
  • MsgType用于标记XML为文本消息,用于区别判断。
  • Content表示粉丝发给公众号的具体内容。
  • MsgId是公众平台为记录识别消息的标记数值,由微信后台系统自动生成。

若要回复给用户一条文本消息,内容为“test”,则开发者发送给公众平台后台的XML内容如下:

<code><xml></code><code> <ToUserName><![CDATA[粉丝号]]></ToUserName></code><code> <FromUserName><![CDATA[公众号]]></FromUserName></code><code> <CreateTime>1460541339</CreateTime></code><code> <MsgType><![CDATA[text]]></MsgType></code><code> <Content><![CDATA[test]]></Content></code><code></xml></code>

说明:

  • ToUserName(接收者)和FromUserName(发送者)。
  • CreateTime用于标记开发者回复消息的时间。
  • text表示发送文本消息(也可以是image/voice等类型)。
  • 文本换行可使用\n

微信公众号支持回复文本、图片、图文、语音、视频、音乐等类型的消息。根据微信官方的安全要求,需要用秘钥对收到的密文消息体进行解密,回复消息体也用此秘钥加密。

微信公众平台提供了示例代码,包括C++、PHP、Java、Python和C#版本

接下来,我们使用Django框架来实现微信公众号的自动回复消息。

安装所需库:

<br>pip install jieba xmltodict

直接上开发代码

<code><em># -*- coding: utf-8 -*-</em></code><code><br></code><code>from django.shortcuts import render</code><code>import hashlib</code><code><em># Create your views here.</em></code><code>from django.http.response import HttpResponse</code><code>from django.views.decorators.csrf import csrf_exempt</code><code>import xmltodict</code><code>import jieba</code><code>import time</code><code>@csrf_exempt</code><code>def wechat(request):</code><code> if request.method == 'GET':</code><code> signature = request.GET.get('signature')</code><code> timestamp = request.GET.get('timestamp', '')</code><code> nonce = request.GET.get('nonce', '')</code><code> echo_str = request.GET.get('echostr', '')</code><code> token='你的'</code><code> hashlist = [token, timestamp, nonce]</code><code> hashlist.sort()</code><code> list2 = ''.join(hashlist)</code><code> sha1 = hashlib.sha1()</code><code> sha1.update(list2.encode('utf-8'))</code><code> hashcode = sha1.hexdigest()</code><code> if hashcode == signature:</code><code> return HttpResponse(echo_str, content_type="text/plain")</code><code> else:</code><code> return HttpResponse('error', content_type="text/plain")</code><code> elif request.method == 'POST':</code><code> dict_xml=request.body.decode('utf-8')</code><code> xmlData = xmltodict.parse(dict_xml)</code><code> msg_type = xmlData['xml']['MsgType']</code><code> if msg_type == 'text':</code><code> contents = jieba.cut(xmlData['xml']['Content'])</code><code> for i in contents:</code><code> if i=="微信公众号开发" or i=="小程序开发" :</code><code> content = "请关注Django与python学习"</code><code> resp_data = {</code><code> "xml": {"ToUserName": xmlData['xml']['FromUserName'],</code><code> "FromUserName": xmlData['xml']['ToUserName'],</code><code> "CreateTime": int(time.time()),</code><code> "MsgType": 'text',</code><code> "Content": content,</code><code> }</code><code> }</code><code> xmltodict.unparse(resp_data)</code><code> response = HttpResponse(xmltodict.unparse(resp_data), content_type="text/plain")</code><code> return response</code><code> else:</code><code> content = xmlData['xml']['Content']</code><code> resp_data={</code><code> "xml":{"ToUserName":xmlData['xml']['FromUserName'],</code><code> "FromUserName":xmlData['xml']['ToUserName'],</code><code> "CreateTime":int(time.time()),</code><code> "MsgType":'news',</code><code> "ArticleCount": 1,</code><code> "Articles": {</code><code> "item": {</code><code> "Title": "搜索"+content+"的结果",</code><code> "Description": "和"+content+"相关的内容",</code><code> "PicUrl": "https://www.baidu.com/img/flexible/logo/pc/result.png",</code><code> "Url": "https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=baidu&wd="+content</code><code> }</code><code> },</code><code> }</code><code> }</code><code> xmltodict.unparse(resp_data)</code><code> response = HttpResponse(xmltodict.unparse(resp_data), content_type="text/plain")</code><code> return response</code><code> elif msg_type == 'image':</code><code> content = "欢迎您"</code><code> resp_data = {</code><code> "xml": {"ToUserName": xmlData['xml']['FromUserName'],</code><code> "FromUserName": xmlData['xml']['ToUserName'],</code><code> "CreateTime": int(time.time()),</code><code> "MsgType": 'image',</code><code> "Content": content,</code><code> }</code><code> }</code><code> xmltodict.unparse(resp_data)</code><code> response = HttpResponse(xmltodict.unparse(resp_data), content_type="text/plain")</code><code> return response</code><code> elif msg_type == 'voice':</code><code> content="欢迎您"</code><code> resp_data={</code><code> "xml":{"ToUserName":xmlData['xml']['FromUserName'],</code><code> "FromUserName":xmlData['xml']['ToUserName'],</code><code> "CreateTime":int(time.time()),</code><code> "MsgType":'voice',</code><code> "Content":content,</code><code> }</code><code> }</code><code> xmltodict.unparse(resp_data)</code><code> response = HttpResponse(xmltodict.unparse(resp_data), content_type="text/plain")</code><code> return response</code><code> elif msg_type == 'video':</code><code> content = "欢迎您"</code><code> resp_data = {</code><code> "xml": {"ToUserName": xmlData['xml']['FromUserName'],</code><code> "FromUserName": xmlData['xml']['ToUserName'],</code><code> "CreateTime": int(time.time()),</code><code> "MsgType": 'video',</code><code> "Content": content,</code><code> }</code><code> }</code><code> xmltodict.unparse(resp_data)</code><code> print(xmltodict.unparse(resp_data))</code><code> response = HttpResponse(xmltodict.unparse(resp_data), content_type="text/plain")</code><code> return response</code><code> elif msg_type == 'music':</code><code> content = "欢迎您"</code><code> resp_data = {</code><code> "xml": {"ToUserName": xmlData['xml']['FromUserName'],</code><code> "FromUserName": xmlData['xml']['ToUserName'],</code><code> "CreateTime": int(time.time()),</code><code> "MsgType": 'music',</code><code> "Content": content,</code><code> }</code><code> }</code><code> xmltodict.unparse(resp_data)</code><code> response = HttpResponse(xmltodict.unparse(resp_data), content_type="text/plain")</code><code> return response</code><code> elif msg_type == 'news':</code><code> resp_data = {</code><code> "xml": {"ToUserName": xmlData['xml']['FromUserName'],</code><code> "FromUserName": xmlData['xml']['ToUserName'],</code><code> "CreateTime": int(time.time()),</code><code> "MsgType": 'news',</code><code> "ArticleCount":1,</code><code> "Articles": {</code><code> "item":{</code><code> "Title":"Django之微信公众号开发接入",</code><code> "Description":"Django之微信公众号开发接入",</code><code> "PicUrl":"",</code><code> "Url":"https://mp.weixin.qq.com/s?__biz=MzAwNjE5MTE3Mw==&mid=2449814757&idx=1&sn=2f8a89d5bee110f4b598528303174480&chksm=8ce0b5cfbb973cd9c90b29d5a214e7489f88f0ea3bd1304c6fe503b727b7277c3c6809a1d39d&token=2126286068&lang=zh_CN#rd"</code><code> }</code><code> },</code><code> }</code><code> }</code><code> xmltodict.unparse(resp_data)</code><code> response = HttpResponse(xmltodict.unparse(resp_data), content_type="text/plain")</code><code> return response</code><code> elif msg_type == 'event':</code><code> if xmlData['xml']['Event']=='subscribe':</code><code> content="谢谢您的关注"</code><code> resp_data={</code><code> "xml":{"ToUserName":xmlData['xml']['FromUserName'],</code><code> "FromUserName":xmlData['xml']['ToUserName'],</code><code> "CreateTime":int(time.time()),</code><code> "MsgType":'text',</code><code> "Content":content,</code><code> }</code><code> }</code><code> xmltodict.unparse(resp_data)</code><code> response = HttpResponse(xmltodict.unparse(resp_data), content_type="text/plain")</code><code> return response</code><code> if xmlData['xml']['Event']=='unsubscribe':</code><code> content="您取关后将接受不到我们的推送服务"</code><code> resp_data={</code><code> "xml":{"ToUserName":xmlData['xml']['FromUserName'],</code><code> "FromUserName":xmlData['xml']['ToUserName'],</code><code> "CreateTime":int(time.time()),</code><code> "MsgType":'text',</code><code> "Content":content,</code><code> }</code><code> }</code><code> xmltodict.unparse(resp_data)</code><code> response = HttpResponse(xmltodict.unparse(resp_data), content_type="text/plain")</code><code> return response</code><code> if xmlData['xml']['Event']=='LOCATION':</code><code> content="我们已收到你发送的定位"</code><code> openid = xmlData['xml']['FromUserName'] <em># 发送者的openid</em></code><code> Latitude=xmlData['xml']['Latitude']<em>#地理位置纬度</em></code><code> Longitude=xmlData['xml']['Longitude']<em>#地理位置经度</em></code><code> Precision=xmlData['xml']['Precision']<em>#地理位置精度</em></code><code> resp_data={</code><code> "xml":{"ToUserName":xmlData['xml']['FromUserName'],</code><code> "FromUserName":xmlData['xml']['ToUserName'],</code><code> "CreateTime":int(time.time()),</code><code> "MsgType":'text',</code><code> "Content":content,</code><code> }</code><code> }</code><code> xmltodict.unparse(resp_data)</code><code> response = HttpResponse(xmltodict.unparse(resp_data), content_type="text/plain")</code><code> return response</code><code> if xmlData['xml']['Event']=='CLICK':</code><code> content="我们已收到你发送的定位"</code><code> openid=xmlData['xml']['FromUserName']<em>#发送者的openid</em></code><code> EventKey=xmlData['xml']['EventKey']<em>#事件 KEY 值,与自定义菜单接口中 KEY 值对应</em></code><code><br></code><code> resp_data={</code><code> "xml":{"ToUserName":xmlData['xml']['FromUserName'],</code><code> "FromUserName":xmlData['xml']['ToUserName'],</code><code> "CreateTime":int(time.time()),</code><code> "MsgType":'text',</code><code> "Content":content,</code><code> }</code><code> }</code><code> xmltodict.unparse(resp_data)</code><code> response = HttpResponse(xmltodict.unparse(resp_data), content_type="text/plain")</code><code> return response</code><code> if xmlData['xml']['Event']=='VIEW':</code><code> content="我们已收到你发送的定位"</code><code> openid=xmlData['xml']['FromUserName']<em>#发送者的openid</em></code><code> EventKey=xmlData['xml']['EventKey']<em>#事件 KEY 值,设置的跳转URL</em></code><code><br></code><code> resp_data={</code><code> "xml":{"ToUserName":xmlData['xml']['FromUserName'],</code><code> "FromUserName":xmlData['xml']['ToUserName'],</code><code> "CreateTime":int(time.time()),</code><code> "MsgType":'text',</code><code> "Content":content,</code><code> }</code><code> }</code><code> xmltodict.unparse(resp_data)</code><code> response = HttpResponse(xmltodict.unparse(resp_data), content_type="text/plain")</code><code> return response</code><code> else:</code><code> content = "这是其他消息,不便回复"</code><code> resp_data = {</code><code> "xml": {"ToUserName": xmlData['xml']['FromUserName'],</code><code> "FromUserName": xmlData['xml']['ToUserName'],</code><code> "CreateTime": int(time.time()),</code><code> "MsgType": 'text',</code><code> "Content": content,</code><code> }</code><code> }</code><code> xmltodict.unparse(resp_data)</code><code> response = HttpResponse(xmltodict.unparse(resp_data), content_type="text/plain")</code><code> return response</code>

完成以上代码后,配置URL即可实现微信公众号自动回复。

消息回复的内容可以建立一个库或者加入ChatGPT,实现对用户消息的判断和回复。

© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容