主頁 > 後端開發 > Django開發微信公眾號

Django開發微信公眾號

2020-10-01 20:35:30 後端開發

一. 背景

??話說很久以前開發了一次微信公眾號,那時用的是官方檔案推薦的框架 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 :   [email protected]
@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 = https://www.cnblogs.com/crisimple/p/ET.fromstring(webData)
    msg_type = xmlData.find('MsgType').text

    if msg_type == 'text':
        return TextMsg(xmlData)


class Msg(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


class TextMsg(Msg):
    def __init__(self, xmlData):
        Msg.__init__(self, xmlData)
        self.Content = xmlData.find('Content').text.encode('utf-8')

2.2 組裝被動回復的文本模板

??我們上面決議了接受到了粉絲發送過來的訊息了,決議完我們能拿到一些關鍵的資料欄位(ToUserName、FromUserName、CreateTime、MsgType、MsgId),接下來可以把這些欄位組裝成回復訊息的 XML 檔案模板,具體的欄位含義與用法請參考《官方檔案》,此處就不再累述,官方檔案參考

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File    :   reply.py
@Time    :   2019/8/6 10:15
@Author  :   Crisimple
@Github :    https://crisimple.github.io/
@Contact :   [email protected]
@License :   (C)Copyright 2017-2019, Micro-Circle
@Desc    :   回復訊息給關注微信公眾號的用戶
"""

import time

class Msg(object):
    def __init__(self):
        pass

    def send(self):
        return 'success'


class TextMsg(Msg):
    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 = """
        <xml>
        <ToUserName><![CDATA[{ToUserName}]]></ToUserName>
        <FromUserName><![CDATA[{FromUserName}]]></FromUserName>
        <CreateTime>{CreateTime}</CreateTime>
        <MsgType><![CDATA[text]]></MsgType>
        <Content><![CDATA[{Content}]]></Content>
        </xml>
        """
        return XmlForm.format(**self.__dict)

2.3 自動回復粉絲的文本訊息

??接收到訊息,如果判定訊息型別未文本訊息,條用autoreply方法決議 XML 檔案,組裝文本訊息模板,將文本訊息自動回復給粉絲,

    特別提醒:假如服務器無法保證在五秒內處理回復,則必須回復“success”或者“”(空串),否則微信后臺會發起三次重試,解釋一下為何有這么奇怪的規定,發起重試是微信后臺為了盡可以保證粉絲發送的內容開發者均可以收到,如果開發者不進行回復,微信后臺沒辦法確認開發者已收到訊息,只好重試,
# views.py

from django.shortcuts import HttpResponse
from django.views.decorators.csrf import csrf_exempt

import hashlib
from . import receive
from . import reply


# 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("Txy159wx")

        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":
        otherContent = autoreply(request)
        return HttpResponse(otherContent)
    else:
        print("你的方法不正確....")


def autoreply(request):
    try:
        webData = https://www.cnblogs.com/crisimple/p/request.body
        print("Handle POST webData is: ", webData)

        recMsg = receive.parse_xml(webData)
        if isinstance(recMsg, receive.Msg) and recMsg.MsgType == 'text':
            toUser = recMsg.FromUserName
            fromUser = recMsg.ToUserName
            content = recMsg.Content.decode('utf-8')
            replyMsg = reply.TextMsg(toUser, fromUser, content)
            return replyMsg.send()
        else:
            print("暫不處理")
            return "success"
    except Exception as e:
        print(e)

??GitHub代碼參考commits id:5f8581d
好的,下來就是在 Linux 服務器將該 Django 專案啟動起來,為了測驗我們發送的訊息是否能被接受發送,可以呼叫 微信公眾號文本介面網頁除錯工具,填寫引數參考截圖,成功呼叫介面回傳成功結果顯示如下圖右半部分,

文本訊息介面除錯
??同樣這時候給公眾號發送文本訊息可以得到自己想要回傳結果,好噠,到這個階段我們算是把微信公眾號開發的初步階段除錯OK了,接下來我們繼續進行更多服務的開發,
文本訊息實測結果

3. 決議發送圖片訊息

??我們來實作“圖尚往來”,即用戶發送圖片訊息給微信公眾號,公眾號被動發送相同的圖片訊息給微信用戶粉絲,不需要通過公眾平臺網頁人為的操作,

3.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 :   [email protected]
@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 = https://www.cnblogs.com/crisimple/p/ET.fromstring(webData)
    msg_type = xmlData.find('MsgType').text

    if msg_type == 'text':
        return TextMsg(xmlData)
    elif msg_type == 'image':
        return ImageMsg(xmlData)


class TextMsg(Msg):
    def __init__(self, xmlData):
        Msg.__init__(self, xmlData)
        self.Content = xmlData.find('Content').text.encode('utf-8')


class ImageMsg(Msg):
    def __init__(self, xmlData):
        Msg.__init__(self, xmlData)
        self.PicUrl = xmlData.find('PicUrl').text
        self.MediaId = xmlData.find('MediaId').text

3.2 組裝被動回復的圖片模板

??我們上面決議了接受到了粉絲發送過來的訊息了,決議完我們能拿到一些關鍵的資料欄位(ToUserName、FromUserName、CreateTime、MsgType、MsgId、MediaId),接下來可以把這些欄位組裝成回復訊息的 XML 檔案模板,具體的欄位含義與用法請參考《官方檔案》,此處就不再累述,官方檔案參考

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File    :   reply.py
@Time    :   2019/8/6 10:15
@Author  :   Crisimple
@Github :    https://crisimple.github.io/
@Contact :   [email protected]
@License :   (C)Copyright 2017-2019, Micro-Circle
@Desc    :   回復訊息給關注微信公眾號的用戶
"""

import time

class Msg(object):
    def __init__(self):
        pass

    def send(self):
        return 'success'


class ImageMsg(Msg):
    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 = """
        <xml>
        <ToUserName><![CDATA[{ToUserName}]]></ToUserName>
        <FromUserName><![CDATA[{FromUserName}]]></FromUserName>
        <CreateTime>{CreateTime}</CreateTime>
        <MsgType><![CDATA[image]]></MsgType>
        <Image>
        <MediaId><![CDATA[{MediaId}]]></MediaId>
        </Image>
        </xml>
        """
        return XmlForm.format(**self.__dict)

3.3 自動回復粉絲的圖片訊息

??接收到訊息,如果判定訊息型別為圖片訊息,條用autoreply方法決議 XML 檔案,組裝圖片訊息模板,將圖片訊息自動回復給粉絲,

    特別提醒:假如服務器無法保證在五秒內處理回復,則必須回復“success”或者“”(空串),否則微信后臺會發起三次重試,解釋一下為何有這么奇怪的規定,發起重試是微信后臺為了盡可以保證粉絲發送的內容開發者均可以收到,如果開發者不進行回復,微信后臺沒辦法確認開發者已收到訊息,只好重試,
# views.py
# ...

def autoreply(request):
    try:
        webData = https://www.cnblogs.com/crisimple/p/request.body
        print("Handle POST webData is: ", webData)

        recMsg = receive.parse_xml(webData)
        if isinstance(recMsg, receive.Msg):
            toUser = recMsg.FromUserName
            fromUser = recMsg.ToUserName
            if recMsg.MsgType == 'text':
                content = recMsg.Content.decode('utf-8')
                replyMsg = reply.TextMsg(toUser, fromUser, content)
                return replyMsg.send()
            if recMsg.MsgType == 'image':
                # Issues1: 'ImageMsg' object has no attribute 'MeidaId'
                # Issues2: 發送圖片回傳了:qCs1WNDj5p9-FULnsVoNoAIeKQUfLsamrfuXn-Goo32RwoDT8wkhh3QGNjZT0D5a
                # Issues3: 'str' object has no attribute 'decode'
                # Issues4: '該公眾號提供的服務出現故障,請稍后再試'
                mediaId = recMsg.MediaId
                replyMsg = reply.ImageMsg(toUser, fromUser, mediaId)
                return replyMsg.send()
            else:
                return reply.Msg().send()
        else:
            print("暫不處理")
            # return "success"
            return reply.Msg().send()
    except Exception as e:
        print(e)

??GitHub代碼參考commits id:2425cab
好的,下來就是在 Linux 服務器將該 Django 專案啟動起來,為了測驗我們發送的訊息是否能被接受發送,可以呼叫 微信公眾號文本介面網頁除錯工具,圖片資訊介面的除錯與文本訊息的除錯類似,以下是圖片除錯成功的實測效果截圖,

圖片訊息實測結果

4. 決議發送語音訊息

??我們來實作“鸚鵡學舌”,即用戶發送語音訊息給微信公眾號,公眾號被動發送相同的語音訊息給微信用戶粉絲,不需要通過公眾平臺網頁人為的操作,

4.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 :   [email protected]
@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 = https://www.cnblogs.com/crisimple/p/ET.fromstring(webData)
    msg_type = xmlData.find('MsgType').text

    if msg_type == 'text':
        return TextMsg(xmlData)
    elif msg_type == 'image':
        return ImageMsg(xmlData)
    elif msg_type == 'voice':
        return VoiceMsg(xmlData)


class Msg(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


class VoiceMsg(Msg):
    def __init__(self, xmlData):
        Msg.__init__(self, xmlData)
        self.MediaId = xmlData.find('MediaId').text
        self.Format = xmlData.find('Format').text

4.2 組裝被動回復的語音模板

??我們上面決議了接受到了粉絲發送過來的訊息了,決議完我們能拿到一些關鍵的資料欄位(ToUserName、FromUserName、CreateTime、MsgType、MsgId、Format、MediaId),接下來可以把這些欄位組裝成回復訊息的 XML 檔案模板,具體的欄位含義與用法請參考《官方檔案》,此處就不再累述,官方檔案參考

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File    :   reply.py
@Time    :   2019/8/6 10:15
@Author  :   Crisimple
@Github :    https://crisimple.github.io/
@Contact :   [email protected]
@License :   (C)Copyright 2017-2019, Micro-Circle
@Desc    :   回復訊息給關注微信公眾號的用戶
"""

import time

class Msg(object):
    def __init__(self):
        pass

    def send(self):
        return 'success'


class VoiceMsg(Msg):
    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 = """
        <xml>
        <ToUserName><![CDATA[{ToUserName}]]></ToUserName>
        <FromUserName><![CDATA[{FromUserName}]]></FromUserName>
        <CreateTime>{CreateTime}</CreateTime>
        <MsgType><![CDATA[voice]]></MsgType>
        <Voice>
        <MediaId><![CDATA[{MediaId}]]></MediaId>
        </Voice>
        </xml>
        """
        return XmlForm.format(**self.__dict)

4.3 自動回復粉絲的語音訊息

??接收到訊息,如果判定訊息型別為圖片訊息,條用autoreply方法決議 XML 檔案,組裝語音訊息模板,將語音訊息自動回復給粉絲,

    特別提醒:假如服務器無法保證在五秒內處理回復,則必須回復“success”或者“”(空串),否則微信后臺會發起三次重試,解釋一下為何有這么奇怪的規定,發起重試是微信后臺為了盡可以保證粉絲發送的內容開發者均可以收到,如果開發者不進行回復,微信后臺沒辦法確認開發者已收到訊息,只好重試,
# views.py
# ...

def autoreply(request):
    try:
        webData = https://www.cnblogs.com/crisimple/p/request.body
        print("Handle POST webData is: ", webData)

        recMsg = receive.parse_xml(webData)
        if isinstance(recMsg, receive.Msg):
            toUser = recMsg.FromUserName
            fromUser = recMsg.ToUserName
            if recMsg.MsgType == 'text':
                content = recMsg.Content.decode('utf-8')
                replyMsg = reply.TextMsg(toUser, fromUser, content)
                return replyMsg.send()
            if recMsg.MsgType == 'image':
                # Issues1: 'ImageMsg' object has no attribute 'MeidaId'
                # Issues2: 發送圖片回傳了:qCs1WNDj5p9-FULnsVoNoAIeKQUfLsamrfuXn-Goo32RwoDT8wkhh3QGNjZT0D5a
                # Issues3: 'str' object has no attribute 'decode'
                # Issues4: '該公眾號提供的服務出現故障,請稍后再試'
                mediaId = recMsg.MediaId
                replyMsg = reply.ImageMsg(toUser, fromUser, mediaId)
                return replyMsg.send()
            else:
                return reply.Msg().send()
        else:
            print("暫不處理")
            # return "success"
            return reply.Msg().send()
    except Exception as e:
        print(e)

??GitHub代碼參考commits id:d435471
好的,下來就是在 Linux 服務器將該 Django 專案啟動起來,為了測驗我們發送的訊息是否能被接受發送,可以呼叫 微信公眾號文本介面網頁除錯工具,語音資訊介面的除錯與文本訊息的除錯類似,以下是語音除錯成功的實測效果截圖,

語音訊息實測結果

5.決議發送視頻訊息

??我們來實作“鸚鵡學舌”,即用戶發送語音訊息給微信公眾號,公眾號被動發送相同的語音訊息給微信用戶粉絲,不需要通過公眾平臺網頁人為的操作,

5.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 :   [email protected]
@License :   (C)Copyright 2017-2019, Micro-Circle
@Desc    :   None
"""

5.2 組裝被動回復的視頻模板

??我們上面決議了接受到了粉絲發送過來的訊息了,決議完我們能拿到一些關鍵的資料欄位(ToUserName、FromUserName、CreateTime、MsgType、MsgId、ThumbMediaId、MediaId),接下來可以把這些欄位組裝成回復訊息的 XML 檔案模板,具體的欄位含義與用法請參考《官方檔案》,此處就不再累述,官方檔案參考

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File    :   reply.py
@Time    :   2019/8/6 10:15
@Author  :   Crisimple
@Github :    https://crisimple.github.io/
@Contact :   [email protected]
@License :   (C)Copyright 2017-2019, Micro-Circle
@Desc    :   回復訊息給關注微信公眾號的用戶
"""



5.3 自動回復粉絲的視頻訊息

??接收到訊息,如果判定訊息型別為圖片訊息,條用autoreply方法決議 XML 檔案,組裝視頻訊息模板,將視頻訊息自動回復給粉絲,

    特別提醒:假如服務器無法保證在五秒內處理回復,則必須回復“success”或者“”(空串),否則微信后臺會發起三次重試,解釋一下為何有這么奇怪的規定,發起重試是微信后臺為了盡可以保證粉絲發送的內容開發者均可以收到,如果開發者不進行回復,微信后臺沒辦法確認開發者已收到訊息,只好重試,
# views.py
# ...


??GitHub代碼參考commits id:
好的,下來就是在 Linux 服務器將該 Django 專案啟動起來,為了測驗我們發送的訊息是否能被接受發送,可以呼叫 微信公眾號文本介面網頁除錯工具,語音資訊介面的除錯與文本訊息的除錯類似,以下是語音除錯成功的實測效果截圖,

視頻訊息實測結果

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/146299.html

標籤:Python

上一篇:Delphi如何用ADOconnection+Ini動態連接SQL Server2000資料庫

下一篇:Opendialog1.Execute取值插入到MDB資料庫

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more