首页 > 编程知识 正文

php推送消息到手机上,php微信小程序实例

时间:2023-05-04 21:58:51 阅读:149447 作者:3090

需求背景

基于微信的通知渠道,微信APP为开发者提供可有效访问用户的模板消息功能,用户自身与微信页面交互后触发,通过微信列表的服务通知快速访问短信

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

但是,用户在单个触发器中在7天内推送一个通知显然是不够的。 例如,登录功能用于通过推送模板消息提醒用户每日登录,只有在前一天登录的情况下才能获得推送模板消息的机会,并在第二天向该用户发送登录通知。 但是,在很多情况下,用户有一天忘记了签名,系统失去了警告用户的权限,与用户的联系被切断。 例如,虽然系统希望主动告知用户已计划事件,但由于微信小程序被动地触发通知的限制,系统不能主动地推送消息。

如何确保模板消息的推送不受限制?

突破口:“一次提交表格一份,多次提交条数独立,互不影响”

为了突破模板消息推送限制,实现7天任性推送,每次提交表格时只需收集足够的推送代码formId。 formId表示开发人员有权向当前用户推送模板消息。

客户端

收集推送代码

如果表单组件的属性report-submit=true,则提交表单时将检索formId并发送模板消息。 然后,改造原始页面,将用户绑定单击事件的界面替换为表单组件的button按钮组件。 也就是说,通过将用户的交互式点击的bindtap事件替换为表单bindsubmit,捕获用户的点击事件并生成更多的推送代码。 //收集推送代码

page({

FORMsubmit:funcition(e ) {

let formId=e.detail.formId;

this.collectformids(formid; //保存推送代码

lettype=e.detail.target.dataset.type; 根据type执行点击事件

(,

CollectFormids3360function{

letformids=app.global data.global formids; //获取全局推送代码数组

if (! formIds )

格式=[ ];

let data={

formId: formId,

expire:newdata(.gettime ) ) 60480000 //7天后过期的时间戳

}

Formids.push(data;

app.global data.global formids=formids;

(,

() )

提升推送代码

等待用户下次启动网络请求,然后将globalFormIds发送到服务器。 //升级推送代码

page({

Onload:funcition(e ) {

this.uploadFormIds (; //上传推送代码

(,

CollectFormids3360function{

varfor mids=app.global data.global formids; //获取全局推送代码

格式. length (if ) {

Formids=JSON.stringify(Formids ); 转换为JSON字符串

app.globalData.gloabalFomIds=' '; //清空当前全局推送代码

}

wx.request(//发送到服务器

url: 'http://xxx ',

方法: ' post ',

数据: {

openId: 'openId ',

格式:格式

(,

success :函数(RES ) {

}

);

(,

() )

服务器端

保存推送代码

使用高频IO、Redis存储推送代码。 //*

*收集用户推送代码

*

* @param openId用户的openid

* @param formTemplates用户的表单模板

*/

公共语音集合(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 < (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天内,对用户发送多条模板消息唤回用户。

这就是实现微信小程序模板消息不受限制、无限主动推送的方法详细的所有内容。

相关文章:

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。