Django 开发微信公众号

一. 背景

  话说很久以前开发了一次微信公众号,那时用的是官方文档推荐的框架 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)认证成功后,就可以继续其他业务服务开发了。

GitHub代码参考commits id:a7cf530

# 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'
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值