1. 微信公众号开发原来如此简单呐!

微信公众号「雪之梦技术驿站」


致读者: 点击上方 “雪之梦技术驿站” → 点击右上角“ ... ”→ 点选“设为星标★ ” 加上星标,就不会找不到我啦!

偷偷溜进文章的小广告,别害羞,点进去瞅瞅,说不定能发现什么宝藏呢!

文末那个也别错过,说不定是通往秘密花园的钥匙哦!

1.1. 引言

前一阵子突然想到小而美的取关需求,决定了开发微信公众号,但是结果却卡在了自定义菜单权限上,于是乎有种鸡肋的感觉.

最后,抱着一丝丝侥幸的心理申请了个人兴趣认证,万一不一定非得是微信认证呢?

个人兴趣认证描述示例

在等待的日子里,那就继续研究一下微信公众号开发的自定义菜单吧!

1.2. 快速上手

俗话说: "磨刀不误砍柴工",先找打趁手的工具,往往能达到事半功倍的效果!

如果是Java开发微信公众号,这里强烈推荐WxJava项目,真的很省心!

WxJava - 微信开发 Java SDK 码云Gitee Github GitHub release Maven Central Build Status 使用IntelliJ IDEA开发维护 License

微信Java开发工具包,支持包括微信支付、开放平台、公众号、企业微信、视频号、小程序等微信功能模块的后端开发。

1.3. 公众平台测试账号

打开微信公众号后台,在设置与开发 --> 开发者工具 里面有个公众平台测试账号栏目,进入申请测试公众号,这里的权限真的大!

无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。

微信扫一扫进入公众平台测试平台

填写接口配置信息

测试账号的权限真的是应有尽有,是个学习技术的好地方!

1.3.1. 自动回复

自动回复的权限默认已获得,上次内容也已经详细解释了有关内容,这里不再赘述.

关键词回复
收到消息回复
被关注回复

值得强调的是,粉丝可以在和公众号的对话里,发送各种各样的消息,包括文字,图片,视频,定位等等.

然而,实际开发过程中大可不必对全部类型的消息进行处理,只需要关注想要关注的消息即可.

接收普通消息

文本消息

<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>1348831860</CreateTime>
  <MsgType><![CDATA[text]]></MsgType>
  <Content><![CDATA[this is a test]]></Content>
  <MsgId>1234567890123456</MsgId>
  <MsgDataId>xxxx</MsgDataId>
  <Idx>xxxx</Idx>
</xml>

图片消息

<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>1348831860</CreateTime>
  <MsgType><![CDATA[image]]></MsgType>
  <PicUrl><![CDATA[this is a url]]></PicUrl>
  <MediaId><![CDATA[media_id]]></MediaId>
  <MsgId>1234567890123456</MsgId>
   <MsgDataId>xxxx</MsgDataId>
  <Idx>xxxx</Idx>
</xml>

语音消息

<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>1357290913</CreateTime>
  <MsgType><![CDATA[voice]]></MsgType>
  <MediaId><![CDATA[media_id]]></MediaId>
  <Format><![CDATA[Format]]></Format>
  <MsgId>1234567890123456</MsgId>
  <MsgDataId>xxxx</MsgDataId>
  <Idx>xxxx</Idx>
  <MediaId16K><![CDATA[media_id_16k]]></MediaId16K>
</xml>

视频消息

<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>1357290913</CreateTime>
  <MsgType><![CDATA[video]]></MsgType>
  <MediaId><![CDATA[media_id]]></MediaId>
  <ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>
  <MsgId>1234567890123456</MsgId>
   <MsgDataId>xxxx</MsgDataId>
  <Idx>xxxx</Idx>
</xml>

小视频消息

<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>1357290913</CreateTime>
  <MsgType><![CDATA[shortvideo]]></MsgType>
  <MediaId><![CDATA[media_id]]></MediaId>
  <ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>
  <MsgId>1234567890123456</MsgId>
   <MsgDataId>xxxx</MsgDataId>
  <Idx>xxxx</Idx>
</xml>

地理位置消息

<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>1351776360</CreateTime>
  <MsgType><![CDATA[location]]></MsgType>
  <Location_X>23.134521</Location_X>
  <Location_Y>113.358803</Location_Y>
  <Scale>20</Scale>
  <Label><![CDATA[位置信息]]></Label>
  <MsgId>1234567890123456</MsgId>
   <MsgDataId>xxxx</MsgDataId>
  <Idx>xxxx</Idx>
</xml>

链接消息

<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>1351776360</CreateTime>
  <MsgType><![CDATA[link]]></MsgType>
  <Title><![CDATA[公众平台官网链接]]></Title>
  <Description><![CDATA[公众平台官网链接]]></Description>
  <Url><![CDATA[url]]></Url>
  <MsgId>1234567890123456</MsgId>
   <MsgDataId>xxxx</MsgDataId>
  <Idx>xxxx</Idx>
</xml>

以上消息既可以来自粉丝发送给微信公众号的对话,也可以来自微信公众号发布图文推送文章等.

1.3.2. 自定义菜单

自定义菜单

自定义菜单能够帮助公众号丰富界面,让用户更好更快地理解公众号的功能。开启自定义菜单后,公众号界面如图所示:

  1. 自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。

  2. 一级菜单最多4个汉字,二级菜单最多8个汉字,多出来的部分将会以“...”代替。

  3. 创建自定义菜单后,菜单的刷新策略是,在用户进入公众号会话页或公众号profile页时,如果发现上一次拉取菜单的请求在5分钟以前,就会拉取一下菜单,如果菜单有更新,就会刷新客户端的菜单。测试时可以以尝试取消关注公众账号后再次关注,则可以看到创建后的效果。

click和view的请求示例

按照官方文档配置click点击按钮和view跳转链接,示例如下:

{
    "button": [
        {
            "type": "click",
            "name": "今日歌曲",
            "key": "V1001_TODAY_MUSIC"
        },
        {
            "name": "菜单",
            "sub_button": [
                {
                    "type": "view",
                    "name": "搜索",
                    "url": "http://www.soso.com/"
                },
                {
                    "type": "miniprogram",
                    "name": "wxa",
                    "url": "http://mp.weixin.qq.com",
                    "appid": "wx286b93c14bbf93aa",
                    "pagepath": "pages/lunar/index"
                },
                {
                    "type": "click",
                    "name": "赞一下我们",
                    "key": "V1001_GOOD"
                }
            ]
        }
    ]
}

恭喜你,踩坑成功,因为配置的第二个子菜单miniprogram没有权限.

【错误信息】:错误代码:45064, 错误信息:no permission to use weapp in menu rid: 66b18514-565169e1-5b36d3f2,微信原始报文:{"errcode":45064,"errmsg":"no permission to use weapp in menu rid: 66b18514-565169e1-5b36d3f2"}

修改后的测试示例

所以,去掉第二个子菜单,重新配置即可.

click:点击推事件用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为event的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互;

view:跳转URL用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的网页URL,可与网页授权获取用户基本信息接口结合,获得用户基本信息。

{
    "button": [
        {
            "type": "click",
            "name": "今日歌曲",
            "key": "V1001_TODAY_MUSIC"
        },
        {
            "name": "菜单",
            "sub_button": [
                {
                    "type": "view",
                    "name": "搜索",
                    "url": "http://www.soso.com/"
                },
                {
                    "type": "click",
                    "name": "赞一下我们",
                    "key": "V1001_GOOD"
                }
            ]
        }
    ]
}

不知道你有没有注意到,view跳转菜单是支持外链跳转的,这一点比微信公众号后台要强!

click和view的消息推送

接收事件推送

  • 点击菜单click消息时的事件推送,XML数据包示例:
<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[FromUser]]></FromUserName>
  <CreateTime>123456789</CreateTime>
  <MsgType><![CDATA[event]]></MsgType>
  <Event><![CDATA[CLICK]]></Event>
  <EventKey><![CDATA[EVENTKEY]]></EventKey>
</xml>
  • 点击菜单view跳转链接时的事件推送,XML数据包示例:
<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[FromUser]]></FromUserName>
  <CreateTime>123456789</CreateTime>
  <MsgType><![CDATA[event]]></MsgType>
  <Event><![CDATA[VIEW]]></Event>
  <EventKey><![CDATA[www.qq.com]]></EventKey>
</xml>

其他新增按钮类型的请求示例

{
    "button": [
        {
            "name": "扫码",
            "sub_button": [
                {
                    "type": "scancode_waitmsg",
                    "name": "扫码带提示",
                    "key": "rselfmenu_0_0",
                    "sub_button": []
                },
                {
                    "type": "scancode_push",
                    "name": "扫码推事件",
                    "key": "rselfmenu_0_1",
                    "sub_button": []
                }
            ]
        },
        {
            "name": "发图",
            "sub_button": [
                {
                    "type": "pic_sysphoto",
                    "name": "系统拍照发图",
                    "key": "rselfmenu_1_0",
                    "sub_button": []
                },
                {
                    "type": "pic_photo_or_album",
                    "name": "拍照或者相册发图",
                    "key": "rselfmenu_1_1",
                    "sub_button": []
                },
                {
                    "type": "pic_weixin",
                    "name": "微信相册发图",
                    "key": "rselfmenu_1_2",
                    "sub_button": []
                }
            ]
        },
        {
            "name": "发送位置",
            "type": "location_select",
            "key": "rselfmenu_2_0"
        },
        {
            "type": "media_id",
            "name": "图片",
            "media_id": "MEDIA_ID1"
        },
        {
            "type": "view_limited",
            "name": "图文消息",
            "media_id": "MEDIA_ID2"
        },
        {
            "type": "article_id",
            "name": "发布后的图文消息",
            "article_id": "ARTICLE_ID1"
        },
        {
            "type": "article_view_limited",
            "name": "发布后的图文消息",
            "article_id": "ARTICLE_ID2"
        }
    ]
}

估计是文档过时了,示例代码都不能直接运行,不过这个报错很明显是按钮数量不合法.

【错误信息】:错误代码:40016, 错误信息:不合法的按钮个数,微信原始报文:{"errcode":40016,"errmsg":"invalid button size rid: 66b185d2-4ad3d18c-4281747d"}

改正后的测试示例

{
    "button": [
        {
            "name": "扫码",
            "sub_button": [
                {
                    "type": "scancode_waitmsg",
                    "name": "扫码带提示",
                    "key": "rselfmenu_0_0",
                    "sub_button": []
                },
                {
                    "type": "scancode_push",
                    "name": "扫码推事件",
                    "key": "rselfmenu_0_1",
                    "sub_button": []
                }
            ]
        },
        {
            "name": "发图",
            "sub_button": [
                {
                    "type": "pic_sysphoto",
                    "name": "系统拍照发图",
                    "key": "rselfmenu_1_0",
                    "sub_button": []
                },
                {
                    "type": "pic_photo_or_album",
                    "name": "拍照或者相册发图",
                    "key": "rselfmenu_1_1",
                    "sub_button": []
                },
                {
                    "type": "pic_weixin",
                    "name": "微信相册发图",
                    "key": "rselfmenu_1_2",
                    "sub_button": []
                }
            ]
        },
        {
            "name": "发送位置",
            "type": "location_select",
            "key": "rselfmenu_2_0"
        }
    ]
}

scancode_waitmsg:扫码推事件且弹出“消息接收中”提示框用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后,将扫码的结果传给开发者,同时收起扫一扫工具,然后弹出“消息接收中”提示框,随后可能会收到开发者下发的消息。

{
    "ScanCodeInfo": {
        "ScanType": "qrcode",
        "ScanResult": "http://weixin.qq.com/r/test"
    },
    "CreateTime": "1722913369",
    "EventKey": "rselfmenu_0_0",
    "Event": "scancode_waitmsg",
    "ToUserName": "gh_test",
    "FromUserName": "oygXc6HxeAfd4yjjm1-test",
    "MsgType": "event"
}

scancode_push:扫码推事件用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后显示扫描结果(如果是URL,将进入URL),且会将扫码的结果传给开发者,开发者可以下发消息。

{
    "ScanCodeInfo": {
        "ScanType": "qrcode",
        "ScanResult": "http://weixin.qq.com/r/test"
    },
    "CreateTime": "1722914371",
    "EventKey": "rselfmenu_0_1",
    "Event": "scancode_push",
    "ToUserName": "gh_test",
    "FromUserName": "oygXc6HxeAfd4yjjm1-test",
    "MsgType": "event"
}

scancode_waitmsgscancode_push 类型的区别有两点:

  1. scancode_waitmsg 扫码后会触发自动回复消息而 scancode_push 不会等待消息系统消息回复

  2. scancode_waitmsg扫码结果不会自动触发,同样的二维码scancode_push可以直接执行扫码结果,例如跳转到另外的公众号!

pic_sysphoto:弹出系统拍照发图用户点击按钮后,微信客户端将调起系统相机,完成拍照操作后,会将拍摄的相片发送给开发者,并推送事件给开发者,同时收起系统相机,随后可能会收到开发者下发的消息。

经测试: 没有收到消息,无反应

pic_photo_or_album:弹出拍照或者相册发图用户点击按钮后,微信客户端将弹出选择器供用户选择“拍照”或者“从手机相册选择”。用户选择后即走其他两种流程。

{
    "CreateTime": "1722915726",
    "EventKey": "rselfmenu_test",
    "Event": "pic_photo_or_album",
    "ToUserName": "gh_test",
    "FromUserName": "oygXc6HxeAfd4yjjm1-test",
    "MsgType": "event",
    "SendPicsInfo": {
        "Count": "1",
        "PicList": {
            "item": [
                {
                    "PicMd5Sum": [
                        "7790eb06e33cf5a4eae080cd5ae29e03"
                    ]
                }
            ]
        }
    }
}

经测试: 拍照没有收到消息,无反应.但是选择相册是可以正常接收到信息反馈.

pic_weixin:弹出微信相册发图器用户点击按钮后,微信客户端将调起微信相册,完成选择操作后,将选择的相片发送给开发者的服务器,并推送事件给开发者,同时收起相册,随后可能会收到开发者下发的消息。

{
    "CreateTime": "1722915993",
    "EventKey": "rselfmenu_test",
    "Event": "pic_weixin",
    "ToUserName": "gh_test",
    "FromUserName": "oygXc6HxeAfd4yjjm1-test",
    "MsgType": "event",
    "SendPicsInfo": {
        "Count": "1",
        "PicList": {
            "item": [
                {
                    "PicMd5Sum": [
                        "5726bb58dd3407500a7b88e61cd180ca"
                    ]
                }
            ]
        }
    }
}

location_select:弹出地理位置选择器用户点击按钮后,微信客户端将调起地理位置选择工具,完成选择操作后,将选择的地理位置发送给开发者的服务器,同时收起位置选择工具,随后可能会收到开发者下发的消息。

{
    "CreateTime": "1722916673",
    "EventKey": "rselfmenu_rest",
    "SendLocationInfo": {
        "Poiname": "测试",
        "Location_X": "10",
        "Location_Y": "110",
        "Label": "测试",
        "Scale": "15"
    },
    "Event": "location_select",
    "ToUserName": "gh_test",
    "FromUserName": "oygXc6HxeAfd4yjjm1-test",
    "MsgType": "event"
}

1.4. 常见错误

【错误信息】:错误代码:45064, 错误信息:no permission to use weapp in menu rid: 66b18514-565169e1-5b36d3f2,微信原始报文:{"errcode":45064,"errmsg":"no permission to use weapp in menu rid: 66b18514-565169e1-5b36d3f2"}

测试公众号没有相关资源的权限

【错误信息】:错误代码:40155, 错误信息:请勿添加其他公众号的主页链接,微信原始报文:{"errcode":40155,"errmsg":"please don't contain other home page url rid: 66b18a05-60f7a4f3-6ce08531"}

测试公众号没有其他公众号的主页链接权限

【错误信息】:错误代码:40020, 错误信息:不合法的按钮 URL 长度,微信原始报文:{"errcode":40020,"errmsg":"invalid button url size rid: 66b18b45-12114fbc-59938cb2"}

可能是配置错误,检测clickurl之类的是否搭配错误!

【错误信息】:错误代码:40007, 错误信息:不合法的媒体文件 id,微信原始报文:{"errcode":40007,"errmsg":"invalid media_id rid: 66b190e0-38d2f7c9-71f2c233"}

微信认证后才能有临时素材的管理权限,永久素材管理权限要求先上传再获取.

【错误信息】:错误代码:48001, 错误信息:api 功能未授权,请确认公众号已获得该接口,可以在公众平台官网 - 开发者中心页中查看接口权限,微信原始报文:{"errcode":48001,"errmsg":"api unauthorized rid: 66b225ed-4bdd1a42-115feb8d"}

测试公众号部分权限不足

【错误信息】:错误代码:40164, 错误信息:invalid ip 183.155.242.143 ipv6 ::ffff:183.155.242.143, not in whitelist rid: 66b2251b-59e5467f-4220f10e,微信原始报文:{"errcode":40164,"errmsg":"invalid ip 183.155.242.143 ipv6 ::ffff:183.155.242.143, not in whitelist rid: 66b2251b-59e5467f-4220f10e"}

测试服务器没有被添加到服务器白名单,解决方法是将外网白名单添加进去即可!

1.5. 总结

本文主要以申请了测试公众号再测试平台上测试了自定义菜单功能,并详细讲解了自定义菜单的类型.

其中,最常用的是click点击按钮和view跳转链接以及其他图文素材相关菜单.

{
    "button": [
        {
            "name": "点击和跳转",
            "sub_button": [
                {
                    "type": "click",
                    "name": "点我试试",
                    "key": "V1001_GOOD"
                },
                {
                    "type": "view",
                    "name": "搜索看看",
                    "url": "http://www.soso.com/"
                }
            ]
        },
        {
            "name": "图文素材",
            "sub_button": [
                {
                    "type": "media_id",
                    "name": "图片",
                    "media_id": "MEDIA_ID1"
                },
                {
                    "type": "view_limited",
                    "name": "图文消息",
                    "media_id": "MEDIA_ID2"
                },
                {
                    "type": "article_id",
                    "name": "发布后的图文消息",
                    "article_id": "ARTICLE_ID1"
                },
                {
                    "type": "article_view_limited",
                    "name": "发布后的图文消息",
                    "article_id": "ARTICLE_ID2"
                }
            ]
        }
    ]
}

其中图文素材类可能需要获取素材id或者是已发布的图文消息.

在测试公众号中,很多高级权限是无限制开放的,这为测试接口能力提供了极大的方便,但实际上不可过度依赖,因为某些权限并没有!

嘿,小伙伴们,你们知道吗?这字儿可不是白码的,每一颗键帽下的汗水都能浇出一朵花来!所以,要是看得开心,就请大方地撒点阳光——评论点赞转发走一波,让我这花园更加灿烂!

1.6. 往期精彩文章

1.7. 欢迎扫码关注

微信公众号「雪之梦技术驿站」

欢迎扫码关注,私信回复『加群』一起交流技术

最后更新时间: 2024-11-07 15:30:30
作者: 雪之梦技术驿站
来源: 雪之梦技术驿站
本文原创发布于「雪之梦技术驿站」,转载请注明出处,谢谢合作!

/snowdreams1006-wechat-open.png

results matching ""

    No results matching ""