大佬教程收集整理的这篇文章主要介绍了微信公众平台开发教程(五)详解自定义菜单,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
如果只有输入框,可能太简单,感觉像命令行。自定义菜单,给我们提供了很大的灵活性,更符合用户的操作习惯。在一个小小的微信对话页面,可以实现更多的功能。菜单直观明了,不仅能提供事件响应,还支持URL跳转,如果需要的功能比较复杂,我们大可以使用URL跳转,跳转至我们的网页即可。
接着我们详细介绍,如何实现自定义菜单?
access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。正常情况下access_token有效期为7200秒,重复获取将导致上次获取的access_token失效。
公众号可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在开发模式中获得(需要已经成为开发者,且帐号没有异常状态)。注意调用所有微信接口时均需使用https协议。
http请求方式: GET
是否必须 | 说明 |
---|
正常情况下,微信会返回下述JSON数据包给公众号:
{"access_token":"ACCESS_TOKEN","expires_in":7200}
说明 |
---|
正常情况下,微信会返回下述JSON数据包给公众号:
说明 |
---|
错误时微信会返回错误码等信息,JSON数据包示例如下(该示例为AppID无效错误):
自定义菜单能够帮助公众号丰富界面,让用户更好更快地理解公众号的功能。开启自定义菜单后,公众号界面如图所示:
目前自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替。请注意,创建自定义菜单后,由于微信客户端缓存,需要24小时微信客户端才会展现出来。建议测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果。
用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为event的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互;
用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的url值(即网页链接),达到打开网页的目的,建议与网页授权获取用户基本信息接口结合,获得用户的登入个人信息。
请求示例
是否必须 | 说明 |
---|
正确时的返回JSON数据包如下:
错误时的返回JSON数据包如下(示例为无效菜单名长度):
使用接口创建自定义菜单后,开发者还可使用接口查询自定义菜单的结构。
用户点击自定义菜单后,如果菜单按钮设置为click类型,则微信会把此次点击事件推送给开发者,注意view类型(跳转到URL)的菜单点击不会上报。
推送XML数据包示例:
参数说明:
描述 |
---|
我们将在上一篇文章基础上,添加自定义菜单功能。
首先需要得到AppId和AppSecret
当你成为开发者后,自然能够在,开发者模式,便可看到这两个值,可以重置。
然后调用按照二.1中所示,进行操作。
注意:access_token有过期时间,如果过期,需要重新获取。
代码如下:
return mAccessToken;
}
}
///
///
///
/// <param name="appId">
/// <param name="appSecret">
///
private static string GetAccessToken(string appId,string appSecret)
{
string url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}",appId,appSecret);
String result = httpUtility.GetData(url);
XDocument doc = XmlUtility.ParseJson(result,"root");
XElement root = doc.Root;
if (root != null)
{
XElement access_token = root.Element("access_token");
if (access_token != null)
{
GetAccessToken_Time = datetiR_427_11845@e.Now;
if (root.Element("expires_in")!=null)
{
Expires_Period = int.Parse(root.Element("expires_in").value);
}
return access_token.Value;
}
else
{
GetAccessToken_Time = datetiR_427_11845@e.MinValue;
}
}
return null;
}
///
/// 判断Access_token是否过期
///
///
private static bool HasExpired()
{
if (GetAccessToken_Time != null)
{
//过期时间,允许有一定的误差,一分钟。获取时间消耗
if (datetiR_427_11845@e.Now > GetAccessToken_Time.AddSeconds(Expires_Period).AddSeconds(-60))
{
return true;
}
}
return false;
}
菜单需根据需要,按照实际要求进行设定。
这里我们提供天气查询功能,将常用的城市列出来,点击即可查询。
然后还提供了友情链接,这里提供了view类型的菜单,直接可以跳转至URL页面,为跳转做个好的演示。
具体菜单如下:
因为菜单的变更没有那么频繁,因此通过txt文件来设置菜单,并通过管理界面来管理菜单。
主要的管理功能:
1)从文件加载菜单
2)创建菜单。即将菜单通知微信服务端,并更新至微信客户端
3)查询菜单。获取当前系统的菜单。
4)删除菜单。从微信服务器删除菜单,也可以删除后再创建。
实现代码如下:
return httpUtility.GetData(url);
}
///
/// 创建菜单
///
public static void CreateMenu(String menu)
{
String url = String.Format("https://api.weixin.qq.com/cgi-bin/menu/create?access_token={0}",Context.AccessToken);
//String menu = FileUtility.Read(Menu_Data_Path);
httpUtility.Sendhttprequest(url,menu);
}
///
/// 删除菜单
///
public static void deleteMenu()
{
String url = String.Format("https://api.weixin.qq.com/cgi-bin/menu/delete?access_token={0}",Context.AccessToken);
httpUtility.GetData(url);
}
///
/// 加载菜单
///
///
public static String LoadMenu()
{
return FileUtility.Read(Menu_Data_Path);
}
}
上面的代码,其实我们对一些公共功能做了封装。如进行get请求、POST提交等操作,读取文件等。
这里我们提供进行get、Post提交的方法案例代码,如果使用,建议优化。
namespace Yank.WeiXin.Robot.Utility
{
///
/// http帮助类
///
class httpUtility
{
///
/// 发送请求
///
/// <param name="url">Url地址
/// <param name="data">数据
public static String Sendhttprequest(String url,String data)
{
return SendPosthttprequest(url,"application/x-www-form-urlencoded",data);
}
///
///
///
/// <param name="url">
///
public static String GetData(String url)
{
return SendGethttprequest(url,"application/x-www-form-urlencoded");
}
///
/// 发送请求
///
/// <param name="url">Url地址
/// <param name="method">方法(post或get)
/// <param name="method">数据类型
/// <param name="requestData">数据
public static String SendPosthttprequest(String url,String contentType,String requestData)
{
Webrequest request = (Webrequest)httpWebrequest.Create(url);
request.Method = "POST";
byte[] postBytes = null;
request.Contenttype = contentType;
postBytes = Encoding.UTF8.GetBytes(requestData);
request.ContentLength = postBytes.Length;
using (Stream outstream = request.GetrequestStream())
{
outstream.Write(postBytes,postBytes.Length);
}
String result = String.Empty;
using (WebResponse response = request.GetResponse())
{
if (response != null)
{
using (Stream stream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream,Encoding.UTF8))
{
result = reader.ReadToEnd();
}
}
}
}
return result;
}
///
/// 发送请求
///
/// <param name="url">Url地址
/// <param name="method">方法(post或get)
/// <param name="method">数据类型
/// <param name="requestData">数据
public static String SendGethttprequest(String url,String contentTypE)
{
Webrequest request = (Webrequest)httpWebrequest.Create(url);
request.Method = "GET";
request.Contenttype = contentType;
String result = String.Empty;
using (WebResponse response = request.GetResponse())
{
if (response != null)
{
using (Stream stream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream,Encoding.UTF8))
{
result = reader.ReadToEnd();
}
}
}
}
return result;
}
}
}
namespace Yank.WeiXin.Robot.Utility
{
class XmlUtility
{
///
///
///
/// <param name="json">
/// <param name="rootName">
///
public static XDocument ParseJson(String json,String rootName)
{
return JsonConvert.DeserializeXNode(json,rootName);
}
}
}
设置了菜单,这下需要处理事件了。跟我们之前设计ASPX或者WinForm一样,都要绑定按钮的事件。这里只是通过XML消息将请求传递过来。
通过“2、设置菜单"中具体的菜单内容,我们便已经知道需要进行哪些事件处理了。对于按钮类型为view的,无须处理,它会自动跳转至指定url.
需要处理的点击事件:
1)赞一下
2)查询某城市的天气,北京、上海、武汉
3)帮助
这个还要沿用上章中的事件处理器EventHandler来扩展处理。
具体的实现代码吧:
namespace Yank.WeiXin.Robot.Handlers
{
class EventHandler : IHandler
{
///
/// 请求的xml
///
private String requestXml { get; set; }
///
/// 构造函数
///
/// <param name="requestXml">
public EventHandler(String requestXml)
{
this.requestXml = requestXml;
}
///
/// 处理请求
///
///
public String Handlerequest()
{
String response = String.Empty;
Eventmessage em = Eventmessage.LoadFromXml(requestXml);
if (em != null)
{
switch (em.Event.ToLower())
{
case ("subscribe"):
response = SubscribeEventHandler(em);
break;
case "click":
response = ClickEventHandler(em);
break;
}
}
return response;
}
///
/// 关注
///
/// <param name="em">
///
private String SubscribeEventHandler(Eventmessage em)
{
//回复欢迎消息
Textmessage tm = new Textmessage();
tm.ToUserName = em.FromUserName;
tm.FromUserName = em.ToUserName;
tm.CreateTime = Common.GetNowTime();
tm.Content = "欢迎您关注***,我是大哥大,有事就问我,呵呵!\n\n";
return tm.GenerateContent();
}
///
/// 处理点击事件
///
/// <param name="em">
///
private String ClickEventHandler(Eventmessage em)
{
String result = String.Empty;
if (em != null && em.EventKey != null)
{
switch (em.EventKey.ToUpper())
{
case "BTN_GOOD":
result = btnGoodClick(em);
break;
case "BTN_TQ_BEIJING":
result = searchWeather("beijing",em);
break;
case "BTN_TQ_SHANGHAI":
result = searchWeather("shanghai",em);
break;
case "BTN_TQ_WUHAN":
result = searchWeather("wuhai",em);
break;
case "BTN_HelP":
result = btnHelpClick(em);
break;
}
}
return result;
}
///
/// 赞一下
///
/// <param name="em">
///
private String btnGoodClick(Eventmessage em)
{
//回复欢迎消息
Textmessage tm = new Textmessage();
tm.ToUserName = em.FromUserName;
tm.FromUserName = em.ToUserName;
tm.CreateTime = Common.GetNowTime();
tm.Content = @"谢谢您的支持!";
return tm.GenerateContent();
}
///
/// 帮助
///
/// <param name="em">
///
private String btnHelpClick(Eventmessage em)
{
//回复欢迎消息
Textmessage tm = new Textmessage();
tm.ToUserName = em.FromUserName;
tm.FromUserName = em.ToUserName;
tm.CreateTime = Common.GetNowTime();
tm.Content = @"查询天气,输入tq 城市名称\拼音\首字母";
return tm.GenerateContent();
}
///
/// 查询天气
///
/// <param name="cityName">
/// <param name="em">
///
private String searchWeather(String cityName,Eventmessage em)
{
Textmessage tm = new Textmessage();
tm.Content = WeatherHelper.GetWeather(cityName);
//进行发送者、接收者转换
tm.ToUserName = em.FromUserName;
tm.FromUserName = em.ToUserName;
tm.CreateTime = Common.GetNowTime();
return tm.GenerateContent();
}
}
}
6、效果图
终于大工告成,最后来看下效果图吧
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持菜鸟教程。
以上是大佬教程为你收集整理的微信公众平台开发教程(五)详解自定义菜单全部内容,希望文章能够帮你解决微信公众平台开发教程(五)详解自定义菜单所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。