Home  >  Article  >  Backend Development  >  Realize unrestricted and unlimited active push of WeChat mini program template messages

Realize unrestricted and unlimited active push of WeChat mini program template messages

韦小宝
韦小宝Original
2018-03-01 14:55:599474browse

Requirement background

Based on WeChat’s notification channel, WeChat mini programs provide developers with template messaging capabilities that can efficiently reach users, allowing users to interact with the mini program page. Triggered after the action, you can quickly access the message through the service notification in the WeChat chat list. Click to view the details and jump to the designated page of the mini program that sent the message.

The conditions for WeChat applet to allow the issuance of template messages are divided into two categories: payment or form submission. The restriction on sending template messages by submitting a form is "Allow developers to push a limited number of template messages to users within 7 days (one message can be sent once a form is submitted, and the number of messages submitted for multiple submissions is independent and does not affect each other) ".

However, it is obviously not enough for a user to push a notification within 7 days once triggered. For example, the check-in function uses the push of template messages to remind users to check in every day. It can only get the opportunity to push the template message once when the user checked in the day before, and then use it to send check-in reminders to the user the next day. However, in many cases, if a user forgets to sign in on a certain day, the system loses the authority to remind the user, resulting in disconnection with the user; for another example, the system wants to proactively inform the user that they are about to do a certain activity, but the WeChat applet passively triggers the notification. limit, the system will not be able to actively push messages.

How to prevent template message push from being restricted?

Breakthrough: "One form submission can issue one message, and the number of messages submitted for multiple submissions is independent and does not affect each other."

In order to break through the push limit of template messages, implement You can push at will within 7 days, as long as you collect enough push codes, which is the formId obtained every time you submit a form. A formId represents the developer's one-time permission to push template messages to the current user.

Client

Collect push code

When the attribute report-submit=true in Form component It means sending a template message, and you can get the formId by submitting the form. Next, we only need to modify the original page, and replace the interface where the user originally bound the click event with the buttonButton Group component in the form component, that is, the bindtap event of the user's interactive click is replaced by the form bindsubmit Instead, capture the user's click event to generate more push codes.

// 收集推送码
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;
},
})

Report push code

Waiting for the next time the user initiates a network request, the globalFormIds will be sent to the server.

// 上报推送码
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) {
}
});
},
})

Server

Storage push code

High frequency IO, using Redis to store push code.

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

Push template message

The following implements the function of group sending, which is similar for specific users.

/**
* 推送消息
*
* @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<String, MsgTemplateVO.KeyWord> 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<String> 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<String, Object> 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<FormTemplateVO> formTemplates = redisTemplate.opsForList().range("mina:openid:" + openId, 0, -1);

String validFormId = "";
int trimStart = 0;

int size;
for (int i = 0; i < (size = formTemplates.size()); i++) {
if (formTemplates.get(i).getExpire() > 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;
}

The above solution can send multiple template messages to the user to recall the user within 7 days after the user last used the mini program.

This is all the details on how to implement unrestricted and unlimited active push of WeChat mini program template messages.

Related articles:

WeChat applet message push php server verification

The above is the detailed content of Realize unrestricted and unlimited active push of WeChat mini program template messages. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn