訂閱號服務開發03-被動消息應答

@python

前言

在進行微信公衆號服務開發,最重要的文檔就是官方的技術文檔,開發以前多閱讀幾遍!web

[info]微信公衆平臺技術文檔:https://mp.weixin.qq.com/wikidjango

何爲被動消息應答?

用戶在微信公衆號中輸入內容或點擊菜單後,開發者服務再根據接收到的消息進行應答,這種類型即是被動消息應答。服務器

被動消息類型

先上一段代碼,用於開發者服務端接收被動消息,打印出消息的類型。
views.py微信

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from wechatpy import parse_message
from wechatpy.exceptions import InvalidSignatureException
from wechatpy.utils import check_signature

@csrf_exempt
def wechat(request):
    # GET 方式用於微信公衆平臺綁定驗證
    if request.method == 'GET':
        signature = request.GET.get('signature', "")
        timestamp = request.GET.get('timestamp', "")
        nonce = request.GET.get('nonce', "")
        echo_str = request.GET.get('echostr', "")
        token = 'MiltonGuan'
        try:
            check_signature(token, signature, timestamp, nonce)
            print("微信簽名驗證經過!")
        except InvalidSignatureException:
            print("微信簽名驗證失敗!")
            echo_str = '微信簽名驗證失敗'
        return HttpResponse(echo_str)
    # POST 方式用於接受被動消息
    if request.method == 'POST':
        # wechatpy 提供了一個便捷的函數 parse_message 來處理由微信服務器發送過來的 XML 消息並解析生成對應的消息類:
        msg = parse_message(request.body)
        print("開發者服務收到的消息:", msg)

與前面的例子相比,修改的代碼只有接收「POST」消息的這一塊app

# POST 方式用於接受被動消息
if request.method == 'POST':
    # wechatpy 提供了一個便捷的函數 parse_message 來處理由微信服務器發送過來的 XML 消息並解析生成對應的消息類:
    msg = parse_message(request.body)
    print("開發者服務收到的消息:", msg)

文本消息 MsgType=="text"

在公衆號中,輸入文本消息「測試文本消息」,則能夠在pycharm的控制檯中打印消息以下微信公衆平臺

開發者服務收到的消息: TextMessage(OrderedDict([('ToUserName', 'gh_dd3ad8e3fb33'), ('FromUserName', 'oiQF0tzMZ5Md5HaAlKvrZo9OIGBw'), ('CreateTime', '1557045409'), ('MsgType', 'text'), ('Content', '測試文本消息'), ('MsgId', '22291530543511304')]))

看過官方文檔便知,實際上微信服務器向開發者服務器發送過來的是xml格式的內容,如框架

<xml> 
 <ToUserName><![CDATA[gh_dd3ad8e3fb33]]></ToUserName>  
<FromUserName><![CDATA[oiQF0tzMZ5Md5HaAlKvrZo9OIGBw]]></FromUserName>  <CreateTime>1557045409</CreateTime> 
 <MsgType><![CDATA[text]]></MsgType>
  <Content><![CDATA[測試文本消息]]></Content> 
 <MsgId>22291530543511304</MsgId></xml>
參數 描述
ToUserName 開發者微信號
FromUserName 發送方賬號(一個OpenID)
CreateTime 消息建立時間 (整型)
MsgType 消息類型,文本爲text
Content 文本消息內容
MsgId 消息id,64位整型

上面例子這裏打印的內容,已經被wechatpy 提供的一個便捷的函數 parse_message 將微信服務器發送過來的 XML 消息解析生成了對應的消息類。ide

圖片消息 MsgType=="image"

在公衆號中,發送一張圖片,pycharm控制檯輸出以下

開發者服務收到的消息: ImageMessage(OrderedDict([('ToUserName', 'gh_dd3ad8e3fb33'), ('FromUserName', 'oiQF0tzMZ5Md5HaAlKvrZo9OIGBw'), ('CreateTime', '1557046675'), ('MsgType', 'image'), ('PicUrl', 'http://mmbiz.qpic.cn/mmbiz_jpg/1GvjsQCjdzN4FwdiaetpjPyibOIibL6rnnC4dicibbibGh4hv0wO7YK6Yu4Rj2Q7QsZYczIX0jZvyoGianwwVB41ouKNA/0'), ('MsgId', '22291549457593467'), ('MediaId', 'cUlcX98uOYHkyxLf7XJmOkSbliTj2Zcups6mCZlSUF6yq94H_IVX-WFLtxK_1dT9')]))

語音消息 MsgType=="voice"

在公衆號中,發送一段語音,pycharm控制檯輸出以下

開發者服務收到的消息: VoiceMessage(OrderedDict([('ToUserName', 'gh_dd3ad8e3fb33'), ('FromUserName', 'oiQF0tzMZ5Md5HaAlKvrZo9OIGBw'), ('CreateTime', '1557046793'), ('MsgType', 'voice'), ('MediaId', 'RQ70i8ItrXzDCAIj4sZoiWjQFBn4a3_i5JlMnzhuaCMkJKnP5vshdz6nlrWCbDNx'), ('Format', 'amr'), ('MsgId', '22291547468076299'), ('Recognition', None)]))

視頻消息 MsgType=="video"

在公衆號中,發送一段視頻,pycharm控制檯輸出以下

開發者服務收到的消息: VideoMessage(OrderedDict([('ToUserName', 'gh_dd3ad8e3fb33'), ('FromUserName', 'oiQF0tzMZ5Md5HaAlKvrZo9OIGBw'), ('CreateTime', '1557046883'), ('MsgType', 'video'), ('MediaId', 'Cpr-ieJ7HH3ZQz9WzbvaCCN14TmF2TonpRRdDXT-TVNIldI2pidNe3r6HNhwOXOP'), ('ThumbMediaId', '2uMNUEopAJ49MLzLxnpltZ8y2LOuRwrVQsufHIJaGqShmQY7K7fbpmyeNU7E-_rx'), ('MsgId', '22291553506594661')]))

地理位置消息 MsgType=="location"

在公衆號中,發送位置,pycharm控制檯輸出以下

開發者服務收到的消息: LocationMessage(OrderedDict([('ToUserName', 'gh_dd3ad8e3fb33'), ('FromUserName', 'oiQF0tzMZ5Md5HaAlKvrZo9OIGBw'), ('CreateTime', '1557046957'), ('MsgType', 'location'), ('Location_X', '23.117962'), ('Location_Y', '113.321632'), ('Scale', '16'), ('Label', '富力中心(天河區珠江新城華夏路10號)'), ('MsgId', '22291551235258971')]))

在公衆號中,發送收藏中的一個連接,pycharm控制檯輸出以下

開發者服務收到的消息: LinkMessage(OrderedDict([('ToUserName', 'gh_dd3ad8e3fb33'), ('FromUserName', 'oiQF0tzMZ5Md5HaAlKvrZo9OIGBw'), ('CreateTime', '1557047123'), ('MsgType', 'link'), ('Title', '官方網站-小鵬汽車'), ('Description', '小鵬汽車,致力於應用新的技術、工藝和商業模式,造年輕人喜好的智能化電動汽車'), ('Url', 'https://www.xiaopeng.com/m/videos.html'), ('MsgId', '22291558059713663')]))

事件消息 MsgType=="event"

在微信用戶和公衆號產生交互的過程當中,用戶的某些操做會使得微信服務器經過事件推送的形式通知到開發者在開發者中心處設置的服務器地址,從而開發者能夠獲取到該信息。其中,某些事件推送在發生後,是容許開發者回覆用戶的,某些則不容許

關注、取消事件 Event=="subscribe",Event=="unsubscribe"

最多見的場景是當咱們關注某個訂閱號時,會收到一條歡迎信息,如
在這裏插入圖片描述

開發者服務收到的消息: SubscribeEvent(OrderedDict([('ToUserName', 'gh_dd3ad8e3fb33'), ('FromUserName', 'oiQF0tzMZ5Md5HaAlKvrZo9OIGBw'), ('CreateTime', '1557123164'), ('MsgType', 'event'), ('Event', 'subscribe'), ('EventKey', None)]))
開發者服務收到的消息: UnsubscribeEvent(OrderedDict([('ToUserName', 'gh_dd3ad8e3fb33'), ('FromUserName', 'oiQF0tzMZ5Md5HaAlKvrZo9OIGBw'), ('CreateTime', '1557123120'), ('MsgType', 'event'), ('Event', 'unsubscribe'), ('EventKey', None)]))

更多事件(略)...

[info] 更多詳細信息,可參考官方文檔:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140453
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140454

被動消息應答類型

根據前面的各類被動消息類型,開發者服務器做出相應的應答,先直接上代碼以下
views.py

import os

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from wechatpy import parse_message
from wechatpy.client import WeChatClient
from wechatpy.exceptions import InvalidSignatureException
from wechatpy.utils import check_signature

app = {
    "appid": "wx3a07084cc1a11915",
    "appsecret": "8f9a6bb1f66b59aa705ecd9938a3874c"
}
wx = WeChatClient(app.get("appid"), app.get("appsecret"))


@csrf_exempt
def wechat(request):
    # GET 方式用於微信公衆平臺綁定驗證
    if request.method == 'GET':
        signature = request.GET.get('signature', "")
        timestamp = request.GET.get('timestamp', "")
        nonce = request.GET.get('nonce', "")
        echo_str = request.GET.get('echostr', "")
        token = 'MiltonGuan'
        try:
            check_signature(token, signature, timestamp, nonce)
            print("微信簽名驗證經過!")
        except InvalidSignatureException:
            print("微信簽名驗證失敗!")
            echo_str = '微信簽名驗證失敗'
        return HttpResponse(echo_str)
    # POST 方式用於接受被動消息
    if request.method == 'POST':
        # wechatpy 提供了一個便捷的函數 parse_message 來處理由微信服務器發送過來的 XML 消息並解析生成對應的消息類:
        msg = parse_message(request.body)
        print("開發者服務收到的消息:", msg)

        if msg.type == "text":
            # 回覆文本消息
            from wechatpy.replies import TextReply
            reply = TextReply(message=msg)
            reply.content = msg.content
            return HttpResponse(reply.render(), content_type="application/xml")

        if msg.type == "image":
            # 回覆圖片消息
            from wechatpy.replies import ImageReply
            reply = ImageReply(message=msg)
            reply.media_id = msg.media_id
            return HttpResponse(reply.render(), content_type="application/xml")

        if msg.type == "voice":
            # 回覆語音消息
            from wechatpy.replies import VoiceReply
            reply = VoiceReply(message=msg)
            reply.media_id = msg.media_id
            return HttpResponse(reply.render(), content_type="application/xml")

        if msg.type == "video":
            # 回覆視頻消息
            from wechatpy.replies import VideoReply
            reply = VideoReply(message=msg)
            reply.media_id = wx.media.upload("video", open(os.path.join(os.path.dirname(__file__), "hello.mp4"), "rb")).get("media_id")
            reply.title = "視頻標題..."
            reply.description = "視頻描述..."
            return HttpResponse(reply.render(), content_type="application/xml")

        if msg.type == "location":
            # 回覆音樂消息
            from wechatpy.replies import MusicReply
            reply = MusicReply(message=msg)
            reply.thumb_media_id = wx.media.upload("thumb", open(os.path.join(os.path.dirname(__file__), "music.jpg"), "rb")).get("thumb_media_id")
            reply.music_url = "https://od.qingting.fm/m4a/5a8e82757cb89146f20a287b_8762416_64.m4a"
            reply.hq_music_url = "https://od.qingting.fm/m4a/5a8e82757cb89146f20a287b_8762416_64.m4a"
            reply.title = "夢想明月曲"
            reply.description = "崔子格"
            return HttpResponse(reply.render(), content_type="application/xml")

        if msg.type == "link":
            # 回覆圖文消息
            from wechatpy.replies import ArticlesReply
            reply = ArticlesReply(message=msg)
            # 當用戶發送文本、圖片、視頻、圖文、地理位置這五種消息時,開發者只能回覆1條圖文消息
            reply.add_article(article={
                'title': '入門接口測試框架pytest',
                'description': '掌握python中的測試框架,首選pytest!',
                'url': 'https://mp.weixin.qq.com/s/4pLFQOdiB02DekTk-5RLbQ',
                'image': 'https://mmbiz.qpic.cn/mmbiz_png/0QhkJiaDuoKSmrTs3KpjQLMwn14WUFOCS9Tq7ZqvFOL653WuowZZMYNNnm8FRbicmk8C8v31HxC4YibFRfOkSsuqQ/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1',
            })
            return HttpResponse(reply.render(), content_type="application/xml")

        if msg.type == "event":
            if msg.event == "subscribe":
                # 訂閱歡迎消息
                from wechatpy.replies import TextReply
                reply = TextReply(message=msg)
                reply.content = "歡迎您的訂閱,一塊兒學習python!"
                return HttpResponse(reply.render(), content_type="application/xml")

回覆文本消息,關鍵代碼:

from wechatpy.replies import TextReply
reply = TextReply(message=msg)
reply.content = msg.content
return HttpResponse(reply.render(), content_type="application/xml")

在這裏插入圖片描述

回覆圖片消息,關鍵代碼:

from wechatpy.replies import ImageReply
reply = ImageReply(message=msg)
reply.media_id = msg.media_id
return HttpResponse(reply.render(), content_type="application/xml")

在這裏插入圖片描述

回覆語音消息,關鍵代碼:

from wechatpy.replies import VoiceReply
reply = VoiceReply(message=msg)
reply.media_id = msg.media_id
return HttpResponse(reply.render(), content_type="application/xml")

在這裏插入圖片描述

回覆視頻消息,關鍵代碼:

from wechatpy.replies import VideoReply
reply = VideoReply(message=msg)
reply.media_id = wx.media.upload("video", open(os.path.join(os.path.dirname(__file__), "hello.mp4"), "rb")).get("media_id")
reply.title = "視頻標題..."
reply.description = "視頻描述..."
return HttpResponse(reply.render(), content_type="application/xml")

在這裏插入圖片描述

回覆音樂消息,關鍵代碼:

from wechatpy.replies import MusicReply
reply = MusicReply(message=msg)
reply.thumb_media_id = wx.media.upload("thumb", open(os.path.join(os.path.dirname(__file__), "music.jpg"), "rb")).get("thumb_media_id")
reply.music_url = "https://od.qingting.fm/m4a/5a8e82757cb89146f20a287b_8762416_64.m4a"
reply.hq_music_url = "https://od.qingting.fm/m4a/5a8e82757cb89146f20a287b_8762416_64.m4a"
reply.title = "夢想明月曲"
reply.description = "崔子格"
return HttpResponse(reply.render(), content_type="application/xml")

在這裏插入圖片描述

回覆圖文消息,關鍵代碼:

from wechatpy.replies import ArticlesReply
reply = ArticlesReply(message=msg)
# 當用戶發送文本、圖片、視頻、圖文、地理位置這五種消息時,開發者只能回覆1條圖文消息
reply.add_article(article={
    'title': '入門接口測試框架pytest',
    'description': '掌握python中的測試框架,首選pytest!',
    'url': 'https://mp.weixin.qq.com/s/4pLFQOdiB02DekTk-5RLbQ',
    'image': 'https://mmbiz.qpic.cn/mmbiz_png/0QhkJiaDuoKSmrTs3KpjQLMwn14WUFOCS9Tq7ZqvFOL653WuowZZMYNNnm8FRbicmk8C8v31HxC4YibFRfOkSsuqQ/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1',
})
return HttpResponse(reply.render(), content_type="application/xml")

在這裏插入圖片描述


:-:
微信掃一掃,關注「python測試開發圈」,獲取更多測試開發分享!

相關文章
相關標籤/搜索