7 自定义菜单
自定义菜单意义作用请参考创建接口 介绍。
目标:三个菜单栏,体验click、view、media_id 三种类型的菜单按钮,其他类型在本小节学习之后,自行请查询公众平台wiki说明领悟。
7.1 创建菜单界面
1)根据公众平台wiki 给的json 数据编写代码,其中涉及media_id部分请阅读”永久素材”章节。
vim menu.py
# -*- coding: utf-8 -*-
# filename: menu.py
import urllib
from basic import Basic
class Menu(object):
def __init__(self):
pass
def create(self, postData, accessToken):
postUrl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=%s" % accessToken
if isinstance(postData, unicode):
postData = postData.encode('utf-8')
urlResp = urllib.urlopen(url=postUrl, data=postData)
print urlResp.read()
def query(self, accessToken):
postUrl = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=%s" % accessToken
urlResp = urllib.urlopen(url=postUrl)
print urlResp.read()
def delete(self, accessToken):
postUrl = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=%s" % accessToken
urlResp = urllib.urlopen(url=postUrl)
print urlResp.read()
#获取自定义菜单配置接口
def get_current_selfmenu_info(self, accessToken):
postUrl = "https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token=%s" % accessToken
urlResp = urllib.urlopen(url=postUrl)
print urlResp.read()
if __name__ == '__main__':
myMenu = Menu()
postJson = """
{
"button":
[
{
"type": "click",
"name": "开发指引",
"key": "mpGuide"
},
{
"name": "公众平台",
"sub_button":
[
{
"type": "view",
"name": "更新公告",
"url": "http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1418702138&token=&lang=zh_CN"
},
{
"type": "view",
"name": "接口权限说明",
"url": "http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1418702138&token=&lang=zh_CN"
},
{
"type": "view",
"name": "返回码说明",
"url": "http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433747234&token=&lang=zh_CN"
}
]
},
{
"type": "media_id",
"name": "旅行",
"media_id": "z2zOokJvlzCXXNhSjF46gdx6rSghwX2xOD5GUV9nbX4"
}
]
}
"""
accessToken = Basic().get_access_token()
#myMenu.delete(accessToken)
myMenu.create(postJson, accessToken)
2)在腾讯云服务器上执行命令:python menu.py。
3)查看: 重新关注公众号后即可看到新创建菜单界面,题外话,如果不重新关注,公众号界面也会自动更改,但有时间延迟。
如下图所示,点击子菜单“更新公告“(view类型),弹出网页(pc版本)
7.2 完善菜单功能
查看公众平台自定义菜单与自定义菜单事件推送 后,可知:点击click类型button,微信后台会推送一个event类型的xml 给开发者。
显然,click类型的还需要开发者进一步完善后台代码逻辑,增加对自定义菜单事件推送的相应。
7.2.1 流程图
7.2.2 码代码
vim handle.py (修改)
# -*- coding: utf-8 -*-
# filename: handle.py
import reply
import receive
import web
class Handle(object):
def POST(self):
try:
webData = web.data()
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 = "test"
replyMsg = reply.TextMsg(toUser, fromUser, content)
return replyMsg.send()
if recMsg.MsgType == 'image':
mediaId = recMsg.MediaId
replyMsg = reply.ImageMsg(toUser, fromUser, mediaId)
return replyMsg.send()
if isinstance(recMsg, receive.EventMsg):
toUser = recMsg.FromUserName
fromUser = recMsg.ToUserName
if recMsg.Event == 'CLICK':
if recMsg.Eventkey == 'mpGuide':
content = u"编写中,尚未完成".encode('utf-8')
replyMsg = reply.TextMsg(toUser, fromUser, content)
return replyMsg.send()
print "暂且不处理"
return reply.Msg().send()
except Exception, Argment:
return Argment
2)vim receive.py (修改)
# -*- coding: utf-8 -*-
# filename: receive.py
import xml.etree.ElementTree as ET
def parse_xml(web_data):
if len(web_data) == 0:
return None
xmlData = ET.fromstring(web_data)
msg_type = xmlData.find('MsgType').text
if msg_type == 'event':
event_type = xmlData.find('Event').text
if event_type == 'CLICK':
return Click(xmlData)
#elif event_type in ('subscribe', 'unsubscribe'):
#return Subscribe(xmlData)
#elif event_type == 'VIEW':
#return View(xmlData)
#elif event_type == 'LOCATION':
#return LocationEvent(xmlData)
#elif event_type == 'SCAN':
#return Scan(xmlData)
elif msg_type == 'text':
return TextMsg(xmlData)
elif msg_type == 'image':
return ImageMsg(xmlData)
class EventMsg(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.Event = xmlData.find('Event').text
class Click(EventMsg):
def __init__(self, xmlData):
EventMsg.__init__(self, xmlData)
self.Eventkey = xmlData.find('EventKey').text
7.3 体验
编译好代码后,重新启动服务,(sudo python main.py 80),view类型、media_id类型的本身就很容易实现,现在重点看一下click类型的菜单按钮。
微信扫码成为公众号的粉丝,点击菜单按钮“开发指引”。
查看后台日志,发现接收到一条xml,如截图:
参考资料
https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Getting_Started_Guide.html