前言:微信官方提供了订阅消息的服务,开发者需要在微信公众平台申请订阅消息的模板,然后用户点击按钮,同意订阅该消息requestSubscribeMessage,我们就可以在后台调用微信官方提供的接口subscribeMessage.send在任何时间给发送一次/无限次订阅提醒。
在微信公众平台申请订阅消息的模板
微信公众平台
消息模板可以分为两类:一次性的(用户允许一次可以发送一次),无限次的(用户允许一次可以一直发送),我们可以去公共模板库选择我们需要的模板,如果在公共模板库没有我们想要的模板,我们就可以申请模板。
申请成功后我们可以获取到该模板的id,之后要用
用户点击按钮,请求用户同意订阅消息
requestSubscribeMessage
当用户进行某个操作之后,我们需要在某个时间提醒用户,我们就可以调用该api,
举个例子:当用户点击付费成为会员后,我们就可以调用该api申请订阅提醒
//就这么简单
//其中tmplIds就是我们刚才获取的订阅消息模板的id,最多写上三个
wx.requestSubscribeMessage({
tmplIds: ['NzwxqklTwH2M5zKlfA3Ful-qxoq7FADxCkYv3Dqq1Mk'],
})
调用该函数有许多需要注意的点
- 只有在用户点击触发的监听函数中才能调用该api
- 注意:当用户点击(不在询问直接同意)时,并不意味着你可以无限次的发送订阅消息,点击这个只是说在需要用户同意时不弹出窗口,直接同意,但是你还是要申请用户同意的。
在任何时间发送一次订阅提醒
subscribeMessage.send
在用户同意后我们就可以发送提醒了。这一步应该是在后台操作,因为用户不会一直开着小程序。在此我使用java来做,我们重点介绍参数的含义,在最后我会附上完整java代码
该接口所需的参数
- 我们重点介绍每一个参数的含义
{
"touser": "xxxx",//用户的openid
"template_id": "NzwxqklTwH2M5zKlfA3Ful-qxoq7FADxCkYv3Dqq1Mk",//订阅消息的id
"page": "pages/test/test/test",//消息发出后,用户可以点击进入小程序,我们设置他要跳转的路径
"miniprogram_state": "developer",//小程序此时的状态,developer:开发
"lang": "zh_CN",//语言,默认为中文
"data": {//这是设置订阅消息的参数
"thing1": {
"value": "个人会员"
},
"date2": {
"value": "2015年01月05日"
},
"thing3": {
"value": "您的会员即将到期"
}
}
}
- 首先我们要通过auth.getAccessToken获取access_token,我是用RestTemplate发送的请求
TokenResult tokenResult = get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wxa6095c87cb44915a&secret=d71751ebd56b4d87beeb28c52c5fb098");
发送get请求的方法
//get
public TokenResult get(String url){
RestTemplate restTemplate = new RestTemplate();
TokenResult tokenResult = restTemplate.getForObject(url, TokenResult.class);
return tokenResult;
}
参数返回的接收类
@Data
@ToString
public class TokenResult {
private String access_token;
private String expires_in;
}
- 然后使用发送post请求,给会员进行提醒,这里我使用jackson把json字符串转换成了map
String token = tokenResult.getAccess_token();
String data = "{\"touser\": \"orgCu5UONbG70W002r_-379xmzkk\",\"template_id\": \"NzwxqklTwH2M5zKlfA3Ful-qxoq7FADxCkYv3Dqq1Mk\",\"page\": \"/pages/test/test/test\",\"miniprogram_state\": \"developer\",\"lang\": \"zh_CN\",\"data\": {\"thing1\": {\"value\": \"个人会员\"},\"date2\": {\"value\": \"2015年01月05日\"},\"thing3\": {\"value\": \"您的会员即将到期\"}}}";
ObjectMapper objectMapper = new ObjectMapper();
TipResult tipResult = null;
try {
tipResult = post("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + token,objectMapper.readValue(data, Map.class));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
System.out.println(tipResult);
发送post请求的方法
//post
public TipResult post(String url, Map<String,Object> data){
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity entity = new HttpEntity(data, headers);
TipResult tipResult = restTemplate.postForObject(url, entity,TipResult.class);
return tipResult;
}
返回数据的接收类
@Data
@ToString
public class TipResult {
private String errcode;
private String errmsg;
private String msgid;
}
- 注意:虽然这是个post请求,但是access_token需要写在url上,并且不用写 header: {“Content-Type”: “application/x-www-form-urlencoded”};
完整java代码
import com.chunxiao.yixunditu.entity.TipResult;
import com.chunxiao.yixunditu.entity.TokenResult;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;
import java.util.Map;
class DemoApplicationTests {
@Test
void contextLoads() throws JsonProcessingException {
TokenResult tokenResult = get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wxa6095c87cb44915a&secret=d71751ebd56b4d87beeb28c52c5fb098");
String token = tokenResult.getAccess_token();
String data = "{\"touser\": \"orgCu5UONbG70W002r_-379xmzkk\",\"template_id\": \"NzwxqklTwH2M5zKlfA3Ful-qxoq7FADxCkYv3Dqq1Mk\",\"page\": \"/pages/test/test/test\",\"miniprogram_state\": \"developer\",\"lang\": \"zh_CN\",\"data\": {\"thing1\": {\"value\": \"个人会员\"},\"date2\": {\"value\": \"2015年01月05日\"},\"thing3\": {\"value\": \"您的会员即将到期\"}}}";
ObjectMapper objectMapper = new ObjectMapper();
TipResult tipResult = null;
try {
tipResult = post("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + token,objectMapper.readValue(data, Map.class));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
System.out.println(tipResult);
}
//post
public TipResult post(String url, Map<String,Object> data){
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity entity = new HttpEntity(data, headers);
TipResult tipResult = restTemplate.postForObject(url, entity,TipResult.class);
return tipResult;
}
//get
public TokenResult get(String url){
RestTemplate restTemplate = new RestTemplate();
TokenResult tokenResult = restTemplate.getForObject(url, TokenResult.class);
return tokenResult;
}
}
@Data
@ToString
public class TokenResult {
private String access_token;
private String expires_in;
}
@Data
@ToString
public class TipResult {
private String errcode;
private String errmsg;
private String msgid;
}