简述
本文介绍 “公众空气质量” 小程序中尝试加入消息模板实现过程
需求分析
目前小程序查看空气质量均需主动打开后才能查看,后续考虑,如果能每天早晨主动推送,好提醒用户是否戴口罩。
实现过程
检查梳理API
模板消息
技术
WebAPI
构建服务端 + 微信小程序
步骤简述
选择“模板” (微信公众平台操作)
——> wx.login() 获取临时登录凭证(微信小程序)
——> 通过 appid、secret、临时登录凭证,验证获取 openid(后台服务)
——> 通过 appid、secret,验证获取 access_token (后台服务)
——> 通过 access_token、openid、template_id、form_id 及对应的消息数据,提交发送消息请求(后台服务)
选择“模板”
wx.login() 获取临时登录凭证
wxml
js
formSubmit: function (e) {
var that = this
wx.login({
success: function (res) {
wx.request({
url: 'https://xxxxxxxx/WebApi/api/Trend/' + res.code + '|' + e.detail.formId + '|' + that.data.city, //e.detail.formId 后续需使用
success: function (res) {
wx.showToast({
title: '推送成功',
icon: 'success',
duration: 2000
})
}
})
}
})
}
通过 appid、secret、临时登录凭证,验证获取 openid
string userId = "userId";
string appid = "wxxxxxxxxxxx";
string secret = "8xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
string url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appid + "&secret=" + secret + "&js_code=" + userId + "&grant_type=authorization_code";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream());
JObject jo = (JObject)JsonConvert.DeserializeObject(sr.ReadToEnd());
string openid = jo["openid"].ToString();
通过 appid、secret,验证获取 access_token
url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret + "";
request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
response = (HttpWebResponse)request.GetResponse();
sr = new StreamReader(response.GetResponseStream());
jo = (JObject)JsonConvert.DeserializeObject(sr.ReadToEnd());
string access_token = jo["access_token"].ToString();
通过 access_token、openid、template_id、form_id 及对应的消息数据,提交发送消息请求
string url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=" + access_token;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "Post";
request.ContentType = "application/x-www-form-urlencoded;charset=gb2312"; // 必须指明字符集!
//获取城市最新小时数据
DataTable dt = xxxxxxxxxxx;
string d = "{\"touser\":\"" + openid +
"\",\"template_id\":\"vTwsk-10bvQt0xJbrUUrxYeya7tHruC8U0oFkV6wC4M\",\"page\":\"/pages/board/board\",\"form_id\":\"" + formId
+ "\",\"data\":{\"keyword1\":{\"value\":\"" + dt.Rows[0]["time"].ToString()
+ "\",\"color\":\"#4a4a4a\"},\"keyword2\":{\"value\":\"" + dt.Rows[0]["city"].ToString()
+ "\",\"color\":\"#4a4a4a\"},\"keyword3\":{\"value\":\"" + dt.Rows[0]["aqi"].ToString() + "," + dt.Rows[0]["quality"].ToString()
+ "\",\"color\":\"#4a4a4a\"},\"keyword4\":{\"value\":\"" + aqi_getHealth(dt.Rows[0]["quality"].ToString()) + aqi_getMeasures(dt.Rows[0]["quality"].ToString())
+ "\",\"color\":\"#4a4a4a\"}},\"color\":\"#ccc\",\"emphasis_keyword\": \"keyword3.DATA\" }";
byte[] data = Encoding.UTF8.GetBytes(d);
request.ContentLength = data.Length;
Stream reqStream = request.GetRequestStream();
reqStream.Write(data, 0, data.Length);
reqStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
new StreamReader(response.GetResponseStream());
经验总结
https 不可直接添加至 request 合法域名
https://api.weixin.qq.com
相关请求、验证都需在后台实现
另官方推荐,appid、secret建议存储于服务器使用
消息模板发送限制
允许开发者向用户在7天内推送有限条数的模板消息(1次提交表单可下发1条,多次提交下发条数独立,相互不影响)
推送消息乱码
检查设置提交API
中字符集
request.ContentType = "application/x-www-form-urlencoded;charset=gb2312"; // 必须指明字符集!
byte[] data = Encoding.UTF8.GetBytes(d);
推送测试成功,上线后失败
实际使用中,开发调试、体验版均实时推送成功,审核发布后推送失败,暂未发现原因