首先我们要获取小程序的私有模板
data结构 ->
例子:
public static void main(String[] args) {
//"订单号:{{character_string1.DATA}}\n商品名称:{{thing2.DATA}}\n发货时间:{{date5.DATA}}\n快递单号:{{character_string4.DATA}}\n快递公司:{{thing7.DATA}}\n",
String content = "订单号:{{character_string1.DATA}}\n商品名称:{{thing2.DATA}}\n发货时间:{{date5.DATA}}\n快递单号:{{character_string4.DATA}}\n快递公司:{{thing7.DATA}}\n";
String[] split = content.split("\n");
List<KeyWordParamVO> list = new ArrayList<>();
for (int i = 0; i < split.length; i++) {
if (StringUtils.isBlank(split[i])){
continue;
}
KeyWordParamVO keyWordParamVO = new KeyWordParamVO();
String[] keyName = split[i].split(":");
//组装给前端用
keyWordParamVO.setParamKey(keyName[0]);
//后台使用占位符,默认给个空串
keyWordParamVO.setParamValue("");
//排序
keyWordParamVO.setParamSort(i);
int index = keyName[1].indexOf(".");
String substring = keyName[1].substring(2, index);
//请求的key
keyWordParamVO.setRequestKey(substring);
list.add(keyWordParamVO);
}
String json = JSONObject.toJSONString(list);
System.out.println(json);
}
根据需求后台拉取模板存入数据库
public CommonResult refreshTemplate() {
//公众号微信token
SysConfig sysConfig = sysConfigMapper.selectByPrimaryKey(SysConfigConstants.WX_TOKEN);
String wxToken = sysConfig.getParamValue();
//调用微信url获取模板
String resultStr = HttpClientUtil.doGet(GET_ALL_PRIVATE_TEMPLATE + wxToken, null);
log.info("===============获取微信公众号推送模板返回==============={}",resultStr);
Map map = JSONObject.parseObject(resultStr, Map.class);
if (!map.get("errcode").equals(0)){
throw new ApiException(resultStr);
}
List<SubscriptionTemplateResponse> pushTemplateResponses = new ArrayList<>();
try {
// String json = JSONObject.toJSONString(map.get("data"));
String json = String.valueOf(map.get("data"));
pushTemplateResponses = JSONObject.parseArray(json, SubscriptionTemplateResponse.class);
} catch (Exception e) {
e.printStackTrace();
throw new ApiException(resultStr);
}
//查询数据库中是否有这写模板
if (CollectionUtils.isEmpty(pushTemplateResponses)){
return CommonResult.failed("微信公众号没有模板");
}
//插入的集合
List<WxSubscriptionTemplate> templates = new ArrayList<>();
List<WxSubscriptionTemplate> subscroptionTemplateList = wxSubscroptionTemplateMapper.selectAll();
List<String> collect = subscroptionTemplateList.stream().map(WxSubscriptionTemplate::getTemplateId).collect(Collectors.toList());
pushTemplateResponses.stream()
.filter(x -> !collect.contains(x.getPriTmplId()))
.forEach(item -> {
WxSubscriptionTemplate template = packageTemplate(item);
templates.add(template);
});
if (!CollectionUtils.isEmpty(templates)) {
wxSubscroptionTemplateMapper.insertBatch(templates);
}
return CommonResult.success();
}
packageTemplate方法根据自己需求包装模板参数,和例子差不多
数据库有了模板就可以做埋点推送了,先看看推送文档
推送例子:
/**
* 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } }的object
*
* "data": {
* "thing1": {
* "value": "商品名称"
* },
* "amount3": {
* "value": "66"
* },
* "thing4": {
* "value": "TIT创意园"
* } ,
* "date5": {
* "value": "2019-10-14 27:34:21"
* },
* "character_string6": {
* "value": "Q123"
* }
* }
*/
public static String pushMsgToServiceNotifications(PushMsgToSNRequest request) {
// String accessToken = wxParamsService.getAccessToken();
String accessToken = "60_o05Q_Hv48p_Ygy4OU6Pw-tiQ-UIXEl4j8ZAuN5MawJ9uPTOiFvvKEQmpoGZSsuPaXAR8iYSGUqnTSl1IVlAJHTwO36wU9dfl20iEro4u6w68CtUtXyrp9-MiMFk7B3ZdumFf9WtTxZ9W9aNQTWMgAAAORH";
String result = HttpClientUtil.doPostJson(SUBSCRIBE_SEND_URL + accessToken, JSONObject.toJSONString(request));
logger.info("==============小程序订阅消息推送到微信服务通知-返回==============={}", result);
return result;
}
public static void main(String[] args) {
String data = "[{\"paramKey\":\"订单号\",\"paramSort\":0,\"paramValue\":\"Q123456789\",\"requestKey\":\"character_string1\"},{\"paramKey\":\"商品名称\",\"paramSort\":1,\"paramValue\":\"测试001\",\"requestKey\":\"thing2\"},{\"paramKey\":\"发货时间\",\"paramSort\":2,\"paramValue\":\"2019-10-14 27:34:21\",\"requestKey\":\"date5\"},{\"paramKey\":\"快递单号\",\"paramSort\":3,\"paramValue\":\"supper666\",\"requestKey\":\"character_string4\"},{\"paramKey\":\"快递公司\",\"paramSort\":4,\"paramValue\":\"物流公司\",\"requestKey\":\"thing7\"}]";
PushMsgToSNRequest pushMsgToSNRequest = new PushMsgToSNRequest();
pushMsgToSNRequest.setTouser("open_id");
pushMsgToSNRequest.setTemplate_id("template_id");
pushMsgToSNRequest.setPage("index");
pushMsgToSNRequest.setData(mapBuild(JSONObject.parseArray(data, KeyWordParamVO.class)));
String json = JSONObject.toJSONString(pushMsgToSNRequest);
System.out.println(json);
String result = pushMsgToServiceNotifications(pushMsgToSNRequest);
System.out.println(result);
}
public static Map<String, Map<String, String>> mapBuild(List<KeyWordParamVO> list) {
Map<String, Map<String, String>> map = new HashMap<>();
list.forEach(item -> {
map.put(item.getRequestKey(), new HashMap() {
{
put("value", item.getParamValue());
}
});
});
return map;
}
当然如果埋点比较少也可以直接写死
public void pushCardReminder(String openId){
Map params = Maps.newHashMap();
params.put("touser",openId);
params.put("template_id", WxParamsService.CARD_REMINDER);
String page = "/packageA/pages/webviewH5/webview?url=https://weapp.quanminyanxuan.com/pages/integralCenter/gold.html";
params.put("page",page);
params.put("miniprogram_state", wxParamsService.MINIPROGRAM_STATE);
Map<String,Map> keywords = Maps.newHashMap();
//卡劵名称
keywords.put("thing4",new HashMap(){
{ put("value","卡劵当钱花"); }
});
//卡劵类型
keywords.put("thing5",new HashMap(){
{ put("value", "换购劵"); }
});
//卡劵金额
keywords.put("amount3",new HashMap(){
{ put("value","5000"); }
});
//卡劵金额
keywords.put("thing2",new HashMap(){
{ put("value","送您5000卡券已到账,可直接换购商品"); }
});
params.put("data",keywords);
String json = getPushSubscriptionMessage(params);
logger.info("卡劵到账提醒,[{}]",json);
}
最后就是碰到的一个坑,文档上面也没有写,就是服务通知key对应的value是有参数限制的。比如说你传的key是thing类型那么你传给微信的参数将不能超过20个字符。
最后推送用户的open_id必须得先授权,有了权限参数没问题才能收到服务通知。