序文
このブログでは、DjangoフレームワークをuWsgiおよびNginxと組み合わせ、Postman APIデバッグツールと組み合わせて、WeChatパブリックアカウントユーザーのメッセージの自動応答機能を実現し、TencentCloudサーバーに正常にデプロイしました。
では、前のブログで、私たちはテンセントクラウドサーバを設定して、簡単な対話を行うことができます。
1.WeChat公式アカウントを構成します
- 公式のWeChatパブリックアカウントプラットフォームにログインし、ページの一番下までスクロールして、[基本構成]をクリックします
- 右側の[構成の変更]をクリックして、対応する情報を入力します
URL: http://服务器公网IP/wx
Token: 自己设置一条字符串
EncodingAESKey: 随机生成就可
消息加解密方式: 为方便调试,暂时选择明文模式
2.情報のソースを確認します
上記の情報を入力した後、送信を選択するとGET
、トークンの検証要求がトリガーされます。検証の論理図は次のとおりです。
以下では、views.py
このロジックをプロジェクトディレクトリ内のファイルに実装します。コードは次のとおりです。
from django.http import HttpResponse
import hashlib
# Create your views here.
def TencentView(request):
if request.method == 'GET':
# 解析参数
data = request.GET
if len(data) == 0:
return HttpResponse(content="hello, this is WeChat view")
signature = data.get(key='signature', default='')
timestamp = data.get(key='timestamp', default='')
nonce = data.get(key='nonce', default='')
echostr = data.get(key='echostr', default='')
# 请按照公众平台官网\基本配置中信息填写
token = "xxxxxxxxxxxxxxxxxx"
list_para = [token, timestamp, nonce]
list_para.sort()
list_str = ''.join(list_para).encode('utf-8')
sha1 = hashlib.sha1()
sha1.update(list_str)
# map(sha1.update, list_para)
# 加密
hashcode = sha1.hexdigest()
print("/GET func: hashcode: {0}, signature: {1}".format(hashcode, signature))
if hashcode == signature:
return HttpResponse(content=echostr)
else:
return HttpResponse(content='验证失败')
elif request.method == 'POST':
pass
ここに落とし穴があります。公式の例はPython2で書かれていますが、Python2のhashlib暗号化はPython3の暗号化とは異なり
utf-8
ます。Python3を最初にエンコードする必要があります。
上記の設定が正しければ、再度送信すると検証に成功します。それでも失敗する場合は、暗号化の結果が間違っていないか確認してください。トークンの検証に成功すると、自動的に基本設定のメインページに戻り、スタートボタンをクリックします。
3.メッセージ受信-応答テスト
ファンは公式アカウントにテキストメッセージ「こんにちは」を送信します。開発者のバックエンドでは、公式プラットフォームからxml
次の情報を受け取ります。
<xml>
<ToUserName><![CDATA[公众号]]></ToUserName>
<FromUserName><![CDATA[粉丝号]]></FromUserName>
<CreateTime>1460537339</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[hello]]></Content>
<MsgId>6272960105994287618</MsgId>
</xml>
フィールドの説明は次のとおりです。
フィールド | 効果 |
---|---|
ToUserName |
公共 |
FromUserName |
ファン番号 |
CreateTime |
WeChatパブリックプラットフォームは、ファンがメッセージを送信した特定の時間を記録します |
MsgType |
メッセージの種類があるtext 、image 、voice など |
Content |
メッセージの内容 |
MsgId |
パブリックプラットフォームはメッセージを識別するタグ値を記録し、WeChatバックグラウンドシステムがそれを自動的に生成します |
公式アカウントは、コンテンツ「テスト」を含むテキストメッセージでファンに返信したいと考えています。その後、開発者が公式プラットフォームのバックエンドに送信するxml
コンテンツは次のとおりです。
<xml>
<ToUserName><![CDATA[粉丝号]]></ToUserName>
<FromUserName><![CDATA[公众号]]></FromUserName>
<CreateTime>1460541339</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[test]]></Content>
</xml>
サーバーが5秒以内に応答を処理することを保証できない場合は、「成功」または「」(空の文字列)で応答する必要があります。そうでない場合、WeChatのバックグラウンドで「公式アカウントは一時的に利用できません。しばらくしてからもう一度お試しください」というプロンプトが表示されます。
メッセージ受信応答フローチャートは次のとおりです。
views.py
次のコードを追加 して、プロジェクトディレクトリ内のファイルにこのプロセスを実装し続けましょう。
from xml.etree import ElementTree
import time
class ParseXmlMsg(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
if self.MsgType == 'text':
self.Content = xmlData.find('Content').text.encode('utf-8')
elif self.MsgType == 'image':
self.PicUrl = xmlData.find('PicUrl').text
self.MediaId = xmlData.find('MediaId').text
class TextMsg(object):
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)
class ImageMsg(object):
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)
また、elif
ステートメントに次のコードを追加する必要があります。
elif request.method == 'POST':
# 解析发送过来的body
webData = request.body
# print("Post webdata is ", webData)
xmlData = ElementTree.fromstring(webData)
recMsg = ParseXmlMsg(xmlData)
if recMsg.MsgType == 'text':
toUser = recMsg.FromUserName
fromUser = recMsg.ToUserName
content = 'test'
replyMsg = TextMsg(toUser, fromUser, content)
return HttpResponse(content=replyMsg.send())
elif recMsg.MsgType == 'image':
print('暂时不做处理')
return HttpResponse(content='success')
4.郵便配達員のデバッグ
デバッグの便宜のために、プロジェクトをローカルで開始し、Postmanxml
を介してメッセージを送受信し、デバッグ後にサーバーにアップロードすることができます。
- まず、プロジェクトをローカルで開始します
# 在启动之前,先注释掉settings.py文件中的一行代码,关闭CSRF验证
# 否则POST时会触发CSRF验证失败
# 'django.middleware.csrf.CsrfViewMiddleware'
python manage.py runserver
- Postmanを開き、
POST
リクエストを使用Body
して、xml
送信する必要のあるメッセージをメニューバーに入力します。具体的な構成情報を次の図に示します。
- 入力後、[
Send
送信]をクリックすると、下の応答情報列に返された情報が表示されます
送信されたメッセージは「hello」、受信されたメッセージは「test」で、問題がないことを示してから、コードをサーバーにアップロードします。
サーバー
uWsgi
をアップロードした後、再起動することを忘れないでくださいNginx
。
5.公式インターフェースのデバッグ
WeChatパブリックプラットフォームは、ファンとパブリックアカウント間の相互作用をシミュレートできるオンラインテストプラットフォームを提供します。
FromUserName
WeChat公式アカウントを構成すると、基本構成メニューバーに表示されます。
構成が正しい場合は、下の检查问题
ボタンをクリックしてください。何も起こらない場合は、次の情報が表示されます。
WeChatの公式アカウントにメッセージを送信すると、絵文字も次のtext
タイプのようです。
OK!非常に素晴らしい!!!