微信小程序订阅消息开发指南(java)
第一步 准备阶段
1、你得有一个小程序,并且认证了,个人的也行
2、开通订阅消息
小程序后台->功能->订阅消息

3、公共模板库选择一个模板
选择的时候,选择你需要的字段,因为字段有限制

4、我的模板点击详情
详情内容,模板 id 都是需要提供个服务端开发人员的

第二步 编码阶段
小程序端
小程序消息订阅,需要用户确认
1、首先小程序授权登陆获取 code
官网示例:https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html
- wx.login({
- success (res) {
- if (res.code) {
- //发起网络请求
- wx.request({
- url: 'https://example.com/onLogin',
- data: {
- code: res.code
- }
- })
- } else {
- console.log('登录失败!' + res.errMsg)
- }
- }
- })
- // 结果 {errMsg: "login:ok", code: "0a3kK4Ga10Gk3F0oBAHa1mGyRl3kK4Gd"}
复制代码uni-App 示例:https://uniapp.dcloud.net.cn/api/plugins/login.html#login
- uni.login({
- provider: 'weixin', //使用微信登录
- success: function (loginRes) {
- console.log(loginRes)
- }
- });
- // 结果 {errMsg: "login:ok", code: "0a3kK4Ga10Gk3F0oBAHa1mGyRl3kK4Gd"}
复制代码 2、将 code 传给服务端 获取用户唯一标识 openId
3、通过代码起小程序消息订阅界面、用户点击确定ok,小程序工作结束
官方示例:https://developers.weixin.qq.com/miniprogram/dev/api/open-api/subscribe-message/wx.requestSubscribeMessage.html
tmplIds 填写模板 id 即可,最多三个- wx.requestSubscribeMessage({
- tmplIds: [''],
- success (res) {
- console.log(res)
- }
- })
复制代码 4、注意事项:
避免重复拉起用户订阅通知,可以通过微信提供的 getSetting 判断用户是否订阅了,如果没有就拉起。
注意下面是用uniapp写的,方法前缀是uni 如果你小程序代码记得修改 wx 以及提示组件
到此小程序工作结束
- getSetting() {
- uni.getSetting({
- withSubscriptions: true, // 获取用户订阅状态
- success(res) {
- // false 表示用户未订阅改消息
- if (!res.subscriptionsSetting.mainSwitch) {
- this.subscribeMessage();
- } else {
- uni.showToast({
- title: '已订阅',
- icon: 'none'
- })
- }
- }
- })
- },
- subscribeMessage() {
- uni.requestSubscribeMessage({
- tmplIds: ['模板id'],
- success(res) {
- if (res.errMsg === 'requestSubscribeMessage:ok') {
- uni.showToast({
- title: '订阅成功',
- icon: 'none'
- })
- }
- }
- })
- }
复制代码 服务端
微信小程序的 appid 和 secret 小程序后台->开发->开发管理->开发设置->开发者 ID
注意事项:
- http 请求这里使用 apache 的工具类,你也可以使用别的
- 微信消息模板字段 thing 字段有长度限制20,超过会失败
- 以下演示代码,生产环境还需进行优化
1、通过 code 获取用户 open id 官网文档- public String getOpenId(String code) throws IOException {
- CloseableHttpClient httpClient = HttpClientBuilder.create().build();
- Map<String, Object> params = new HashMap<>();
- params.put("appid", Constants.APPLET_APP_ID);
- params.put("secret", Constants.APPLET_SECRET);
- params.put("js_code", code);
- params.put("grant_type", "authorization_code");
- String url = handleParams("https://api.weixin.qq.com/sns/jscode2session", params);
- HttpGet httpGet = new HttpGet(url);
- CloseableHttpResponse response = httpClient.execute(httpGet);
- HttpEntity entity = response.getEntity(); // 响应结果
- return EntityUtils.toString(entity, CharSetType.UTF8.getType());
- }
- public static void main(String[] args) throws IOException {
- HttpUtils httpUtils = new HttpUtils();
- String token = httpUtils.getToken();
- System.out.println(token);
- }
复制代码 响应结果:- {"access_token":"67_u22CQaWq22222222Q4griDE6kiT5hwg7jVxedn8J9te17Az1oWGGxPgB22222229Y4Wm6h_Yzci7-FSDjeH8YG6DsCOYrQXJCWsPXhT6nWbKIWCXfABACID","expires_in":7200}
复制代码 2、通过 appid 和 secret 获取 token 超时 7200 秒 可 redis 缓存 官方文档- public String getToken() throws IOException {
- CloseableHttpClient httpClient = HttpClientBuilder.create().build();
- Map<String, Object> params = new HashMap<>();
- params.put("appid", Constants.APPLET_APP_ID);
- params.put("secret", Constants.APPLET_SECRET);
- params.put("grant_type", "client_credential");
- String url = handleParams("https://api.weixin.qq.com/cgi-bin/token", params);
- HttpGet httpGet = new HttpGet(url);
- CloseableHttpResponse response = httpClient.execute(httpGet);
- HttpEntity entity = response.getEntity(); // 响应结果
- return EntityUtils.toString(entity, CharSetType.UTF8.getType());
- }
复制代码 3、指定用户推送消息结束 官方文档- public String pushMsg(String token) throws IOException {
- CloseableHttpClient httpClient = HttpClientBuilder.create().build();
- Map<String, Object> params = new HashMap<>();
- // 处理微信推送数据结构
- JSONObject mapData = new JSONObject();
- Map<String, Object> map1 = new HashMap<>();
- map1.put("value", "任务名称");
- mapData.put("thing2", map1);
- Map<String, Object> map2 = new HashMap<>();
- map2.put("value", "2022-04-03 10:00:00");
- mapData.put("time3", map2);
- Map<String, Object> map3 = new HashMap<>();
- map3.put("value", "描述信息");
- mapData.put("thing4", map3);
- Map<String, Object> map4 = new HashMap<>();
- map4.put("value", "备注信息");
- mapData.put("thing10", map4);
- Map<String, Object> map5 = new HashMap<>();
- map5.put("value", "任务来源");
- mapData.put("thing11", map5);
- params.put("template_id", "templateId");// 模板 id
- params.put("touser", "openId"); // open id
- params.put("data", mapData); // 数据
- params.put("page", "page"); // 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转
- params.put("miniprogram_state", "trial"); //developer为开发版;trial为体验版;formal为正式版;默认为正式版
- params.put("lang", "zh_CN"); //
- HttpPost httpPost = new HttpPost("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + token);
- httpPost.addHeader("ContentTyp", "application/json");
- // 参数转 JSON 格式
- String json = objToStr(params);
- StringEntity stringEntity = new StringEntity(json, CharSetType.UTF8.getType());
- stringEntity.setContentEncoding(CharSetType.UTF8.getType());
- httpPost.setEntity(stringEntity);
- CloseableHttpResponse response = httpClient.execute(httpPost);
- HttpEntity entity = response.getEntity(); // 响应结果
- return EntityUtils.toString(entity, CharSetType.UTF8.getType());
- }
复制代码 4、完整代码- import com.alibaba.fastjson.JSONObject;
- import com.fasterxml.jackson.core.JsonProcessingException;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.github.chenlijia1111.utils.core.enums.CharSetType;
- import org.apache.http.HttpEntity;
- import org.apache.http.client.methods.CloseableHttpResponse;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.client.methods.HttpPost;
- import org.apache.http.entity.StringEntity;
- import org.apache.http.impl.client.CloseableHttpClient;
- import org.apache.http.impl.client.HttpClientBuilder;
- import org.apache.http.util.EntityUtils;
- import org.jeecg.modules.video.utitls.Constants;
- import java.io.IOException;
- import java.io.UnsupportedEncodingException;
- import java.net.URLEncoder;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Objects;
- import java.util.Set;
- import java.util.stream.Collectors;
- /**
- * @description:
- * @author: Mr.Fang
- * @create: 2023-04-03 17:06
- **/
- public class HttpUtils {
- /**
- * description: 获取token,返回结果为 JSON 自行转 map
- * create by: Mr.Fang
- *
- * @return: java.lang.String
- * @date: 2023/4/3 17:46
- */
- public String getToken() throws IOException {
- CloseableHttpClient httpClient = HttpClientBuilder.create().build();
- Map<String, Object> params = new HashMap<>();
- params.put("appid", Constants.APPLET_APP_ID);
- params.put("secret", Constants.APPLET_SECRET);
- params.put("grant_type", "client_credential");
- String url = handleParams("https://api.weixin.qq.com/cgi-bin/token", params);
- HttpGet httpGet = new HttpGet(url);
- CloseableHttpResponse response = httpClient.execute(httpGet);
- HttpEntity entity = response.getEntity(); // 响应结果
- return EntityUtils.toString(entity, CharSetType.UTF8.getType());
- }
- /**
- * description: 获取 open id,返回结果为 JSON 自行转 map
- * create by: Mr.Fang
- *
- * @param: [code]
- * @return: java.lang.String
- * @date: 2023/4/3 17:46
- */
- public String getOpenId(String code) throws IOException {
- CloseableHttpClient httpClient = HttpClientBuilder.create().build();
- Map<String, Object> params = new HashMap<>();
- params.put("appid", Constants.APPLET_APP_ID);
- params.put("secret", Constants.APPLET_SECRET);
- params.put("js_code", code);
- params.put("grant_type", "authorization_code");
- String url = handleParams("https://api.weixin.qq.com/sns/jscode2session", params);
- HttpGet httpGet = new HttpGet(url);
- CloseableHttpResponse response = httpClient.execute(httpGet);
- HttpEntity entity = response.getEntity(); // 响应结果
- return EntityUtils.toString(entity, CharSetType.UTF8.getType());
- }
- /**
- * description: 消息推送 返回结果为 JSON 自行转 map;token 调用 getToken获取
- * create by: Mr.Fang
- *
- * @param: [token]
- * @return: java.lang.String
- * @date: 2023/4/3 17:46
- */
- public String pushMsg(String token) throws IOException {
- CloseableHttpClient httpClient = HttpClientBuilder.create().build();
- Map<String, Object> params = new HashMap<>();
- // 处理微信推送数据结构
- JSONObject mapData = new JSONObject();
- Map<String, Object> map1 = new HashMap<>();
- map1.put("value", "任务名称");
- mapData.put("thing2", map1);
- Map<String, Object> map2 = new HashMap<>();
- map2.put("value", "2023-04-03 12:00:00");
- mapData.put("time3", map2);
- Map<String, Object> map3 = new HashMap<>();
- map3.put("value", "描述信息");
- mapData.put("thing4", map3);
- Map<String, Object> map4 = new HashMap<>();
- map4.put("value", "备注系信息");
- mapData.put("thing10", map4);
- Map<String, Object> map5 = new HashMap<>();
- map5.put("value", "抖音");
- mapData.put("thing11", map5);
- params.put("template_id", "templateId");// 模板 id
- params.put("touser", "openId"); // open id
- params.put("data", mapData); // 数据
- params.put("page", "page"); // 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转
- params.put("miniprogram_state", "trial"); //developer为开发版;trial为体验版;formal为正式版;默认为正式版
- params.put("lang", "zh_CN"); //
- HttpPost httpPost = new HttpPost("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + token);
- httpPost.addHeader("ContentTyp", "application/json");
- // 参数转 JSON 格式
- String json = objToStr(params);
- StringEntity stringEntity = new StringEntity(json, CharSetType.UTF8.getType());
- stringEntity.setContentEncoding(CharSetType.UTF8.getType());
- httpPost.setEntity(stringEntity);
- CloseableHttpResponse response = httpClient.execute(httpPost);
- HttpEntity entity = response.getEntity(); // 响应结果
- return EntityUtils.toString(entity, CharSetType.UTF8.getType());
- }
- /**
- * description: 对象转 字符串
- * create by: Mr.Fang
- *
- * @param: [obj]
- * @return: java.lang.String
- * @date: 2023/4/3 17:45
- */
- public static String objToStr(Object obj) {
- ObjectMapper objectMapper = new ObjectMapper();
- if (Objects.nonNull(obj)) {
- try {
- String jsonStr = objectMapper.writeValueAsString(obj);
- return jsonStr;
- } catch (JsonProcessingException var2) {
- var2.printStackTrace();
- }
- }
- return null;
- }
- /**
- * description: map 转 URL 地址拼接
- * create by: Mr.Fang
- *
- * @param: [url, params]
- * @return: java.lang.String
- * @date: 2023/4/3 17:45
- */
- public String handleParams(String url, Map<String, Object> params) {
- if (params.size() != 0) {
- Set<Map.Entry<String, Object>> entries = params.entrySet();
- String paramsString = entries.stream().map((e) -> {
- try {
- StringBuilder sb = new StringBuilder();
- sb.append(URLEncoder.encode(e.getKey(), CharSetType.UTF8.getType()));
- sb.append("=");
- if (Objects.nonNull(e.getValue())) {
- sb.append(URLEncoder.encode(e.getValue().toString(), CharSetType.UTF8.getType()));
- }
- return sb.toString();
- } catch (UnsupportedEncodingException var2) {
- var2.printStackTrace();
- return null;
- }
- }).collect(Collectors.joining("&"));
- return url + "?" + paramsString;
- }
- return url;
- }
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |