模板消息 php-实现微信小程序模板消息不受限制、无限主动推送

需求背景

微信小程序基于微信的通知通道模板消息 php,为开发者提供了模板消息能力,可以高效触达用户。 用户与小程序页面交互后触发。 可以通过微信聊天列表中的服务通知快速访问消息。模板消息 php,点击查看详情并跳转至发送消息的小程序指定页面。

微信小程序允许下发模板消息的条件分为两类:支付或表单提交。 通过提交表单发送模板消息的限制为“允许开发者在7天内向用户推送有限数量的模板消息(一次提交表单只能发送一条消息,多次提交的消息数量独立)”并且互不影响)”。

但用户在触发后7天内推送通知显然是不够的。 例如,签到功能通过模板消息的推送来提醒用户每天签到。 它只能在用户前一天签到时获得一次推送模板消息的机会,然后利用它向用户发送第二天的签到提醒。 但很多情况下,如果用户在某一天忘记登录,系统就失去了提醒用户的权限,导致与用户断线; 再比如,系统想要主动通知用户即将进行某项活动,但微信小程序却被动触发了通知。 限制,系统将无法主动推送消息。

如何防止模板消息推送被限制?

突破:“一次表单提交可发布一项,多次提交提交的项目数量独立,互不影响。”

模板消息群发_模板消息申请理由怎么写_模板消息 php

想要突破模板消息推送限制,实现7天内任意推送,只需要收集足够的推送码,即每次提交表单时获取到的formId即可。 formId代表开发者向当前用户推送模板消息的一次性权限。

客户端收集推送码

当表单组件中的属性report-submit=true表示发送模板消息时,可以通过提交表单获取formId。 接下来我们只需要修改原来的页面,将用户原来绑定点击事件的界面替换为表单组件中的按钮组件即可。 即把用户交互点击的bindtap事件替换为表单bindsubmit,从而捕获用户的点击事件,生成更多的推送代码。

// 收集推送码
Page({
   formSubmit: funcition(e) {
let formId = e.detail.formId;
this.collectFormIds(formId); //保存推送码
let type = e.detail.target.dataset.type; // 根据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;
},
})

模板消息群发_模板消息 php_模板消息申请理由怎么写

登录后复制

举报推送码

等待用户下次发起网络请求时,将globalFormIds发送到服务器。

// 上报推送码
Page({
   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: 'http://xxx',
           method: 'POST',
           data: {
               openId: 'openId',
               formIds: formIds
},
           success: function(res) {
}
});
},
})

登录后复制

服务器

存储推送代码

高频IO,使用Redis存储推送代码。

模板消息申请理由怎么写_模板消息群发_模板消息 php

/**
* 收集用户推送码
*
* @param openId        用户的openid
* @param formTemplates 用户的表单模板
*/
public void collect(String openId, List formTemplates) {
   redisTemplate.opsForList().rightPushAll("mina:openid:" + openId, formTemplates);
}

登录后复制

推送模板消息

下面实现群发功能,针对特定用户类似。

/**
* 推送消息
*
* @param templateId 模板消息id
* @param page       跳转页面
* @param keyWords   模板内容
*/
public void push(String templateId, String page, String keyWords) {
String logPrefix = "推送消息";
// 获取access token
String accessToken = this.getAccessToken();
// 创建消息通用模板
MsgTemplateVO msgTemplateVO = MsgTemplateVO.builder().template_id(templateId).build();
// 跳转页面
   msgTemplateVO.setPage(StringUtils.isNotBlank(page) ? page : "");
// 模板内容
if (StringUtils.isNotBlank(keyWords)) {
String[] keyWordArr = keyWords.split(BaseConsts.COMMA_STR);
Map keyWordMap = new HashMap(8);
for (int i = 0; i < keyWordArr.length; i++) {
MsgTemplateVO.KeyWord keyWord = msgTemplateVO.new KeyWord(keyWordArr[i]);
           keyWordMap.put(MsgTemplateVO.KEYWORD + (i + 1), keyWord);
}
       msgTemplateVO.setData(keyWordMap);
} else {
       msgTemplateVO.setData(Collections.emptyMap());
}
// 获取所有用户
List openIdList = minaRedisDao.getAllOpenIds();
for (String openId : openIdList) {
// 获取有效推送码
String formId = minaRedisDao.getValidFormId(openId);
if (StringUtils.isBlank(formId)) {
           LOGGER.error("{}>>>openId={}>>>已无有效推送码[失败]", logPrefix, openId);
continue;
}
// 指派消息
MsgTemplateVO assignMsgTemplateVO = msgTemplateVO.assign(openId, formId);
// 发送消息
Map resultMap;
try {
String jsonBody = JsonUtils.getObjectMapper().writeValueAsString(assignMsgTemplateVO);
String resultBody = OkHttpUtils.getInstance().postAsString(messageUrl + accessToken, jsonBody);
           resultMap = JsonUtils.getObjectMapper().readValue(resultBody, Map.class);
} catch (IOException e) {
           LOGGER.error("{}>>>openId={}>>>{}[失败]", logPrefix, openId, e.getMessage(), e);
continue;
}
if ((int) resultMap.get(ResponseConsts.Mina.CODE) != 0) {
           LOGGER.error("{}>>>openId={}>>>{}[失败]", logPrefix, openId, resultMap.get(ResponseConsts.Mina.MSG));
continue;
}
       LOGGER.info("{}>>>openId={}>>>[成功]", logPrefix, openId);
}
}
/**
* 根据用户获取有效的推送码
*
* @param openId 用户的openid
* @return 推送码
*/
public String getValidFormId(String openId) {
List formTemplates = redisTemplate.opsForList().range("mina:openid:" + openId, 0, -1);
String validFormId = "";
int trimStart = 0;
int size;
for (int i = 0; i  System.currentTimeMillis()) {
           validFormId = formTemplates.get(i).getFormId();
           trimStart = i + 1;
break;
}
}
// 移除本次使用的和已过期的
   redisTemplate.opsForList().trim(KEY_MINA_PUSH + openId, trimStart == 0 ? size : trimStart, -1);
return validFormId;
}

登录后复制

上述方案可以在用户上次使用小程序后7天内向用户发送多条模板消息来召回用户。

以上就是如何实现微信小程序模板消息无限制、无限制主动推送的全部细节。

相关文章:

微信小程序消息推送php服务器验证