.Net6+Furion+Sqlsugar+SenparcSdk开发微信公众号系列之八:自定义菜单

一、创建接口

1.1、注意事项

  1. 自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。
  2. 一级菜单最多4个汉字,二级菜单最多8个汉字,多出来的部分将会以“...”代替。
  3. 创建自定义菜单后,菜单的刷新策略是,在用户进入公众号会话页或公众号 profile 页时,如果发现上一次拉取菜单的请求在5分钟以前,就会拉取一下菜单,如果菜单有更新,就会刷新客户端的菜单。测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果。​

1.2、按钮类型

  1. click:点击推事件用户点击 click 类型按钮后,微信服务器会通过消息接口推送消息类型为 event 的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的 key 值,开发者可以通过自定义的 key 值与用户进行交互;
  2. view:跳转 URL 用户点击 view 类型按钮后,微信客户端将会打开开发者在按钮中填写的网页URL,可与网页授权获取用户基本信息接口结合,获得用户基本信息。
  3. scancode_push:扫码推事件用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后显示扫描结果(如果是URL,将进入URL),且会将扫码的结果传给开发者,开发者可以下发消息。
  4. scancode_waitmsg:扫码推事件且弹出“消息接收中”提示框用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后,将扫码的结果传给开发者,同时收起扫一扫工具,然后弹出“消息接收中”提示框,随后可能会收到开发者下发的消息。
  5. pic_sysphoto:弹出系统拍照发图用户点击按钮后,微信客户端将调起系统相机,完成拍照操作后,会将拍摄的相片发送给开发者,并推送事件给开发者,同时收起系统相机,随后可能会收到开发者下发的消息。
  6. pic_photo_or_album:弹出拍照或者相册发图用户点击按钮后,微信客户端将弹出选择器供用户选择“拍照”或者“从手机相册选择”。用户选择后即走其他两种流程。
  7. pic_weixin:弹出微信相册发图器用户点击按钮后,微信客户端将调起微信相册,完成选择操作后,将选择的相片发送给开发者的服务器,并推送事件给开发者,同时收起相册,随后可能会收到开发者下发的消息。
  8. location_select:弹出地理位置选择器用户点击按钮后,微信客户端将调起地理位置选择工具,完成选择操作后,将选择的地理位置发送给开发者的服务器,同时收起位置选择工具,随后可能会收到开发者下发的消息。
  9. media_id:下发消息(除文本消息)用户点击media_id类型按钮后,微信服务器会将开发者填写的永久素材 id 对应的素材下发给用户,永久素材类型可以是图片、音频、视频 、图文消息。请注意:永久素材 id 必须是在“素材管理/新增永久素材”接口上传后获得的合法id。
  10. view_limited:跳转图文消息 URL 用户点击view_limited类型按钮后,微信客户端将打开开发者在按钮中填写的永久素材 id 对应的图文消息URL,永久素材类型只支持图文消息。请注意:永久素材 id 必须是在“素材管理/新增永久素材”接口上传后获得的合法id。
  11. article_id:用户点击 article_id 类型按钮后,微信客户端将会以卡片形式,下发开发者在按钮中填写的图文消息
  12. article_view_limited:类似 view_limited,但不使用 media_id 而使用 article_id

注意: 草稿接口灰度完成后,将不再支持图文信息类型的 media_id 和 view_limited,有需要的,请使用 article_id 和 article_view_limited 代替

请注意,3到8的所有事件,仅支持微信iPhone5.4.1以上版本,和Android5.4以上版本的微信用户,旧版本微信用户点击后将没有回应,开发者也不能正常接收到事件推送。9~12,是专门给第三方平台旗下未微信认证(具体而言,是资质认证未通过)的订阅号准备的事件类型,它们是没有事件推送的,能力相对受限,其他类型的公众号不必使用。

1.3、使用测试账号

默认账号没有认证是不能新建自定义菜单的

可以使用平台测试账号调试接口

1.4、WebApi

Services文件夹下新建文件夹Menu和菜单服务MenuService.cs

新建创建菜单接口

namespace WeiXinApi.Application.Services
{
    public class MenuService : BaseService
    {

        /// <summary>
        /// 创建菜单
        /// </summary>
        /// <param name="resultFull"></param>
        /// <returns></returns>
        [HttpPost("/menu/add")]
        public dynamic CrateMenu(GetMenuResultFull resultFull)
        {
            try
            {
                var buttonGroup = CommonApi.GetMenuFromJsonResult(resultFull, new ButtonGroup()).menu;
                var result = CommonApi.CreateMenu(AppId, buttonGroup);
                if (result.errmsg == "ok")
                {
                    return "菜单更新成功";
                }
                else
                {
                    return result;
                }
            }
            catch (Exception ex)
            {

                throw Oops.Oh($"更新失败:{ex.Message}");
            }

        }

    }
}

使用apipost测试接口

测试数据

{
	"menu": {
		"button": [
			{
				"type": "click",
				"name": "今日歌曲",
				"key": "V1001_TODAY_MUSIC"
			},
			{
				"name": "菜单",
				"sub_button": [
					{
						"type": "view",
						"name": "搜索",
						"url": "http://www.baidu.com/"
					},
					{
						"type": "click",
						"name": "赞一下我们",
						"key": "V1001_GOOD"
					}
				]
			},
			{
				"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": []
					}
				]
			}
		]
	}
}

二、查询接口

2.1、说明

本接口将会提供公众号当前使用的自定义菜单的配置,如果公众号是通过 API 调用设置的菜单,则返回菜单的开发配置,而如果公众号是在公众平台官网通过网站功能发布菜单,则本接口返回运营者设置的菜单配置。

请注意:

  1. 第三方平台开发者可以通过本接口,在旗下公众号将业务授权给你后,立即通过本接口检测公众号的自定义菜单配置,并通过接口再次给公众号设置好自动回复规则,以提升公众号运营者的业务体验。
  2. 本接口与自定义菜单查询接口的不同之处在于,本接口无论公众号的接口是如何设置的,都能查询到接口,而自定义菜单查询接口则仅能查询到使用 API 设置的菜单配置。
  3. 认证/未认证的服务号/订阅号,以及接口测试号,均拥有该接口权限。
  4. 从第三方平台的公众号登录授权机制上来说,该接口从属于消息与菜单权限集。
  5. 本接口中返回的图片/语音/视频为临时素材(临时素材每次获取都不同,3天内有效,通过素材管理 - 获取临时素材接口来获取这些素材),本接口返回的图文消息为永久素材素材(通过素材管理 - 获取永久素材接口来获取这些素材)。

2.2、WebApi

新建接口

        /// <summary>
        /// 获取菜单
        /// </summary>
        /// <returns></returns>
        [HttpGet("/menu/list")]
        public dynamic GetMenu()
        {
            try
            {
                var result = CommonApi.GetMenu(AppId);
                if (result == null)
                {
                    throw Oops.Oh($"菜单不存在或验证失败");
                }
                else
                {
                    //正常序列化只返回菜单Name,因为GetMenuResult里面button只有name字段,所以这里需要转换一下
                    var menu = JsonConvert.DeserializeObject<GetMenuResultFull>(result.ToJson());
                    return menu;
                }
            }
            catch (Exception ex)
            {
                throw Oops.Oh($"菜单不存在或验证失败:{ex.Message}");

            }
        }

测试接口

三、删除接口

3.1、说明

使用接口创建自定义菜单后,开发者还可使用接口删除当前使用的自定义菜单。另请注意,在个性化菜单时,调用此接口会删除默认菜单及全部个性化菜单。

3.2、WebApi

        /// <summary>
        /// 删除菜单
        /// </summary>
        /// <returns></returns>
        [HttpGet("/menu/delete")]
        public dynamic Delete()
        {
            try
            {
                var result = CommonApi.DeleteMenu(AppId);
                if (result.errmsg == "ok")
                {
                    return "删除菜单成功";
                }
                else
                {
                    return result.errmsg;
                }
            }
            catch (Exception ex)
            {
                throw Oops.Oh($"删除菜单失败:{ex.Message}");

            }

        }

请求测试

可以看到公众号也就没有菜单了

四、事件推送

详情请看事件推送章节

五、个性化菜单

5.1、说明

为了帮助公众号实现灵活的业务运营,微信公众平台新增了个性化菜单接口,开发者可以通过该接口,让公众号的不同用户群体看到不一样的自定义菜单。该接口开放给已认证订阅号和已认证服务号。

开发者可以通过以下条件来设置用户看到的菜单:

  1. 用户标签(开发者的业务需求可以借助用户标签来完成)
  2. 性别
  3. 手机操作系统
  4. 地区(用户在微信客户端设置的地区)
  5. 语言(用户在微信客户端设置的语言)

注意:为保护个人隐私,公众号个性化菜单将不再支持对性别、地区、语言这类涉及个人隐私数据的信息进行筛选的功能,具体调整如下:

  1. 创建时,只要匹配条件中包含隐私信息的,将被拒绝,并返回错误码 65320;
  2. 已经创建的,如包含隐私信息的则自动失效,不包含的则正常匹配;
  3. 开发者仍然可以正常通过测试接口,获取到粉丝看到的菜单;
  4. 查询个性化菜单时,所有规则正常显示。

个性化菜单接口说明:

  1. 个性化菜单要求用户的微信客户端版本在iPhone6.2.2,Android 6.2.4以上,暂时不支持其他版本微信
  2. 菜单的刷新策略是,在用户进入公众号会话页或公众号 profile 页时,如果发现上一次拉取菜单的请求在5分钟以前,就会拉取一下菜单,如果菜单有更新,就会刷新客户端的菜单。测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果
  3. 普通公众号的个性化菜单的新增接口每日限制次数为2000次,删除接口也是2000次,测试个性化菜单匹配结果接口为20000次
  4. 出于安全考虑,一个公众号的所有个性化菜单,最多只能设置为跳转到3个域名下的链接
  5. 创建个性化菜单之前必须先创建默认菜单(默认菜单是指使用普通自定义菜单创建接口创建的菜单)。如果删除默认菜单,个性化菜单也会全部删除
  6. 个性化菜单接口支持用户标签,请开发者注意,当用户身上的标签超过1个时,以最后打上的标签为匹配

个性化菜单匹配规则说明:

个性化菜单的更新是会被覆盖的。 例如公众号先后发布了默认菜单,个性化菜单1,个性化菜单2,个性化菜单3。那么当用户进入公众号页面时,将从个性化菜单3开始匹配,如果个性化菜单3匹配成功,则直接返回个性化菜单3,否则继续尝试匹配个性化菜单2,直到成功匹配到一个菜单。 根据上述匹配规则,为了避免菜单生效时间的混淆,决定不予提供个性化菜单编辑API,开发者需要更新菜单时,需将完整配置重新发布一轮。 

5.2、创建个性化菜单

新增AddPersonalInput.cs类,用来接收前端传过来的值

实体类内容

namespace WeiXinApi.Application.Services
{
    public class AddPersonalInput
    {
        /// <summary>
        /// 菜单
        /// </summary>
        public GetMenuResultFull ResultFull { get; set; }

        /// <summary>
        /// 规则
        /// </summary>
        public MenuMatchRule MenuMatchRule { get; set; }
    }
}

MenuService.cs新增接口

        /// <summary>
        /// 创建个性化菜单
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("/menu/addpersonal")]
        public dynamic CratePersonalMenu(AddPersonalInput input)
        {
            try
            {
                WxJsonResult result = null;
                var buttonGroup = CommonApi.GetMenuFromJsonResult(input.ResultFull, new ConditionalButtonGroup()).menu;

                var addConditionalButtonGroup = buttonGroup as ConditionalButtonGroup;
                addConditionalButtonGroup.matchrule = input.MenuMatchRule;
                result = CommonApi.CreateMenuConditional(AppId, addConditionalButtonGroup);
                var message = $"menuid:{(result as CreateMenuConditionalResult).menuid}";
                if (result.errcode == 0)
                {
                    return "菜单更新成功:" + message;
                }
                else
                {
                    return result;
                }
            }
            catch (Exception ex)
            {

                throw Oops.Oh($"更新失败:{ex.Message}");
            }

        }

启动项目测试接口,成功添加

手机上测试看看效果

电脑上的微信还是原来的菜单

5.3、测试个性化菜单匹配结果

MenuService新建接口

        /// <summary>
        /// 测试个性化菜单匹配结果
        /// </summary>
        /// <param name="user_id"></param>
        /// <returns></returns>
        [HttpPost("/menu/test")]
        public dynamic PersonalMenuTest(string user_id)
        {
            var result = CommonApi.TryMatch(AppId, user_id);
            return result;
        }

测试一下,这里没有返回菜单,可能是因为传的userid,我没有根据用户的个性化设置,所以返回的是空的,不过这功能无关紧要,没必要纠结。

六、本章Gitee地址链接

https://gitee.com/huguodong520/weixinapi/tree/%E8%87%AA%E5%AE%9A%E4%B9%89%E8%8F%9C%E5%8D%95/

 

posted @ 2022-06-01 11:38  HuTiger  阅读(417)  评论(0编辑  收藏  举报