微信企业号开发:自定义菜单

开发微信企业号可以通过程序自定义菜单,只需要调用相关的接口就可以实现。

其实这个菜单也就是微信底部的菜单,目前自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替。其实创建菜单也很简单。

但有一点需要说明,如果有子菜单,那么这个菜单就不会向后端发送事件。例如:我定义了三个一级菜单一个click,两个view。

如果没有子菜单,则点击click类型的菜单时,后主动向后端发送上报菜单事件,如果有则不会发送上报菜单事件。

如果没有子菜单,则点击view类型的菜单时,回主动向后端发送点击菜单跳转链接的事件。并且会打开对应的网页,如果有则不会发送点击菜单跳转链接的事件,也不会打开对应的网页。

也就是,如果有子菜单,则这个菜单,就是点击单纯的显示子菜单,不会有其他的动作了。

例如:

核心代码菜单相关:

public enum MenuTypeEnum
    {
        click = 1,
        view = 2,
        scancode_push = 3,
        scancode_waitmsg = 4,
        pic_sysphoto = 5,
        pic_photo_or_album = 6,
        pic_weixin = 7,
        location_select = 8

    };
   public abstract class SubButton
    {
        /// <summary>
        /// 菜单的响应动作类型,目前有click、view两种类型 scancode_push	扫码推事件scancode_waitmsg	扫码推事件且弹出“消息接收中”提示框
        /// </summary>
        public string type { get; protected set; }
        /// <summary>
        /// 菜单标题,不超过16个字节,子菜单不超过40个字节
        /// </summary>
        public string name { get; set; }
        public List<SubButton> sub_button { get; set; }
        public virtual bool  HasError()
        {
            if (string.IsNullOrEmpty(this.name))
            {
                LogInfo.Error("菜单名称为空");
                return true;
            }
            if (string.IsNullOrEmpty(this.type))
            {
                LogInfo.Error("菜单类型为空");
                return true;
            }
            if (sub_button!=null&&sub_button.Count > 0)
            {
                foreach (SubButton bt in sub_button)
                {
                    if (bt.HasError())
                    {
                        return true;
                    }
                }
            }
            return false;
        }
        public static SubButton CreateSubButton(MenuTypeEnum type,string name,string key,string url)
        {
            SubButton subButton = null;
            string menuTypeText = GetMenuTypeText(type);
            switch (type)
            {
                case MenuTypeEnum.view:
                    subButton = new SubViewButton(menuTypeText,name, url);
                    break;
                case MenuTypeEnum.click:
                case MenuTypeEnum.scancode_push:
                case MenuTypeEnum.scancode_waitmsg:
                case MenuTypeEnum.pic_sysphoto:
                case MenuTypeEnum.pic_photo_or_album:
                case MenuTypeEnum.pic_weixin:
                case MenuTypeEnum.location_select:
                    subButton = new SubClickButton(menuTypeText, name, key);
                    break;
                default:
                    throw new Exception("type=" + type + ",此类型的SubButton没有实现");

            }
            return subButton;
        }
        public static MenuTypeEnum GetMenuType(string type)
        {
            MenuTypeEnum text = MenuTypeEnum.click;
            switch (type)
            {
                case "click":
                    text = MenuTypeEnum.click;
                    break;
                case "view":
                    text = MenuTypeEnum.view ;
                    break;
                case "scancode_push":
                    text =MenuTypeEnum.scancode_push ;
                    break;
                case "scancode_waitmsg":
                    text = MenuTypeEnum.scancode_waitmsg ;
                    break;
                case  "pic_sysphoto" :
                    text = MenuTypeEnum.pic_sysphoto;
                    break;
                case "pic_photo_or_album":
                    text = MenuTypeEnum.pic_photo_or_album ;
                    break;
                case "pic_weixin":
                    text = MenuTypeEnum.pic_weixin ;
                    break;
                case "location_select":
                    text =MenuTypeEnum.location_select ;
                    break;
                default:
                    throw new Exception("type=" + type + ",此类型的MenuTypeEnum没有找到");

            }
            return text;
        }
        public static string GetMenuTypeText(MenuTypeEnum type)
        {
            string text = "";
            switch (type)
            {
                case MenuTypeEnum.click:
                    text = "click";
                    break;
                case MenuTypeEnum.view:
                    text = "view";
                    break;
                case MenuTypeEnum.scancode_push:
                    text = "scancode_push";
                    break;
                case MenuTypeEnum.scancode_waitmsg:
                    text = "scancode_waitmsg";
                    break;
                case MenuTypeEnum.pic_sysphoto:
                    text = "pic_sysphoto";
                    break;
                case MenuTypeEnum.pic_photo_or_album:
                    text = "pic_photo_or_album";
                    break;
                case MenuTypeEnum.pic_weixin:
                    text = "pic_weixin";
                    break;
                case MenuTypeEnum.location_select:
                    text = "location_select";
                    break;
                default:
                    throw new Exception("type=" + type + ",此类型的MenuTypeEnum没有实现");

            }
            return text;
        }
    }
   public class SubClickButton : SubButton
   {
       public SubClickButton(string type,string name,string key)
       {
           this.type = type;
           this.name = name;
           this.key = key;
       }
       /// <summary>
       /// 菜单KEY值,用于消息接口推送,不超过128字节
       /// </summary>
       public string key { get; set; }
       public override bool HasError()
       {
           if (string.IsNullOrEmpty(this.key))
           {
               LogInfo.Error("菜单key为空");
               return true;
           }
           return base.HasError();
       }
   }
   public class SubViewButton : SubButton
   {
       public SubViewButton(string type, string name, string url)
       {
           this.type = type;
           this.name = name;
           this.url = url;
       }
       /// <summary>
       /// 成员点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的网页URL,可与网页授权获取成员基本信息接口结合,获得成员基本信息。
       /// </summary>
       public string url { get; set; }
       public override bool HasError()
       {
           if (string.IsNullOrEmpty(this.url))
           {
               LogInfo.Error("菜单url为空");
               return true;
           }
           return base.HasError();
       }
   }

 /// <summary>
    /// 自定义菜单
    /// </summary>
   public class Menu
    {
       public List<SubButton> button { get; set; }
       public virtual bool HasError()
       {
           if (button.Count >= 4)
           {
               LogInfo.Error("最多包括3个一级菜单");
               return true;
           }
           foreach(SubButton bt in button)
           {
               if (bt.HasError())
               {
                   return true;
               }
           }
           return false;
       }
    }

添加修改,删除菜单

public class BLLMenu
    {

       /// <summary>
       ///
       /// </summary>
       /// <param name="info"></param>
        /// <param name="agentid">企业应用的id,整型。可在应用的设置页面查看</param>
       /// <returns></returns>
        public static bool Create(Menu info, int agentid)
        {
            if (info.HasError())
            {
                return false;
            }
            string urlFormat = "https://qyapi.weixin.qq.com/cgi-bin/menu/create?access_token={0}&agentid={1}";
            var url = string.Format(urlFormat, BLLAccessToken.GetAccessToken(), agentid);
            WebUtils wut = new WebUtils();
            var postData = Tools.ToJsonString<Menu>(info);
            //数据不用加密发送
            LogInfo.Info("创建应用菜单消息: " + postData);
            string sendResult = wut.DoPost(url, postData);
            ReturnResult tempAccessTokenjson = Tools.JsonStringToObj<ReturnResult>(sendResult);
            if (tempAccessTokenjson.HasError())
            {
                LogInfo.Error("发送创建应用菜单返回错误: " + Tools.ToJsonString<ReturnResult>(tempAccessTokenjson));
                return false;
            }

            return true;
        }
       /// <summary>
       ///
       /// </summary>
        /// <param name="agentid">企业应用的id,整型。可在应用的设置页面查看</param>
       /// <returns></returns>
        public static bool DelAll(int agentid)
        {
            string urlFormat = "https://qyapi.weixin.qq.com/cgi-bin/menu/delete?access_token={0}&agentid={1}";
            var url = string.Format(urlFormat, BLLAccessToken.GetAccessToken(), agentid);
            WebUtils wut = new WebUtils();

            //数据不用加密发送
            LogInfo.Info("发送删除菜单消息: " + url);
            string sendResult = wut.DoGet(url);
            ReturnResult tempAccessTokenjson = Tools.JsonStringToObj<ReturnResult>(sendResult);
            if (tempAccessTokenjson.HasError())
            {
                LogInfo.Error("发送删除菜单返回错误: " + Tools.ToJsonString<ReturnResult>(tempAccessTokenjson));
                return false;
            }

            return true;
        }
        public static bool GetAll(int agentid)
        {
            string urlFormat = "https://qyapi.weixin.qq.com/cgi-bin/menu/get?access_token={0}&agentid={1}";
            var url = string.Format(urlFormat, BLLAccessToken.GetAccessToken(), agentid);
            WebUtils wut = new WebUtils();

            //数据不用加密发送
            LogInfo.Info("发送获取菜单列表消息: " + url);
            string sendResult = wut.DoGet(url);
            MenuListResult tempAccessTokenjson = Tools.JsonStringToObj<MenuListResult>(sendResult);
            if (tempAccessTokenjson.HasError())
            {
                LogInfo.Error("发送获取菜单列表返回错误: " + Tools.ToJsonString<MenuListResult>(tempAccessTokenjson));
                return false;
            }

            return true;
        }
    }

测试代码

 private void button7_Click(object sender, EventArgs e)
        {
		///测试添加
            ConmonWeixin.MenuInfo.Menu info = new ConmonWeixin.MenuInfo.Menu();
            SubButton subbt1 = SubButton.CreateSubButton(MenuTypeEnum.click, "Click1", "Click1", "");
            subbt1.sub_button = new List<SubButton>();
            SubButton bt11 = SubButton.CreateSubButton(MenuTypeEnum.scancode_push, "codePush2", "CancodePushButton11", "");
            SubButton bt12 = SubButton.CreateSubButton(MenuTypeEnum.scancode_waitmsg, "codeWaitmsg2", "CancodeWaitmsgButton12", "");
            SubButton bt13 = SubButton.CreateSubButton(MenuTypeEnum.click, "Click12", "Click12", "");
            SubButton bt14 = SubButton.CreateSubButton(MenuTypeEnum.view, "V2级", "V22", "https://www.baidu.com");
            subbt1.sub_button.Add(bt11);
            subbt1.sub_button.Add(bt12);
            subbt1.sub_button.Add(bt13);
            subbt1.sub_button.Add(bt14);
            SubButton subbt2 = SubButton.CreateSubButton(MenuTypeEnum.view, "V1级", "", "www.baidu.com");
            subbt2.sub_button = new List<SubButton>();
            SubButton bt21 = SubButton.CreateSubButton(MenuTypeEnum.pic_sysphoto, "PicSysphoto", "PicSysphotoButton21", "");

            SubButton bt22 = SubButton.CreateSubButton(MenuTypeEnum.pic_photo_or_album, "photoalbum2", "PicSysphotoButton22", "");
            subbt2.sub_button.Add(bt21);
            subbt2.sub_button.Add(bt22);

            SubButton subbt3 = SubButton.CreateSubButton(MenuTypeEnum.view, "V1级", "", "http://hlogin.html");
            subbt3.sub_button = new List<SubButton>();
            SubButton bt31 = SubButton.CreateSubButton(MenuTypeEnum.pic_weixin, "pic_weixin2", "Subpic_weixinButton31", "");

            SubButton bt32 = SubButton.CreateSubButton(MenuTypeEnum.location_select, "location_selec", "location_selec32", "");
            subbt3.sub_button.Add(bt31);
            subbt3.sub_button.Add(bt32);

            info.button = new List<SubButton>();
            info.button.Add(subbt1);
            info.button.Add(subbt2);
            info.button.Add(subbt3);
            BLLMenu.Create(info,7);
          //  Menu info, int agentid
        }

        private void button8_Click(object sender, EventArgs e)
        {
		//测试删除
            BLLMenu.DelAll(7);
        }

创建应用菜单官方文档

菜单接收事件官方文档

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 07-20

微信企业号开发:自定义菜单的相关文章

微信公众平台自定义菜单开发——创建菜单

自己从不会到最后做出来,所以好东西必须分享,所以我就给大家写一下过程 1.首先必须是成为微信的开发者,这样才有AppId 和AppSecret 2步就是获取access_token 在你的浏览器上输入https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET (注意连接中得appid=APPID&secret=APPSECRET 分别是你自己在微信

微信公众号自定义菜单创建

微信公众号自定义菜单的创建步骤 1.找到AppId和AppSecret.自定义菜单申请成功后,在"高级功能"-"开发模式"-"接口配置信息"的最后两项就是: 2.根据AppId和AppSecret,以https get方式获取访问特殊接口所必须的凭证access_token: 3.根据access_token,将json格式的菜单数据通过https post方式提交. 接口调用请求说明 http请求方式:POST(请使用https协议) http

微信企业号开发之 企业号人员身份认证与开发

前言 这里完全可以链接一个登录页面,让用户输入用户名密码进行登录的...2333 但是,这样所就完全失去了微信企业号的意义,本来进入微信企业号的时候,就已经对人员身份进行认证了,你这里再让别人登录,不是显得多余么? 于是,需要考虑的是,如何获取微信企业号中用户的身份,以及将用户身份与自有系统进行关联. 一.建立企业应用并配置可信域名 在微信的管理界面里面,建立一个企业应用.建立的过程很简单,但是这里需要注意的是,建立完以后,一定要配置可信域名!!!!并且如果你不是使用的标准端口,一定也要把端口配

.net之微信企业号开发(二) 企业号人员身份认证与开发

前言 这里完全可以链接一个登录页面,让用户输入用户名密码进行登录的...2333 但是,这样所就完全失去了微信企业号的意义,本来进入微信企业号的时候,就已经对人员身份进行认证了,你这里再让别人登录,不是显得多余么? 于是,需要考虑的是,如何获取微信企业号中用户的身份,以及将用户身份与自有系统进行关联. 一.建立企业应用并配置可信域名 在微信的管理界面里面,建立一个企业应用.建立的过程很简单,但是这里需要注意的是,建立完以后,一定要配置可信域名!!!!并且如果你不是使用的标准端口,一定也要把端口配

[转载]微信企业号开发如何建立连接

连接将使你的企业号更具价值,你可以使用以下三种方式,连接你的企业号及企业应用: 1.企业应用调用企业号提供的接口,管理或查询企业号后台所管理的资源.或给成员发送消息等,以下称主动调用模式. 2.企业号把用户发送的消息或用户触发的事件推送给企业应用,由企业应用处理,以下称回调模式. 3.用户在微信中阅读企业应用下发的H5页面,该页面可以调用微信提供的原生接口,使用微信开放的终端能力,以下称JSAPI模式. 通过这三种连接方式的结合,你可以在企业号中建立功能强大的移动轻应用,并依托微信数亿活跃用户,

微信公众平台自定义菜单及高级接口PHP SDK

本文介绍介绍微信公众平台自定义菜单及高级接口的PHP SDK及使用方法. 作者 方倍工作室 修正记录: 2014.05.03 v1.0 方倍工作室 http://www.cnblogs.com/txw1958/ SDK 源码: 1 /* 2 方倍工作室 http://www.cnblogs.com/txw1958/ 3 CopyRight 2014 www.doucube.com All Rights Reserved 4 */ 5 6 class class_weixin_adv 7 { 8

.net之微信企业号开发(一) 所使用的环境与工具以及准备工作

前言 一直以来,从事的是.net winform的编程,虽然对移动互联这块很感兴趣,但是由于现有的工作和移动互联之间隔的太远,也就没有时间和精力好好的去研究和实现.今年年初辞职了,刚好朋友那里希望建立一套新的网点销售管理系统,将原有的PC中的一些东西,移植到手机终端来.于是我接受了这个任务,除了给他们搭建新系统外,也慢慢的接触到了移动互联应用,开始了我的移动互联征程. 由于WEB应用本身的局限性,同时自身也不具备多个平台开发APP的精力和实力.我选择了微信的企业号开发.对于微信这样一个普及很广的

微信企业号开发之回调模式的接口开发

一.前言 微信企业号应用中,有两种模式,一种是普通模式,这种模式只能进行简单网页链接,以及发送固定的消息.为了可以让企业号的用户更好的与应用交互,微信提供了回调模式,这种回调模式的可以将用户发送给微信的信息,转发到用户提供的一个回调接口上,该接口解析用户发送过来的信息,解析后进行相应,而且回调模式中,可以调用的东西不少,扫码,图片,视频,地理位置信息等. 在应用的模式下,选择回调模式,之后,需要设置3个参数(1.回调接口URL:2.token:3.ASESKey),URL就是提供的回调接口,微信

Force.com微信企业号开发系列(一) - 启用二次验证

微信于9月份推出企业号后引起了业界不小的反响,许多企业都在思索企业号将如何影响企业的运营,从本文开始,我将详细阐述微信企业号开发的相关知识,而本文将着重介绍如何实现更高安全机制的二次验证. 申请企业体验号: 企业号顾名思义就是企业来申请的号,申请时就像申请服务号一样,需要提供各种组织证明文件,对广大开发者来说很难操作,好在腾讯公司也像服务号一样开通了体验号申请,留意企业体验号的有效期间非常短,只有90天(服务号测试账号有1年有效期),且如果企业体验号长期不使用还会收到腾讯公司的提前失效提醒邮件.