Django – 微信公众号开发之公众号接入与回复消息(被动)

  • A+
所属分类:Python教程 学编程

一、介绍

1.1、公众号介绍

微信公众号分为服务号、订阅号、企业号,订阅号可以个人申请,服务号和企业号要有企业资质才可以。

我们所说的微信公众号开发指的是订阅号和服务号。关于订阅号和服务器的区别,官方是这样解释的

1.服务号:主要偏向于服务交互(功能类似12315,114,银行,提供绑定信息,服务交互),每月可群发4条消息;服务号适用人群:媒体、企业、政府或其他组织。

2.订阅号:主要偏向于为用户传达资讯,(功能类似报纸杂志,为用户提供新闻信息或娱乐趣事),每天可群发1条消息;订阅号适用人群:个人、媒体、企业、政府或其他组织。

1.2、微信公众号注册

进入微信公众号注册页面https://mp.weixin.qq.com/ 点击公众号右上方的注册按钮,进入注册界面,填写基本信息,选择需要注册的公众号类型后根据提示完善信息即可。

1.3、使用测试公众号

个人订阅号有一些接口是没有权限的,也就是说个人订阅号无法调用一些高级的权限接口,如生成二维码、网页授权、自定义菜单、微信支付这样的接口权限个人订阅号是没有调用权限的, 幸运的是,微信公众平台提供了测试公众账号,测试公众号有很多个人订阅号不具备的权限, 测试公众号的注册地址为:

http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

用微信扫描页面中的二维码进行登录,登录成功后,就可以看到腾讯分配给我们的测试公众号的信息了,如下图所示, 接下来我们就可以搭建环境,进行开发测试了

Django - 微信公众号开发之公众号接入与回复消息(被动)

二、开始公众号开发

附上微信官方的开发文档地址:https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html

微信服务器与我们的程序之前的通讯简图如下:
用户 --> 微信公众号服务器 --> 我们的程序

2.1、微信公众号接入(校验签名)

接入指南地址:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html

1.前面服务器配置包含服务器地址(URL)、令牌(Token) 和 消息加解密密钥(EncodingAESKey)。

服务器地址即公众号后台提供业务逻辑的入口地址,目前只支持80端口,之后包括接入验证以及任何其它的操作的请求(例如消息的发送、菜单管理、素材管理等)都要从这个地址进入。接入验证和其它请求的区别就是,接入验证时是get请求,其它时候是post请求;

Token可由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性);

EncodingAESKey由开发者手动填写或随机生成,将用作消息体加解密密钥。本例中全部以未加密的明文消息方式,不涉及此配置项。

2.验证服务器地址的有效性,当点击“提交”按钮后,微信服务器将发送一个http的get请求到刚刚填写的服务器地址,并且携带四个参数:

Django - 微信公众号开发之公众号接入与回复消息(被动)

接到请求后,我们需要做如下三步,若确认此次GET请求来自微信服务器,原样返回echostr参数内容,则接入生效,否则接入失败。

基于django框架的Python代码如下:

1.urls.py内容如下:
from django.conf.urls import url
from django.contrib import admin
from wechat_api import views

urlpatterns = [
    url(r'^wx_api/$', views.wx_api),
]

2.views.py中函数如下
from django.shortcuts import render,redirect,HttpResponse
import hashlib
import xmltodict
import time
from urllib.request import urlopen
import json

WECHAT_APPID = "wx639c597ed8xxxx"       #你的appid
WECHAT_APPSECRET = "205e6f1aed90c81a0cxxxxx"      #你的appsecret
token = "xxxx"      # 自己设置的token

def wx_api(request):
    # GET请求执行这里 - 处理微信认证用
    if request.method == "GET":
        # 获取GET请求里的参数
        signature = request.GET.get("signature")      # 先获取加密签名
        timestamp = request.GET.get("timestamp")      # 获取时间戳
        nonce = request.GET.get("nonce")         # 获取随机数
        echostr = request.GET.get("echostr")
        # 校验获取到的参数内容不为空
        if signature and timestamp and nonce and echostr:
            # 使用字典序排序(按照字母或数字的大小顺序进行排序)
            lst = [token, timestamp, nonce]
            lst.sort()
            # 字符串拼接,然后进行sha1加密(得到的是加密的对象)
            temp = ''.join(lst)
            sha1 = hashlib.sha1(temp.encode('utf-8'))
            # 取加密后的结果
            hashcode = sha1.hexdigest()
            # 将加密后的字符串和signatrue对比,如果相同返回echostr,表示验证成功
            if hashcode == signature:
                return HttpResponse(echostr)
            return HttpResponse("403")
        return HttpResponse('404')

配置接口配置信息,如下图:

Django - 微信公众号开发之公众号接入与回复消息(被动)

出现图中绿色的提示配置成功就表示配置成功了。

三、消息管理

微信官方文档地址:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html

官方说明:
当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。

请注意:

1、关于重试的消息排重,推荐使用msgid排重。

2、微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。假如服务器无法保证在五秒内处理并回复,

可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。详情请见“发送消息-被动回复消息”。

3、如果开发者需要对用户消息在5秒内立即做出回应,即使用“发送消息-被动回复消息”接口向用户被动回复消息时,可以在

公众平台官网的开发者中心处设置消息加密。开启加密后,用户发来的消息和开发者回复的消息都会被加密(但开发者通过客服

接口等API调用形式向用户发送消息,则不受影响)。关于消息加解密的详细说明,请见“发送消息-被动回复消息加解密说明”。

微信消息类型分为:
1.文本消息
2.图片消息
3.语音消息
4.视频消息
5.小视频消息
6.地理位置消息
7.链接消息

这里附上消息处理的django代码(以下代码是公众号接入部分代码的下半部分):

# POST请求执行这里 - 实现与微信消息交互(被动)

    else:
        #获取微信发来的xml消息,并判断消息是否存在
        xml_str = request.body
        if xml_str:
            #如果xml消息存在,就将xml类型的消息通过xmltodict模块转换为字典类型的消息并只获取xml键里面的值
            xml_dict = xmltodict.parse(xml_str)
            xml_dict = xml_dict.get("xml")
            msg_type = xml_dict.get("MsgType")        #获取消息的类型
            msg_content = xml_dict.get("Content")     # 获取消息的内容
            event_type = xml_dict.get("Event")        #获取关注事件(subscribe(订阅)、unsubscribe(取消订阅))
            # 判断消息内容,给指定的回复
            if msg_content == "测试":
                # 构造返回值,经由微信服务器回复给用户的消息内容
                resp_dict = {
                    "xml": {
                        "ToUserName": xml_dict.get("FromUserName"),      #发消息给谁(发送给发来消息的人)
                        "FromUserName": xml_dict.get("ToUserName"),      #谁发送的消息(原消息的目标人发送的消息)
                        "CreateTime": int(time.time()),                    #当前的时间戳(转换为整数类型)
                        "MsgType": "text",                                 #消息类型(文本类型)
                        "Content": "https://www.zhuimengren.co/"        #要回复的消息内容(这里是把接收到的消息返回给客户)
                    }
                }
            #如果是订阅,给指定的回复
            elif event_type == "subscribe":
                resp_dict = {
                    "xml": {
                        "ToUserName": xml_dict.get("FromUserName"),  # 发消息给谁(发送给发来消息的人)
                        "FromUserName": xml_dict.get("ToUserName"),  # 谁发送的消息(原消息的目标人发送的消息)
                        "CreateTime": int(time.time()),  # 当前的时间戳(转换为整数类型)
                        "MsgType": "text",  # 消息类型(文本类型)
                        "Content": "你好,欢迎关注追梦人的测试公众号!!"  # 要回复的消息内容
                    }
                }
            else:        #如果是其他文本消息就默认回复
                resp_dict = {
                    "xml": {
                        "ToUserName": xml_dict.get("FromUserName"),
                        "FromUserName": xml_dict.get("ToUserName"),
                        "CreateTime": int(time.time()),
                        "MsgType": "text",
                        "Content": "消息已收到,未定义该指令。"
                    }
                }
            # 将字典转换为xml字符串
            resp_xml_str = xmltodict.unparse(resp_dict)
            # 返回消息数据给微信服务器
            return HttpResponse(resp_xml_str)

使用微信扫面二维码关注测试公众号后测试下,测试截图如下:
Django - 微信公众号开发之公众号接入与回复消息(被动)

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: