微信小程序消息订阅Java

2023-10-31

前言

编写日期 : 2022-11-04

写这篇文章原因

公司给政府做一个订餐系统,需要在员工在小程序上发起订餐后经过部门领导和书记的审批后,再由食堂确认订餐结果。在订餐审批单在各个节点流转的过程中,需要给每一个节点的审批人发送微信订阅消息手机短信,通知订餐流程所在节点的人有新的订餐审批单需要审批,最终将订餐结果通过微信订阅消息手机短信反馈给订餐人员。手机短信那块后端很好整,没啥问题,但是这个微信小程序发送订阅消息这个没有整过,有点懵,但不慌。本来这个微信的消息订阅前端已经做好了,但是架构师说这块的逻辑后端做,所以我就来搞这个了。

官方文档说明

链接 :>>>微信小程序发送订阅消息官方文档 <<<

调用方式 HTTPS 调用
POST https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN

请求参数

属性 类型 类型 说明
access_token String 需要用小程序的appid和密钥secret去调用 官方 接口获取
template_id String 所需下发的订阅模板id
page String 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转
touser String 接收者(用户)的 openid,
data String 模板内容,格式形如 { “key1”: { “value”: any }, “key2”: { “value”: any } }的object
miniprogram_state String 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
lang String 进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN

申请的微信订阅消息模板

在这里插入图片描述

访问接口传参示例

{
  "touser": "OPENID",
  "template_id": "TEMPLATE_ID",
  "page": "index",
  "miniprogram_state":"developer",
  "lang":"zh_CN",
  "data": {
      "thing1": {
          "value": "金先生"
      },
      "time2": {
          "value": "2020-05-01"
      },
      "phrase13": {
          "value": "成功"
      } ,
      "thing17": {
          "value": "xx地方"
      }
  }
}

代码

需要用到的当前小程序的参数

  • appid 小程序的appid
  • secret 小程序密钥
  • TempId 申请的订阅消息模板id

获取access_token


	@Value("${wx.xiaochengxu.appid}")
    private String appid;
    @Value("${wx.xiaochengxu.secret}")
    private String secret;

 /**
  *	@param appid secret
  */
  	@Override
	public String getAccessToken() {
	        HttpResponse response = HttpRequest.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret + "").execute();
	        JSONObject tokenJson = JSON.parseObject(response.body());
	        String accessToken =  tokenJson.get("access_token").toString();
	        return accessToken;
	    }

发送订阅消息

请求参数
public class SendMsgBody {

    /*接收者(用户)的 openid*/
    private String touser;

    /*所需下发的订阅模板id*/
    private String template_id;

    /*点击消息后跳转的页面*/
    private String page;

    /*跳转小程序类型:developer 为开发版;trial 为体验版;formal 为正式版;默认为正式版*/
    private String miniprogram_state="developer";

    /*进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN返回值*/
    private String lang="zh_CN";

    /*模板数据,这里定义为object是希望所有的模板都能使用这个消息配置*/
    private Object data;


    public String getTouser() {
        return touser;
    }
    public void setTouser(String touser) {
        this.touser = touser;
    }
	//template_id、page、data ==>getset
}
请求参数中的data
public class MsgSuccess {

    /*姓  名*/
    private Map<String, String> thing1;

    /*预约时间*/
    private Map<String, String> time2;

    /*预约状态*/
    private Map<String, String> phrase13;

    /*预约地点*/
    private Map<String, String> thing17;

    public Map<String, String> getThing1() {
        return thing1;
    }

    public Map<String, String> getTime2() {
        return time2;
    }

    public Map<String, String> getPhrase13() {
        return phrase13;
    }

    public Map<String, String> getThing17() {
        return thing17;
    }

    public void setThing1(String thing1) {
        this.thing1 = getFormat(thing1);
    }

    public void setTime2(String time2) {
        this.time2 = getFormat(time2);
    }

    public void setPhrase13(String phrase13) {
        this.phrase13 = getFormat(phrase13);
    }

    public void setThing17(String thing17) {
        this.thing17 = getFormat(thing17);
    }

    public HashMap<String, String> getFormat(String str) {
        return new HashMap<String, String>() {{
            put("value", str);
        }};
    }

    @Override
    public String toString() {
        return "DCSuccess{" +
                "thing1=" + thing1 +
                ", time2=" + time2 +
                ", phrase13=" + phrase13 +
                ", thing17=" + thing17 +
                '}';
    }
}
发送消息
	@Value("${wx.xiaochengxu.sendMsg.successTempId}")
    private String tempId;//模板id

	@Override
	public void wxSendMsgSuccess(String openId, Map<String, String> node) {
	        String accessToken = getAccessToken() ;
	
	        //先填充请求体中data的数据
	        MsgSuccess msgSuccess = new MsgSuccess ();
	        msgSuccess .setThing1(node.get("thing1"));
	        msgSuccess .setTime2(node.get("time2"));
	        msgSuccess .setPhrase13("成功");
	        msgSuccess .setThing17(node.get("thing17"));
	
			//请求参数数据填充
	        SendMsgBody sendMsgBody = new SendMsgBody();
	        sendMsgBody.setTouser(openId);
	        sendMsgBody.setTemplate_id(tempId);
	        sendMsgBody.setData(msgSuccess);
	
	        String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken;
	
	        //发送请求
	        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
	        HttpHeaders headers = new HttpHeaders();
	        headers.setContentType(type);
	        HttpEntity<SendMsgBody> httpEntity = new HttpEntity<>(sendMsgBody, headers);
	        JSONObject jsonResult = restTemplate.postForObject(url, httpEntity, JSONObject.class);
	        JSONObject responseData = jsonResult ;
	
	        Integer errorCode = responseData.getInteger("errcode");
	        String errorMessage = responseData.getString("errmsg");
	        if (errorCode == 0) {
	            log.info("订餐通知消息发送成功");
	        } else {
	            log.info("订餐通知消息发送失败,errcode:{},errorMessage:{}", errorCode, errorMessage);
	        }
	    }
调用
    @GetMapping("wxSendSuccess")
    @ApiOperation(value = "微信小程序发送订阅消息通知")
    public boolean wxSendSuccess(){
        String openId = "oks*******************Gk";
        HashMap<String, String> map = new HashMap<>();
        map.put("thing1","***");
        map.put("time2","2022-11-03 12:13");
        map.put("thing17","405");
        return wxService.wxSendMsgSuccess(openId,map);
    }

结果

在这里插入图片描述

总结

咱们这个消息的订阅前端授权一次后,咱们也就只能发送成功一次,在接收订阅消息的用户没有同意接收订阅信息的时候,我们调用接口给用户发送订阅消息基本都会被拒绝。请求结果如下:

errcode:43101,errorMessage:user refuse to accept the msg rid: 6363495-2267c4de-7aa0fab1

如果你的小程序没有进行政府 医疗等认证,那你就不能长期订阅,所以每一次订阅消息的发送都需要接收方的一次授权,并且接收放的授权次数是可以累加的,比如说这次订阅了你没发订阅消息,下次再继续订阅,你就可以连续发两条订阅成功。但是在特殊情况下小程序方也会清楚所有的授权次数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

微信小程序消息订阅Java 的相关文章

随机推荐

  • 浏览器页面后退,重新运行ajax

    问题描述 在浏览器页面后退时 也就是说你点击链接到一个页面 然后又点击后退按钮回到刚才的页面 结果发现jQuery的ajax GET请求不再执行了 解决方法 禁用ajax缓存 ajaxSetup cache false 吐槽 为了解决这个问
  • java中的String

    Java中的String类是一种复合数据类型 比较String类的是否相等也有2种办法 和equals 两种 String是一个系统定义的类 不是基本数据类型 有关字符串处理的方法非常多 有时候两个 一样 的字符串做相等的比较运算时会得到t
  • 华为OD机试真题-查找充电设备组合【2023Q1】【JAVA、Python、C++】

    题目描述 某个充电站 可提供n个充电设备 每个充电设备均有对应的输出功率 任意个充电设备组合的输出功率总和 均构成功率集合P的1个元素 功率集合P的最优元素 表示最接近充电站最大输出功率p max的元素 输入描述 输入为3行 第1行为充电设
  • 时序预测

    时序预测 MATLAB实现Bayes贝叶斯优化LSTM 长短期记忆神经网络 时间序列预测 预测效果一览
  • React - Websocket

    组件didMount调用 Store createWebSocket Math random Store url ws window backend server slice 7 apronMapWebsocket 这个要与后端提供的相同
  • C++函数重载、重写与重定义

    演示代码 include
  • 探索Java8——CompletableFuture: 组合式异步编程

    文章目录 Future接口 Future接口的局限性 使用 CompletableFuture 使用并行流对请求进行并行操作 使用 CompletableFuture 发起异步请求 如果你的意图是实现并发 而非并行 或者你的主要目标是在同一
  • https到底是如何防篡改的

    1 前言 https是一个老生常谈的话题了 也是面试过程种经常甚至必然会问到的一个问题 但当问到https为什么安全的时候 很多人的回答就是简单的回一句 因为他加密了 然后就没然后了 你也相当于啥都没回答出来 2 我为什么要写这篇文章呢 网
  • select底部增加固定按钮

  • 基于SSM的校园快递一站式服务系统设计与实现

    末尾获取源码 开发语言 Java Java开发工具 JDK1 8 后端框架 SSM 前端 采用JSP技术开发 数据库 MySQL5 7和Navicat管理工具结合 服务器 Tomcat8 5 开发软件 IDEA Eclipse 是否Mave
  • 统计学R语言 第五章课后练习 置信区间

    5 1 计算一个总体均值的置信区间 大样本 gt exercise5 1 lt read csv D 289250 统计学 基于R 第4版 例题和习题数据 统计学 基于R 第4版 例题和习题数据 公开资源 exercise chap05 e
  • 用python网络爬虫爬取英雄联盟英雄图片

    用python爬虫爬取lol皮肤 这也用python网络爬虫爬取lol英雄皮肤 忘了是看哪个大神的博客 由于当时学了下就一直放在这儿 现在又才拿出来 再加上马上要考二级挺忙的 代码基本上是没改 还望大神原谅 本人小白 没学过Python 只
  • Pay Cycle related record

    select delete from sysadm ps pycycl stat where pay cycle ACH and pay cycle seq num gt 30 select delete from sysadm ps PY
  • Golang初入编程-踩坑笔记(3)- 并发,优雅关闭

    主函数也是线程 在不使用sync WaitGroup的情况下 需要main等待goroutine完成 不然main完成就没了 sync是synchronizing 使 同步 的缩写 wg done 最好加defer chan需要make c
  • Sqli-labs之Less-26和Less-26a

    Less 26 GET 基于错误 您所有的空格和注释都属于我们 根据提示我们知道这一关过滤了空格和注释 实际上过滤的远远不止这些 我们来看下源码 可以确认一下 id 231 确认过滤了 id or1 确认过滤了or id 1 确认过滤了多行
  • C语言 fstat函数

    系列文章目录 文章目录 系列文章目录 前言 一 stat系统调用 二 fstat 1 功能 2 相关函数 3 头文件 4 函数声明 5 描述 6 返回值 7 例子 三 struct stat结构体 前言 一 stat系统调用 stat系统调
  • Linux学习之expect操作详解

    一 expect安装介绍 1 expect命令安装 安装语句 yum install expect 2 expect命令含义 expect是一种脚本语言 它能够代替人工实现与终端的交互 主要应用于执行命令和程序时 系统以交互形式要求输入指定
  • Python全栈开发【基础-03】编程语言的分类

    专栏介绍 本专栏为Python全栈开发系列文章 技术包括Python基础 函数 文件 面向对象 网络编程 并发编程 MySQL数据库 HTML JavaScript CSS JQuery bootstrap WSGI Django Flas
  • usb鼠标驱动(一)

    Linux USB 鼠标驱动程序详解 注册一个usb driver 这个drvier不是usb设备driver 而是接口driver use a define to avoid include chaining to get THIS MO
  • 微信小程序消息订阅Java

    前言 编写日期 2022 11 04 写这篇文章原因 公司给政府做一个订餐系统 需要在员工在小程序上发起订餐后经过部门领导和书记的审批后 再由食堂确认订餐结果 在订餐审批单在各个节点流转的过程中 需要给每一个节点的审批人发送微信订阅消息和手