DjangoはWeChat公式アカウントをドッキングして自動メッセージ返信を実現します

序文

  このブログでは、DjangoフレームワークをuWsgiおよびNginxと組み合わせ、Postman APIデバッグツールと組み合わせて、WeChatパブリックアカウントユーザーのメッセージの自動応答機能を実現し、TencentCloudサーバーに正常にデプロイしました。

  では、前のブログで、私たちはテンセントクラウドサーバを設定して、簡単な対話を行うことができます。

1.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 メッセージの種類があるtextimagevoiceなど
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!非常に素晴らしい!

ここに写真の説明を挿入

おすすめ

転載: blog.csdn.net/qq_42730750/article/details/112366788