>백엔드 개발 >PHP 튜토리얼 >WeChat 미니 프로그램 템플릿 메시지의 무제한 및 무제한 활성 푸시 실현

WeChat 미니 프로그램 템플릿 메시지의 무제한 및 무제한 활성 푸시 실현

韦小宝
韦小宝원래의
2018-03-01 14:55:599535검색

요구사항 배경

WeChat 알림 채널을 기반으로 WeChat 미니 프로그램은 사용자에게 효율적으로 도달할 수 있는 템플릿 메시지 기능을 개발자에게 제공합니다. 사용자가 미니 프로그램 페이지와 상호작용한 후 WeChat 채팅 목록을 통해 빠르게 액세스할 수 있습니다. 메시지를 보려면 클릭하세요. 세부정보를 확인하고 메시지를 보낸 미니 프로그램의 지정된 페이지로 이동합니다.

WeChat 애플릿에서 템플릿 메시지 발행을 허용하는 조건은 결제 또는 양식 제출이라는 두 가지 범주로 나뉩니다. 양식을 제출하여 템플릿 메시지를 보내는 것에 대한 제한은 "개발자가 7일 이내에 제한된 수의 템플릿 메시지를 사용자에게 푸시할 수 있도록 허용합니다(양식이 제출되면 하나의 메시지가 전송될 수 있으며 여러 번 제출된 메시지 수는 독립적이며 서로 영향을 미치지 않습니다) ".

그러나 사용자가 트리거된 후 7일 이내에 하나의 알림을 푸시하는 것만으로는 충분하지 않습니다. 예를 들어, 체크인 기능은 템플릿 메시지 푸시를 사용하여 사용자에게 매일 체크인하도록 상기시킵니다. 사용자가 전날 체크인할 때 템플릿 메시지를 한 번만 푸시한 다음 이를 사용하여 보낼 수 있습니다. 다음날 사용자에게 체크인 알림을 보냅니다. 그러나 많은 경우, 사용자가 특정 날짜에 로그인하는 것을 잊어버린 경우 시스템은 사용자에게 알림을 보낼 권한을 상실하여 사용자와의 연결이 끊어지게 됩니다. 특정 활동을 수행하려고 하지만 WeChat 애플릿이 알림 제한을 수동적으로 트리거하면 시스템이 메시지를 적극적으로 푸시할 수 없습니다.

템플릿 메시지 푸시가 제한되는 것을 어떻게 방지할 수 있나요?

획기적 방법: "하나의 양식 제출은 하나의 메시지를 발행할 수 있으며, 여러 제출은 서로 영향을 주지 않고 독립적인 번호를 발행할 수 있습니다."

템플릿 메시지의 푸시 제한을 돌파하고 7일 이내에 임의 푸시를 달성하려면 충분히 수집해야 합니다. 푸시 코드는 양식이 제출될 때마다 획득되는 양식 ID입니다. formId는 현재 사용자에게 템플릿 메시지를 푸시할 수 있는 개발자의 일회성 권한을 나타냅니다.

Client

푸시 코드를 수집합니다

양식 구성 요소의 report-submit=true 속성이 템플릿 메시지 전송을 의미하고 양식을 제출하면 formId를 얻을 수 있습니다. 다음으로 원본 페이지를 수정하고 사용자가 원래 클릭 이벤트를 바인딩한 인터페이스를 양식 구성 요소의 버튼 버튼 구성 요소로 바꾸면 됩니다. 즉, 사용자의 대화형 클릭의 바인딩 탭 이벤트를 양식 바인딩 제출로 바꾸면 됩니다. 따라서 사용자 클릭 이벤트를 캡처하여 더 많은 푸시 코드를 생성합니다.

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

푸시 코드 신고

다음번에 사용자가 네트워크 요청을 시작할 때까지 기다리는 동안 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) {
}
});
},
})

Server

스토리지 푸시 코드

고빈도 IO, Redis를 사용하여 푸시 코드 저장.

/**
* 收集用户推送码
*
* @param openId        用户的openid
* @param formTemplates 用户的表单模板
*/
public void collect(String openId, List<FormTemplateVO> 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<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;
}

위 솔루션은 사용자가 미니 프로그램을 마지막으로 사용한 후 7일 이내에 사용자를 불러올 수 있도록 여러 개의 템플릿 메시지를 사용자에게 보낼 수 있습니다.

WeChat 미니 프로그램 템플릿 메시지의 무제한 및 무제한 활성 푸시를 구현하는 방법에 대한 모든 세부 정보입니다.

관련 기사:

WeChat 애플릿 메시지 푸시 PHP 서버 확인

위 내용은 WeChat 미니 프로그램 템플릿 메시지의 무제한 및 무제한 활성 푸시 실현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.