一. 背景
话说很久以前开发了一次微信公众号,那时用的是官方文档推荐的框架 webpy 开发的,基本没怎么维护,加上最近云服务器也到期了(主要是最近比较懒…)数据被清了才想起来维护?,人呀真是不能懈怠。
最近又想起了搞事情了,准备再玩玩微信公众号。选技术栈时犹豫了,是用继续用 webpy 呢? 还是搞个新的框架玩玩?调研了一番惊奇的发现 webpy 的作者竟然去见 马克思 老人家了,哎真是天妒英才!
最终决定用 Django 作为技术栈,本篇记录下自己的开发历程。由于本人才疏学浅,难免会有不足之处,希望各位留言指正共同学习进步。(本文参考《微信公众号开发WiKi》)
二. 开发环境搭建
1. 开发工具
(1). 系统开发环境:Windows 10
(2). IntelliJ IDEA 2019.02
(3). Python 3.7.2
(4). django 2.2.3
(5). 部署环境:Ubuntu 18.04.1 LTS \n \l
2. 环境配置
2.1. python虚拟环境配置
# 安装虚拟环境配置工具virtualenv
pip install virtualenv
# 配置虚拟环境
virtualenv env
# windows激活虚拟环境
source env/Scripts/activate
# 如果时Linux环境,则使用下面的命令
source env/bin/activate
# 退出虚拟环境
deactivate
# 导出环境配置所需要的第三方库
pip freeze >> requirements.txt
2.2. 配置django环境
# 安装
pip install django
# 创建django 项目
django-admin startproject WePublic
# 创建开发微信公众号app
cd WePublic
python manage.py startapp mypublic
2.3. 代码管理配置
# 至于用什么代码管理工具就不管了
# 这里我用的是git + github, 配置什么的就不详细说了,这里只是配置下.gitignore文件
echo env/ >> .gitignore
echo __pycache__/ >> .gitignore
三. 微信公众号配置
具体的微信公众号的申请就不描述了,我们这里直接进行开发配置。这会提交提交配置会报错,别急,因为你的配置还没和微信服务器进行交互呢!
四.微信服务器认证与服务开发
来先晒一下程序整体的目录结构,本着实用原则,后续会用到那进行那块的详细描述,Django 的其他用法后续会进行学习整理分享:
ubuntu@VM-0-8-ubuntu:~/WePublic$ tree -CF -L 2
.
├── db.sqlite3
├── env/
│ ├── bin/
│ ├── include/
│ └── lib/
├── manage.py
├── mypublic/
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations/
│ ├── models.py
│ ├── __pycache__/
│ ├── receive.py
│ ├── reply.py
│ ├── tests.py
│ └── views.py
├── README.md
├── requirements.txt
└── WePublic/
├── __init__.py
├── __pycache__/
├── settings.py
├── urls.py
└── wsgi.py
来再上一张微信微信消息发送的逻辑图:
1. 与微信服务器认证
根据上面的微信消息发送逻辑,要完成微信认证需要进行一下操作:
(1)接收到参数分别提取出 signature、timestamp、nonce、echostr 字段;
(2)将 token、timestamp、nonce 字段组成字典排序得到 list;
(3)哈希算法加密list,得到 hashcode;
(4)判断 signature 和 hashcode 值是否相等,如果相等把 echostr 返回微信后台,供微信后台认证 token;不相等的话就不处理,返回个自定义的字符串;
(5)认证成功后,就可以继续其他业务服务开发了。
# views.py
from django.shortcuts import HttpResponse
from django.views.decorators.csrf import csrf_exempt
import hashlib
# Create your views here.
# django默认开启了csrf防护,@csrf_exempt是去掉防护
# 微信服务器进行参数交互,主要是和微信服务器进行身份的验证
@csrf_exempt
def check_signature(request):
if request.method == "GET":
print("request: ", request)
# 接受微信服务器get请求发过来的参数
# 将参数list中排序合成字符串,再用sha1加密得到新的字符串与微信发过来的signature对比,如果相同就返回echostr给服务器,校验通过
# ISSUES: TypeError: '<' not supported between instances of 'NoneType' and 'str'
# 解决方法:当获取的参数值为空是传空,而不是传None
signature = request.GET.get('signature', '')
timestamp = request.GET.get('timestamp', '')
nonce = request.GET.get('nonce', '')
echostr = request.GET.get('echostr', '')
# 微信公众号处配置的token
token = str("你在微信公众号中配置的Token")
hashlist = [token, timestamp, nonce]
hashlist.sort()
print("[token, timestamp, nonce]: ", hashlist)
hashstr = ''.join([s for s in hashlist]).encode('utf-8')
print('hashstr before sha1: ', hashstr)
hashstr = hashlib.sha1(hashstr).hexdigest()
print('hashstr sha1: ', hashstr)
if hashstr == signature:
return HttpResponse(echostr)
else:
return HttpResponse("weixin index")
elif request.method == "POST":
# autoreply方法时用来回复消息的,此时可以先将此处的两行代码修改成return "success"
otherContent = autoreply(request)
return HttpResponse(otherContent)
else:
print("你的方法不正确....")
接下来在服务器端部署代码并启动代码:
git pull github master
source env/bin/activate
pip install -r requirements.txt
sudo python manage.py runserver 0.0.0.0:80
这会再在微信公众号开发配置页面,点击提交就可以配置成功了。
2. 解析发送文本消息
进行完微信服务器认证后,我们来实现“你说我学”,即用户发送文本消息给微信公众号,公众号模仿人发送消息返回给微信用户粉丝,不需要通过公众平台网页人为的操作。
2.1 解析接受的文本消息
微信接口的消息时以 XML 格式接受和传送的,所以首先进行接口消息的 XML 消息解析吧,具体的字段含义与用法请参考《官方文档》,此处就不再累述。官方文档参考
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File : receive.py
@Time : 2019/8/6 10:15
@Author : Crisimple
@Github : https://crisimple.github.io/
@Contact : Crisimple@foxmail.com
@License : (C)Copyright 2017-2019, Micro-Circle
@Desc : None
"""
import xml.etree.ElementTree as ET
def parse_xml(webData):
if len(webData) == 0:
return None
xmlData = ET.fromstring(webData)
msg_type = xmlData.find('MsgType').text
if msg_type == 'text'