微信小程序消息推送

简介
微信小程序发送消息推送到用户微信上
基础流程
- 用户登录 :获取微信提供的openid
- 开发者去微信公众平台申请模板:获得模板id
- 授权消息推送:在小程序中调用wx.requestSubscribeMessage方法
- 成功后将数据保存到后台 消息推送表 中
- 在需要发送消息推送时:查询 消息推送表 如果有,使用 消息推送表 的数据调用接口subscribeMessage.send
细节流程
1.1用户微信登录(缓存opid)
1.2用户普通登录(无opid)
2 消息推送申请
2.1用户授权
2.1.1无opid(弹框要求 微信登录(类似第一步)
2.1.2有opid(继续
2.2获得了授权的模板id和opid
3传输到后台,后台存储到消息推送表,参数:模板id,opid,用户名称,身份证。默认参数:是否发送为N,创建时间,主键 ,发送时间为空
4后台定时器,查询到要发送的用户时,查询消息推送表,修改发送状态为Y,更新发送时间,然后发送微信小程序消息推送
代码
1用户微信小程序登录
wx.login({
success: res => {
console.log(res);
// 发送 res.code 到后台换取 openId, sessionKey, unionId
request.post('后台用小程序id和密钥获取Openid的接口.do', {
code: res.code
}).then((res) => {
console.log(res);
let result = JSON.parse(res.result);
wx.setStorageSync('openid',result.openid)//缓存openid
that.setData({
sessionKey: result.session_key
})
});
}
})
2 小程序消息推送授权
let templateId = '模板id';
wx.requestSubscribeMessage({
tmplIds: [templateId],
success (res) {
console.log(res);
if(res.模板id =='reject'){//被拒绝
}else{//同意
//获取缓存的openid,可能是之前用户登录时存放的
let opid = wx.getStorageSync('openid');
//如果有OPID,直接发送
if(opid){
//执行保存到后台的操作
that.saveSubMssage(opid,templateId);
}else{
wx.showToast({
title: '需要关联微信账号',
icon: 'success',
duration: 2000
})
//和登录授权一样
wx.login({
success: res => {
console.log(res);
// 发送 res.code 到后台换取 openId, sessionKey, unionId
request.post('后台换取用户id的接口', {
code: res.code
}).then((res) => {
//得到openid
let result = JSON.parse(res.result);
wx.setStorageSync('openid',result.openid)
opid=res.openid;
//执行保存到后台的操作
that.saveSubMssage(opid,templateId);
});
}
})
}
}
},
error(res){
console.log(res);
wx.showToast({
title: '授权出现错误',
icon: 'none',
duration: 2000
})
}
})
saveSubMssage(openid,tmplIds){
let that = this;
request.Post('后台保存用户同意消息推送的接口.do', {
openId: openid,//用户openid
templateId: tmplIds,//模板id
userName: encodeURI(that.data.userName),//中文乱码处理
idCard: that.data.idCard//身份证
}).then((res) => {
console.log(res);
wx.showToast({
title: '授权成功',
icon: 'success',
duration: 2000
})
//退出页面
setTimeout(function() {
wx.navigateBack({ changed: true });
}, 2000);
});
3 后台保存用户同意消息推送的接口
@RequestMapping(value="/SaveMessageAuthority.do" ,produces = "application/json;charset=UTF-8")
@ResponseBody
public String SaveMessageAuthority(String openId,String templateId,String userName ,String idCard) throws Exception {
try {
WeChatMessageAuthorityPO weChatMessageAuthority = new WeChatMessageAuthorityPO();
weChatMessageAuthority.setOpenId(openId);
weChatMessageAuthority.setTemplateId(templateId);
weChatMessageAuthority.setIdCard(idCard);
// String temp = request.getParameter("studentName");
if(StringUtils.isNotEmpty(userName)){
userName = java.net.URLDecoder.decode(userName,"UTF-8");
weChatMessageAuthority.setUserName(userName);
}
weChatMessageAuthority.setCreateDate(new Date());
weChatMessageAuthority.setIsSend(BaseStaticParameter.NO);
iWxMassageAuthorityService.saveOrUpdate(weChatMessageAuthority);
}catch (Exception e){
e.printStackTrace();
return "false";
}
return "true";
}
4 后台发送推送信息
public static boolean sendNearRemindMessage(String openId,String serveName,String windowName,String lineNumber,String waitNumber,String msg) throws Exception {
WxMaSubscribeMessage subscribeMessage = new WxMaSubscribeMessage();
//跳转小程序页面路径
subscribeMessage.setPage("pages/index/index");
//模板消息id
subscribeMessage.setTemplateId(WxMaConfiguration.templateId);
//给谁推送 用户的openid (可以调用根据code换openid接口)
subscribeMessage.setToUser(openId);
//==========================================创建一个参数集合========================================================
ArrayList<WxMaSubscribeData> wxMaSubscribeData = new ArrayList<>();
// 订阅消息参数值内容限制说明
// ---摘自微信小程序官方:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html
// 参数类别 参数说明 参数值限制 说明
// thing.DATA 事物 20个以内字符 可汉字、数字、字母或符号组合
// number.DATA 数字 32位以内数字 只能数字,可带小数
// letter.DATA 字母 32位以内字母 只能字母
// symbol.DATA 符号 5位以内符号 只能符号
// character_string.DATA 字符串 32位以内数字、字母或符号 可数字、字母或符号组合
// time.DATA 时间 24小时制时间格式(支持+年月日) 例如:15:01,或:2019年10月1日 15:01
// date.DATA 日期 年月日格式(支持+24小时制时间) 例如:2019年10月1日,或:2019年10月1日 15:01
// amount.DATA 金额 1个币种符号+10位以内纯数字,可带小数,结尾可带“元” 可带小数
// phone_number.DATA 电话 17位以内,数字、符号 电话号码,例:+86-0766-66888866
// car_number.DATA 车牌 8位以内,第一位与最后一位可为汉字,其余为字母或数字 车牌号码:粤A8Z888挂
// name.DATA 姓名 10个以内纯汉字或20个以内纯字母或符号 中文名10个汉字内;纯英文名20个字母内;中文和字母混合按中文名算,10个字内
// phrase.DATA 汉字 5个以内汉字 5个以内纯汉字,例如:配送中
WxMaSubscribeData wxMaSubscribeData1 = new WxMaSubscribeData();
wxMaSubscribeData1.setName("thing1");
wxMaSubscribeData1.setValue(serveName);
wxMaSubscribeData.add(wxMaSubscribeData1);
WxMaSubscribeData wxMaSubscribeData2 = new WxMaSubscribeData();
wxMaSubscribeData2.setName("thing6");
wxMaSubscribeData2.setValue(windowName);
wxMaSubscribeData.add(wxMaSubscribeData2);
WxMaSubscribeData wxMaSubscribeData3 = new WxMaSubscribeData();
wxMaSubscribeData3.setName("character_string2");
wxMaSubscribeData3.setValue(lineNumber);
wxMaSubscribeData.add(wxMaSubscribeData3);
WxMaSubscribeData wxMaSubscribeData4 = new WxMaSubscribeData();
wxMaSubscribeData4.setName("number3");
wxMaSubscribeData4.setValue(waitNumber);
wxMaSubscribeData.add(wxMaSubscribeData4);
WxMaSubscribeData wxMaSubscribeData5 = new WxMaSubscribeData();
wxMaSubscribeData5.setName("thing5");
wxMaSubscribeData5.setValue(msg);//"快到您了,请关注窗口和叫号情况"
wxMaSubscribeData.add(wxMaSubscribeData5);
//把集合给大的data
subscribeMessage.setData(wxMaSubscribeData);
//=========================================封装参数集合完毕========================================================
try {
System.out.println(JsonUtil.toJSONString(subscribeMessage));
//获取微信小程序配置:
final WxMaService wxService = WxMaConfiguration.getMaService(WxMaConfiguration.appid);
//进行推送
wxService.getMsgService().sendSubscribeMsg(subscribeMessage);
return true;
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.toString());
}
return false;
}
5 微信maven(微信调用方式可选)
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
<version>3.6.0</version>
</dependency>
6 WxMaConfiguration
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
import cn.binarywang.wx.miniapp.bean.WxMaMessage;
import cn.binarywang.wx.miniapp.bean.WxMaTemplateData;
import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import cn.binarywang.wx.miniapp.message.WxMaMessageHandler;
import cn.binarywang.wx.miniapp.message.WxMaMessageRouter;
import cn.binarywang.wx.miniapp.message.WxMaXmlOutMessage;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.io.File;
import java.util.Map;
/**
* create by zhaojiong
* 22-8-16
*/
@Configuration
public class WxMaConfiguration {
//叫号
public final static String jh_templateId = "
消息模板id";
//排队
public final static String pd_templateId = "消息模板id";
public final static String appid = "按情况填写";
public final static String secret = "按情况填写";
public final static String token = "按情况填写";
public final static String aesKey = "按情况填写";
public final static String msgDataFormat = "JSON";
//
private static Map<String, WxMaMessageRouter> routers = Maps.newHashMap();
private static Map<String, WxMaService> maServices = Maps.newHashMap();
//
//
public static WxMaService getMaService(String appid) {
WxMaService wxService = maServices.get(appid);
if (wxService == null) {
throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid));
}
return wxService;
}
//
public static WxMaMessageRouter getRouter(String appid) {
return routers.get(appid);
}
//
//
@PostConstruct
public void init() {
WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
config.setAppid(appid);
config.setSecret(secret);
config.setToken(token);
config.setAesKey(aesKey);
config.setMsgDataFormat(msgDataFormat);
WxMaService service = new WxMaServiceImpl();
service.setWxMaConfig(config);
routers.put(appid, this.newRouter(service));
maServices.put(appid, service);
}
//
private WxMaMessageRouter newRouter(WxMaService service) {
final WxMaMessageRouter router = new WxMaMessageRouter(service);
router
.rule().handler(logHandler).next()
.rule().async(false).content("模板").handler(templateMsgHandler).end()
.rule().async(false).content("文本").handler(textHandler).end()
.rule().async(false).content("图片").handler(picHandler).end()
.rule().async(false).content("二维码").handler(qrcodeHandler).end();
return router;
}
private final WxMaMessageHandler templateMsgHandler = new WxMaMessageHandler() {
@Override
public WxMaXmlOutMessage handle(WxMaMessage wxMessage, Map<String, Object> context, WxMaService service, WxSessionManager sessionManager) throws WxErrorException {
service.getMsgService().sendTemplateMsg(WxMaTemplateMessage.builder()
.templateId("此处更换为自己的模板id")
.formId("自己替换可用的formid")
.data(Lists.newArrayList(
new WxMaTemplateData("keyword1", "339208499", "#173177")))
.toUser(wxMessage.getFromUser())
.build());
return null;
}
};
private final WxMaMessageHandler logHandler = new WxMaMessageHandler() {
@Override
public WxMaXmlOutMessage handle(WxMaMessage wxMessage, Map<String, Object> context, WxMaService service, WxSessionManager sessionManager) throws WxErrorException {
System.out.println("收到消息:" + wxMessage.toString());
service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("收到信息为:" + wxMessage.toJson())
.toUser(wxMessage.getFromUser()).build());
return null;
}
};
private final WxMaMessageHandler textHandler = new WxMaMessageHandler() {
@Override
public WxMaXmlOutMessage handle(WxMaMessage wxMessage, Map<String, Object> context, WxMaService service, WxSessionManager sessionManager) throws WxErrorException {
service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回复文本消息")
.toUser(wxMessage.getFromUser()).build());
return null;
}
};
private final WxMaMessageHandler picHandler = new WxMaMessageHandler() {
@Override
public WxMaXmlOutMessage handle(WxMaMessage wxMessage, Map<String, Object> context, WxMaService service, WxSessionManager sessionManager) throws WxErrorException {
try {
WxMediaUploadResult uploadResult = service.getMediaService()
.uploadMedia("image", "png",
ClassLoader.getSystemResourceAsStream("tmp.png"));
service.getMsgService().sendKefuMsg(
WxMaKefuMessage
.newImageBuilder()
.mediaId(uploadResult.getMediaId())
.toUser(wxMessage.getFromUser())
.build());
} catch (WxErrorException e) {
e.printStackTrace();
}
return null;
}
};
private final WxMaMessageHandler qrcodeHandler = new WxMaMessageHandler() {
@Override
public WxMaXmlOutMessage handle(WxMaMessage wxMessage, Map<String, Object> context, WxMaService service, WxSessionManager sessionManager) throws WxErrorException {
try {
final File file = service.getQrcodeService().createQrcode("123", 430);
WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia("image", file);
service.getMsgService().sendKefuMsg(
WxMaKefuMessage
.newImageBuilder()
.mediaId(uploadResult.getMediaId())
.toUser(wxMessage.getFromUser())
.build());
} catch (WxErrorException e) {
e.printStackTrace();
}
return null;
}
};
}
407a4f37-fd09-4b00-873c-0eaa1ca3b473
微信小程序消息推送的更多相关文章
- 微信小程序--消息推送配置Token令牌错误校验失败如何解决
微信开放第三方API接口, 申请地址: https://mp.weixin.qq.com/advanced/advanced?action=interface&t=advanced/inter ...
- Java实现 微信小程序 + 消息推送
实现效果: 下面要显示五个字段 接下来,参照官方文档,一步步实现: https://developers.weixin.qq.com/miniprogram/dev/api-backend/open- ...
- 微信小程序消息推送,前端操作
<form bindsubmit="getFormId" report-submit="true"> <button form-type=&q ...
- 微信小程序消息通知-打卡考勤
微信小程序消息通知-打卡考勤 效果: 稍微改一下js就行,有不必要的错误,我就不改了,哈哈! index.js //index.js const app = getApp() // 填写微信小程序ap ...
- .NET CORE 微信小程序消息验证的坑
进入微信小程序,点击开发->选择消息推送->扫码授权,填写必要参数 进入接口开发: /// <summary> /// 验证小程序 /// </summary> / ...
- Java企业微信开发_05_消息推送之发送消息(主动)
一.本节要点 1.发送消息与被动回复消息 (1)流程不同:发送消息是第三方服务器主动通知微信服务器向用户发消息.而被动回复消息是 用户发送消息之后,微信服务器将消息传递给 第三方服务器,第三方服务器接 ...
- Java企业微信开发_04_消息推送之发送消息(主动)
源码请见: Java企业微信开发_00_源码及资源汇总贴 一.本节要点 1.发送消息与被动回复消息 (1)流程不同:发送消息是第三方服务器主动通知微信服务器向用户发消息.而被动回复消息是 用户发送消息 ...
- 利用python对微信自动进行消息推送
from wxpy import * #该库主要是用来模拟与对接微信操作的 import requests from datetime import datetime import time impo ...
- Java企业微信开发_05_消息推送之被动回复消息
一.本节要点 1.消息的加解密 微信加解密包 下载地址:http://qydev.weixin.qq.com/java.zip ,此包中封装好了AES加解密方法,直接调用方法即可. 其中,解 ...
- php实现微信小程序消息通知
大家好,又见面了,我是你们的朋友全 接入消息通知指引地址:https://mp.weixin.qq.com/debug/wxadoc/dev/api/custommsg/callback_help.h ...
随机推荐
- Linux reboot全过程
一.版本说明嵌入式Linux 下面的reboot命令看似简单,但出问题时定位起来发现别有洞天.下面就按在shell下执行reboot命令之后程序的执行过程进行解析.Busybox:1.23.2 ...
- for循环的注意事项
1.注意事项! 实操 可以看见上图,当{}里的循环走完后,i还存在,但是a消失了,因此{}里的变量会在每一次循环结束后释放 . 这也是为什么之前我们打印a会出错的原因:a早就已经从内存中释放了,还怎么 ...
- AIops
How does AIOps work?With AIOps, your organization takes a more proactive approach to resolve IT oper ...
- VJ结营测试
A 这题其实自己画一下图可以发现当奇数行为每行都为W,偶数行为W与R交替出现,就可以得到满足题意的图形了. 点击查看代码 #include<bits/stdc++.h> using nam ...
- Linux poweroff 命令
poweroff 命令命令用于关闭计算器并切断电源. 使用权限:系统管理者. 语法 poweroff [-n] [-w] [-d] [-f] [-i] [-h] 参数说明: -n : 在关机前不做将记 ...
- ChirpStack 设备连通性测试极简工具
一.工具简介 你是否为调试 ChirpStack 设备数据连通性而烦恼?是否希望快速验证数据解析逻辑而无需复杂部署?这个 ChirpStack 数据连通性测试工具,算是一个极简解决方案! 无论是 Ch ...
- Unity资源打包之Asset Bundle
Asset Bundle的作用: 1.AssetBundle是一个压缩包包含模型.贴图.预制体.声音.甚至整个场景,可以在游戏运行的时候被加载: 2.AssetBundle自身保存着互相的依赖关系: ...
- rabbitmq防止消息的重复消费
一.rabbitmq出现消息重复的场景 A:消息消费成功,事务已经提交,ack时,机器宕机,导致没有ack成功, Broker的消息重新由unack变为ready,并发送给其他消费者 B:消息消费失败 ...
- eolinker校验规则之 Json Path定位:返回值内有多项同类参数,检验其中一个参数值
比如创建商品后,查询商品是否生成,执行完创建商品接口后就需要再执行查询商品接口. 查询接口查询出来的数据可能包括所有商品数据或者有同名商品数据,所有整个返回结果内可能包含多个同名不同商品id的数据 往 ...
- AWVS(Acunetix)
网络安全渗透测试-AWVS(Acunetix)漏洞扫描工具安装与使用教程 AWVS安装与激活 AWVS简介 AWVS(Acunetix Vulnerability Scanner)是一款网络漏洞扫描工 ...