一. 背景
??話說很久以前開發了一次微信公眾號,那時用的是官方檔案推薦的框架 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
