【⼩程序】使⽤模板消息发送消息给多个⽤户
使⽤模板消息发送消息给多个⽤户
⼀、需求背景
基于的通知渠道,⼩程序为开发者提供了可以⾼效触达⽤户的模板消息能⼒,在⽤户本⼈与⼩程序页⾯有交互⾏为后触发,通过聊天列表中的服务通知可快捷进⼊查看消息,点击查看详情还能跳转到下发消息的⼩程序的指定页⾯。
⼩程序允许下发模板消息的条件分为两类:⽀付或者提交表单。通过提交表单来下发模板消息的限制为“允许开发者向⽤户在7天内推送有限条数的模板消息(1次提交表单可下发1条,多次提交下条数独⽴,相互不影响)”。
然⽽,⽤户1次触发7天内推送1条通知是明显不够⽤的。⽐如,签到功能利⽤模板消息的推送来提醒⽤户每天签到,只能在⽤户前⼀天签到的情况下,获取⼀次推送模板消息的机会,然后⽤于第⼆天向该⽤户发送签到提醒。但是很多情况下,⽤户在某⼀天忘记签到,系统便失去了提醒⽤户的权限,导致和⽤户断开了联系;再⽐如,系统想主动告知⽤户即将做某活动,然⽽由于⼩程序被动触发通知的限制,系统将⽆法主动推送消息。
⼆、如何突破模板消息的推送限制?
为了突破模板消息的推送限制,实现7天内任性推送,只需收集到⾜够的推送码,即每次提交表单时获取到的formId。⼀个formId代表着开发者有向当前⽤户推送模板消息的⼀次权限。
三、实现
1.收集推送码。获取多个表单id并保存,便于⼀次性发送给服务器
// 收集推送码
Page({
formSubmit: funcition(e) {//form表单按钮点击调⽤该⽅法
let formId = e.detail.formId; //获取表单formId
llectFormIds(formId); //保存推送码
let type = e.detail.pe; // 根据type执⾏点击事件奥运百米决赛
},
collectFormIds: function(formId) { //保存推送码
let formIds = app.globalData.globalFormIds; // 获取全局推送码数组
if (!formIds)
formIds = [];
let data = {
formId: formId,
expire: new Data().getTime() + 60480000 // 7天后的过期时间戳
}
formIds.push(data);
app.globalData.globalFormIds = formIds;
},
})
2.上传推送码。即将推送码发送给服务器然后保存起来(需要上传的数据:formId和openId)
// 上报推送码
Page({火炬之光2人物加点
onLoad: funcition(e) {
this.uploadFormIds(); //上传推送码
},
collectFormIds: function(formId) {
var formIds = app.globalData.globalFormIds; // 获取全局推送码
if (formIds.length) {
formIds = JSON.stringify(formIds); // 转换成JSON字符串
app.globalData.gloabalFomIds = ''; // 清空当前全局推送码
}
wx.request({ // 发送到服务器
url: 'xxx',
method: 'POST',
data: {
openId: 'openId',//openId为⼩程序的⽤户唯⼀标识,需⾃⾏获取
formIds: formIds//表单id
},
success: function(res) {
}
});
},
})
3.服务端-存储推送码(⾼频IO,采⽤Redis来存储推送码。将推送码保存到数据库实现持久化存储,由于formId有七天有效期,所以需要定时清理⽆效推送码)
/**
* 收集⽤户推送码
*
* @param openId ⽤户的openid
* @param formIds ⽤户的formId
*/
public void collect(String openId, List<FormTemplateVO> formTemplates) {
redisTemplate.opsForList().rightPushAll(openId, formIds);
}
4.发送模板消息相关接⼝
需要使⽤的接⼝:
1>模板消息发送api:POST api.weixin.qq/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN
要想使⽤该接⼝发送模板消息,还需要获取
ACCESS_TOKEN 即接⼝调⽤凭证
2>
接⼝调⽤凭证
api:
GET api.weixin.qq/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET 获取接⼝调⽤凭证需要appid和secret
孝敬父母的小故事appid:⼩程序唯⼀标识
secret:⼩程序唯⼀凭证密钥
appid和secret获取⽅式请查看:
5.推送模板消息。发送消息给⽤户
templateId消息模板id:⾃⾏登录获取
以下两个⽅法只是部分代码,调⽤sendTemplateMessage⽅法即可发送消息
/**
* 发送模板消息
*
* @param accessToken 接⼝调⽤凭证
* @param touser 接收者(⽤户)的 openid
* @param templateId 所需下发的模板消息的id
* @param page 点击模板卡⽚后的跳转页⾯,仅限本⼩程序内的页⾯。⽀持带参数,(⽰例index?foo=bar)。该字段不填则模板⽆跳转
* @param formId 表单提交场景下,为 submit 事件带上的 formId;⽀付场景下,为本次⽀付的 prepay_id
* @param data 模板内容,不填则下发空模板。具体格式请参考⽰例。
* @param emphasisKeyword 模板需要放⼤的关键词,不填则默认⽆放⼤
*/
public WxResSendTemplateMessage sendTemplateMessage(String accessToken, String touser, String templateId,
String page, String formId, Map<String, Object> data, String emphasisKeyword) {
/**
* data⽰例:
*
* "data": {
先富带动后富 * "keyword1": { "value": title, "color": "#173177" },
* "keyword2": { "value": gettime() }
* }
* emphasisKeyword⽰例:
* "emphasis_keyword": "keyword1.DATA"
*
草莓酱的做法
*/
/** 结果 */
String result = "";
/** 获取输出流 */
OutputStreamWriter os = null;
/** 获取输⼊流 */
BufferedReader in = null;
/** 请求地址 */
String urlPath = "api.weixin.qq/cgi-bin/message/wxopen/template/send?access_token=" + accessToken;
/** 需要传递的数据 */
Map<String, Object> messageData = new HashMap<>();气质高冷名字女
messageData.put("touser", touser);//接收者(⽤户)的 openid
messageData.put("template_id", templateId);//所需下发的模板消息的id
messageData.put("page", page);//点击模板卡⽚后的跳转页⾯,仅限本⼩程序内的页⾯。⽀持带参数,(⽰例index?
foo=bar)。该字段不填则模板⽆跳转
messageData.put("form_id", formId);//表单提交场景下,为 submit 事件带上的 formId;⽀付场景下,为本次⽀付的
prepay_id
messageData.put("data", data);//模板内容,不填则下发空模板。具体格式请参考⽰例。
messageData.put("emphasis_keyword", emphasisKeyword);//模板需要放⼤的关键词,不填则默认⽆放⼤
try {
/** 获得url对象 */
URL url = new URL(urlPath);
/** 打开连接 */
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
/** 设置通⽤的请求属性 */
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
/** 设置请求⽅式 */
conn.setRequestMethod(Http.HttpMethod.POST.name());
/** 设置允许读写出数据,默认可以读不可写 */
conn.setDoOutput(true);
conn.setDoInput(true);
/** 获取输出流 */
os = new OutputStream(), "UTF-8");
/** 发送请求参数 */
os.JsonString(messageData));
/** 输出缓存流 */
os.flush();
/** 获取输⼊流 */
in = new BufferedReader(new InputStream()));
/** 接收⾏数据 */
String line;
/** 读取数据 */
while((line = in.readLine()) != null) {
result += line;
}
} catch(Exception e) {
e.printStackTrace();
} finally {/** 释放输⼊输出流并关闭 */
try {
if(os != null) {
os.close();
}
if(in != null) {
in.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
(">>>模板消息发送>>>result={}>>>", result);
return (WxResSendTemplateMessage) JsonMapper.fromJsonString(result, WxResSendTemplateMessage.class); }
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论