小程序的消息模版
点击事件中添加
tmplIds:消息模版id
uni.requestSubscribeMessage({
tmplIds:['jSyQfAWJ_zeyemzNWetSVHHqrW-RrFjpTUOnejVTvms'],
success: res => {
console.log(res)
},
fail: res=>{
console.log(res)
}
});
点击按钮会调用授权框,点击允许即可
前端的部分基本就完成了,消息推送还是主要在后端
/**
* 调用微信开放接口subscribeMessage.send发送订阅消息(固定模板的订阅消息)
* POST https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN
*/
public static void sendSubscribeMessage(String toUserOpenId){
HttpURLConnection httpConn = null;
InputStream is = null;
BufferedReader rd = null;
String accessToken = null;
String str = null;
try
{
//获取token 小程序全局唯一后台接口调用凭据
accessToken = getWxToken();
JSONObject xmlData = new JSONObject();
xmlData.put("touser", toUserOpenId);//接收者(用户)的 openid
xmlData.put("template_id", "jSyQfAWJ_zeyemzNWetSVHHqrW-RrFjpTUOnejVTvms");//所需下发的订阅模板id
xmlData.put("page", "pages/index/index");//点击模板卡片后的跳转页面,仅限本小程序内的页面
xmlData.put("miniprogram_state", "developer");//跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
xmlData.put("lang", "zh_CN");//进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN返回值
/**
* 订阅消息参数值内容限制说明
thing.DATA:20个以内字符;可汉字、数字、字母或符号组合
time.DATA:24小时制时间格式(支持+年月日),支持填时间段,两个时间点之间用“~”符号连接
*/
JSONObject data = new JSONObject();
//取餐号
JSONObject character_string4 = new JSONObject();//character_string4必须和模板消息的字段id一致,以下同样,必须要一致,注意时间格式,详情看图二
character_string4.put("value", "测试消息标题");
data.put("thing2", character_string4);
//购买商品
JSONObject thing5 = new JSONObject();
thing5.put("value", "2024-09-03");
data.put("date5", thing5);
xmlData.put("data", data);//小程序模板数据
System.out.println("发送模板消息xmlData:" + xmlData);
URL url = new URL(
"https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token="
+ accessToken);
httpConn = (HttpURLConnection)url.openConnection();
httpConn.setRequestProperty("Host", "https://api.weixin.qq.com");
// httpConn.setRequestProperty("Content-Length", String.valueOf(xmlData.));
httpConn.setRequestProperty("Content-Type", "text/xml; charset=\"UTF-8\"");
httpConn.setRequestMethod("POST");
httpConn.setDoInput(true);
httpConn.setDoOutput(true);
OutputStream out = httpConn.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out, "UTF-8");
osw.write(xmlData.toString());
osw.flush();
osw.close();
out.close();
is = httpConn.getInputStream();
rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
while ((str = rd.readLine()) != null)
{
System.out.println("返回数据:" + str);
}
}
catch (Exception e)
{
System.out.println("发送模板消息失败.." + e.getMessage());
}
}
/**
* 用于获取access_token
*
* @return access_token
* @throws Exception
*/
public static String getWxToken() {
String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + API_KEY
+ "&secret=" + SECRET_KEY;
String body = HttpRequest.post(requestUrl).execute().body();
JSONObject jsonObject = JSONObject.parseObject(body);
String accesstoken = jsonObject.getString("access_token");
return accesstoken;
}
把这个方法里面的API_KEY和SECRET_KEY换成你自己的小程序的
测试方法,传入用户的openId
public static void main(String[] args) {
sendSubscribeMessage("olEns4hliIuhhgbLx0WZ31Uhv630");
}
用户的openId获取是在小程序登录那步拿到的,后端会存起来
uni.login({
success(res2) {
getUnionId({
code: res2.code
}).then(res => {})
})
这里的getUnionId方法是后端的
@ResponseBody
@RequestMapping(value = "/getUnionId", method = RequestMethod.POST, consumes = {"application/json;charset=UTF-8"})
@NoLoginRequired
public R getUnionId(@RequestBody JSONObject data) {
if (StrUtil.isBlank(data.getString("code"))) {
return R.error("code不能为空");
}
// 解析unionId
StringBuffer url = new StringBuffer();
url.append("https://api.weixin.qq.com/sns/jscode2session?appid=").append(QRCodeUtil.API_KEY)
.append("&secret=").append(QRCodeUtil.SECRET_KEY).append("&js_code=").append(data.getString("code"))
.append("&grant_type=authorization_code");
try {
String body = HttpRequest.get(url.toString()).execute().body();
JSONObject parseObject = JSONObject.parseObject(body);
if (parseObject.containsKey("unionid")) {
return R.ok(parseObject.getString("unionid"));
} else {
return R.error("提交失败");
}
} catch (Exception e) {
return R.error("提交失败");
}
}
由于我公司的一直使用的unionId,这个parseObject对象里面包含openId,也可以取到
最后调用成功的界面
这里要注意的是,消息只能推送一次,要想推送多次,必须申请长期模版,不然每次推送完后就无法再推送,要想再次推送必须小程序那边再次订阅一次消息,很恶心,现在的长期模版貌似不好申请。