上一篇文章中,说明如何从微信服务器获取用户输入的数据,并按照指定格式返回至微信服务器。本质上是前端代码调用后台的代码。而消息处理的剩余两项:客服消息和模板消息,则是通过开发者服务器,将数据推送到微信服务器上,有点类似,“前端”调用“后台”的方法。另外在微信公众号中,创建菜单的功能,也是将数据推送到微信服务器上,与上面的两个类似。所以本篇就将创建菜单、模板消息、客服消息三者合在一起讲述。先说一下创建菜单。
用POST方式,向下面的URL中传入指定格式的JSON字符串即可
https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
JSON的格式
//这个是微信公众号官网的例子,我直接拿来使用了---郑林 2019-11-19
{
"button":[
{
"type":"click",
"name":"今日歌曲",
"key":"V1001_TODAY_MUSIC"
},
{
"name":"菜单",
"sub_button":[
{
"type":"view",
"name":"搜索",
"url":"http://www.soso.com/"
},
{
//这个是小程序,需要开发者自己开发 --- 郑林 2019-11-19
"type":"miniprogram",
"name":"wxa",
"url":"http://mp.weixin.qq.com",
"appid":"wx286b93c14bbf93aa",
"pagepath":"pages/lunar/index"
},
{
"type":"click",
"name":"赞一下我们",
"key":"V1001_GOOD"
}]
}]
}
思路很简单,就是向指定的URL发起一个POST请求,并且带着指定格式的数据。
不过这儿有一个事情需要说明,就是在URL最后有一个ACCESS_TOKEN,这个是访问令牌,如何获取这个值呢?可以通过如下的方式:
向下面的URL发起一个GET请求。
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
其中APPID和APPSECRET为你账号的ID和密码,以我测试账号为例:
上面的URL返回一个JSON,如下所示,将JSON解析即可。
{“access_token”:“ACCESS_TOKEN”,“expires_in”:7200}
另外,这个访问令牌的有效期是2小时,所以接近2小时时,应该有一个刷新的机制。
言归正传,直接贴代码
//创建菜单主方法
private string createMenu()
{
//1、将创建菜单的JSON数据保存到menu.txt了,也可以直接将JSON写成一个string串
FileStream fs1 = new FileStream(Server.MapPath("~/") + "\\App_Data\\menu.txt", FileMode.Open);
StreamReader sr = new StreamReader(fs1, Encoding.GetEncoding("GBK"));
string menu = sr.ReadToEnd();
sr.Close();
fs1.Close();
//2、获取我的访问令牌
string my_token = getMyWeChatToken();
//3、组合成创建菜单的URL
string url = string.Format("https://api.weixin.qq.com/cgi-bin/menu/create?access_token={0}", my_token);
//4、调用创建菜单的方法,并返回结果
return createMenu(url, menu);
}
我将创建menu的内容放到menu.txt中了,txt中具体内容如下:
{
"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"
}]
}]
}
还是原来官网上的例子,只不过是把小程序的那个给取消了
//获取访问令牌
public string getMyWeChatToken()
{
if (HttpContext.Cache["access_token"] == null)
{
string urltemp = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";
//需要填写自己的APPID和APPSECRET
string url = string.Format(urltemp, "1111111", "1111111111");
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded";//链接类型
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
string access_token = "";
using (Stream s = response.GetResponseStream())
{
StreamReader reader = new StreamReader(s, Encoding.UTF8);
access_token= reader.ReadToEnd();
}
JObject my_toke_obj =(JObject) JsonConvert.DeserializeObject(access_token);
string my_token = my_toke_obj["access_token"].ToString();
//将访问令牌存储到Cache中
Cache cache = HttpContext.Cache;
cache.Insert("access_token", my_token, null, DateTime.Now.AddSeconds(7000), Cache.NoSlidingExpiration);
return my_toke_obj["access_token"].ToString();
}
else
{
return HttpContext.Cache["access_token"].ToString();
}
}
以上把访问令牌存放到Cache中,这只是演示使用,真实环境必须做相关处理。另外,方法中用到了JSON解析,不要忘记引用
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
创建菜单的方法如下:
//创建菜单
private string createMenu(string url,string menu_txt)
{
Stream outstream = null;
Stream instream = null;
StreamReader sr = null;
HttpWebResponse response = null;
HttpWebRequest request = null;
Encoding encoding = Encoding.UTF8;
byte[] data = encoding.GetBytes(menu_txt);
request = WebRequest.Create(url) as HttpWebRequest;//创建请求
//写入数据
CookieContainer cookieContainer = new CookieContainer();
request.CookieContainer = cookieContainer;
request.AllowAutoRedirect = true;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
outstream = request.GetRequestStream();
outstream.Write(data, 0, data.Length);
outstream.Close();
//读取返回结果
response = request.GetResponse() as HttpWebResponse;
instream = response.GetResponseStream();
sr = new StreamReader(instream, encoding);
string content = sr.ReadToEnd();
//读取操作码
JObject my_toke_obj = (JObject)JsonConvert.DeserializeObject(content);
string error_code = my_toke_obj["errcode"].ToString();
return error_code;
}
上面的方法写完之后,将代码部署到开发者服务器上,然后调用相关方法即可。我是在访问某个Controller时调用的创建菜单的方法,代码如下:
public ActionResult About()
{
//创建菜单
string create_code = createMenu();
ViewBag.MyMessage = create_code;
return View();
}
当网站访问About页面时,就会调用创建菜单的方法,并将操作代码展示在界面上。