登录微信公众平台的管理界面,点击左边的菜单中的“自定义菜单”,可以进行自定义菜单的基本配置。
如果已启用服务器配置的话,就不能在公众平台管理界面进行自定义菜单,而需要调用微信提供的接口进行自定义菜单的开发。
开启和停止服务器配置在左边菜单中的开发→基本配置中可以找到。如果停止,用户可以自定义菜单,且向客户端推送消息,但不能接收客户端的请求。如果启用,必须由开发者调用API接口对自定义菜单进行开发,可以向客户端推送消息,也可以接收客户端的请求,对请求进行处理并相应(即被动回复消息)。
自定义菜单的API是微信提供的高级接口,必须经过微信认证才可以调用。个人订阅号无法进行微信认证,只有企业/组织订阅号才可以进行微信认证。微信认证需每年向腾讯缴纳300元费用。
自定义菜单实质上是一个JSON字符串,如下所示
{ "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" }] }] }
其中的type指的是按钮的类型,有多种类型的按钮,此例中为click和view。更多类型按钮的说明请查看开发文档。
接口调用使用POST方式,https协议:
https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
ACCESS_TOKEN获取方法如下:
1、在基本配置中查看开发者ID(AppID)和开发者密码(AppSecret)。其中AppSecret具有极高的安全性,需要使用管理员账号(而非第三方授权用户)登录,点击重置后可看到AppSecret。
2、得到AppID和AppSecret后,还需要设置白名单,即可以获取ACCESS_TOKEN值的IP地址,本机IP以微信提供的网站http://ip.qq.com/为准。
3、点击开发→开发者工具,接口类型选择基础支持,接口列表选择获取access_token接口/token。输入刚才获取到的appid和secret。
4、点击“检查问题”,可以得到access_token的值,expires_in是过期时间
得到ACCESS_TOKEN后,访问以下网址创建自定义菜单:
5、ACCESS_TOKEN存在有效期,expire_in为7200秒即2个小时,如果超过2小时将失效。因此如果想实现在网页上点击按钮生成自定义菜单,应该通过代码获取ACCESS_TOKEN。
首先定义全局变量AppID和AppSecret
const string appid = "xxxxxxxxxxxxxxxxxx"; const string secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
获取代码如下:
/// <summary> /// 获取access_token /// </summary> /// <param name="grant_type">填写client_credential</param> /// <param name="appid">第三方用户唯一凭证</param> /// <param name="secret">第三方用户唯一凭证密钥,即appsecret</param> /// <returns>access_token</returns> public string GetAccessToken(string grant_type,string appid , string secret) { string access_token = string.Empty; //接口格式:协议为https,请求方式为GET,需指定3个参数grant_type,appid和secret string tokenUrl = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type={0}&appid={1}&secret={2}", grant_type, appid, secret); WebClient wc = new WebClient(); string download_string = wc.DownloadString(tokenUrl); //获取以上接口url调用的结果字符串,即包含access_token的JSON数据 //注意:由于.net 2.0不支持使用JavaScriptSerializer类反序列化,只能使用Newtonsoft.Json进行反序列化 object obj = JsonConvert.DeserializeObject(download_string); //使用Newtonsoft.Json反序列化JSON数据 /* 正确时的返回JSON数据包如下: { "access_token": "access_token的值", "expires_in": 7200 } 错误时返回的JSON数据包如下: { "errcode":错误代码, "errmsg":"错误信息" } */ Newtonsoft.Json.Linq.JObject js = obj as Newtonsoft.Json.Linq.JObject; //获得JObject //Newtonsoft.Json.Linq.JToken jt; //根据键获取值 if (js["access_token"] != null) access_token = js["access_token"].ToString(); //如果正确返回,获取access_token else access_token = js["errcode"].ToString() + ":" + js["errmsg"].ToString() ; //如果发生错误,获取错误代码及错误消息 /* 返回码说明: -1:系统繁忙,此时请开发者稍候再试 0:请求成功 40001:AppSecret错误或者AppSecret不属于这个公众号,请开发者确认AppSecret的正确性 40002:请确保grant_type字段值为client_credential 40164:调用接口的IP地址不在白名单中,请在接口IP白名单中进行设置 */ return access_token; }
调用代码:
GetAccessToken("client_credential", appid, secret);