当前位置: 首页 > news >正文

小程序一次性订阅消息(消息通知):java服务端实现

文章目录

  • 引言
  • 一、消息订阅
    • 1.1 小程序订阅消息功能介绍
    • 1.2 消息分类
      • 1.2.1 新版一次性订阅消息Beta
      • 1.2.2 一次性订阅消息(用户通过弹窗订阅)
      • 1.2.3 长期订阅消息(用户通过弹窗订阅)
      • 1.2.4 设备订阅消息
  • 二、获取模板ID
    • 1.登录[微信公众平台](https://mp.weixin.qq.com)开通订阅消息
    • 2.在微信公众平台手动配置获取模板 ID:
  • 三、获取接口调用凭据wx_access_token
    • 1、接口说明
      • 接口英文名:getAccessToken
      • 功能描述:
    • 2、调用方式
      • HTTPS 调用
      • 请求参数
    • 3、Java代码实现
  • 四、发送消息
    • 1、接口说明
      • 接口英文名:sendMessage
      • 功能描述:
      • 调用方式
        • HTTPS 调用
      • 请求参数
      • 返回参数
    • 2、注意点(需要前端配合)
    • 3、发送消息的Java代码实现
      • 1)封装前端引导用户授权所需的参数:
      • 2)封装后台调用微信官方API所需的参数:
      • 3)编写发送消息的内容:
      • 4)获取用户的openid
      • 5)编写发送消息的函数:
  • 总结

引言

最近在开发小程序服务端代码,需要实现一个能够实现消息通知的接口业务,记录一下整个接口业务的开发过程。

一、消息订阅

先附上微信官方文档:订阅消息

1.1 小程序订阅消息功能介绍

消息能力是小程序能力中的重要组成,我们为开发者提供了订阅消息能力,以便实现服务的闭环和更优的体验。
订阅消息推送位置:服务通知
订阅消息下发条件:开发者通过一定的方式触发用户主动订阅
订阅消息卡片跳转能力:点击查看详情可跳转至该小程序的页面

1.2 消息分类

1.2.1 新版一次性订阅消息Beta

新版一次性订阅消息是一种无需用户在弹窗中主动订阅即可向用户下发消息的能力,用户的订阅方式为:
当用户在小程序中进行微信支付后,开发者可将微信支付订单号作为 code 向用户下发服务通知
开发者可在小程序中将触发服务的 button 组件的 open-type 的值设置为 liveActivity,当用户点击 button 后可获得 code ,后续可使用此 code 向用户下发服务通知
此下发方式由平台定义模版,开发者根据自身业务选择模版进行接入。
详见订阅消息接入 Beta开发指南文档。

1.2.2 一次性订阅消息(用户通过弹窗订阅)

一次性订阅消息用于解决用户使用小程序后,后续服务环节的通知问题。
开发者在小程序中调用 requestSubscribeMessage 接口后,将向用户展示弹窗,用户可打开自己想要接受的消息开关。用户订阅后,开发者可不限时间地下发一条对应的服务消息;每条消息可单独订阅或退订。
详见小程序订阅消息开发指南文档。

1.2.3 长期订阅消息(用户通过弹窗订阅)

一次性订阅消息可满足小程序的大部分服务场景需求,但线下公共服务领域存在一次性订阅无法满足的场景,如航班延误,需根据航班实时动态来多次发送消息提醒。为便于服务,我们提供了长期性订阅消息,用户订阅一次后,开发者可长期下发多条消息。
目前长期性订阅消息仅向政务民生、医疗、交通、金融、教育等线下公共服务开放,后期将逐步支持到其他线下公共服务业务。
详见小程序订阅消息开发指南文档。
同时长期订阅消息支持语音提醒与添加提醒能力。

1.2.4 设备订阅消息

设备订阅消息是一种特殊类型的订阅消息,它属于长期订阅消息类型,且需要完成设备接入才能使用。
设备订阅消息用于在设备触发某些需要人工介入的事件时(例如设备发生故障、设备耗材不足等),向用户发送消息通知。
详见设备订阅消息文档。

二、获取模板ID

先附上微信官方文档:小程序订阅消息(用户通过弹窗订阅)开发指南

1.登录微信公众平台开通订阅消息

在微信公众平台中的小程序后台找到订阅消息功能模块
在这里插入图片描述
开通订阅消息:
在这里插入图片描述
由于长期性订阅消息,目前仅向政务民生、医疗、交通、金融、教育等线下公共服务开放,后期将逐步支持到其他线下公共服务业务。仅就线下公共服务这一点,长期性订阅消息就和大部分开发者无缘了。所以我们这里只能以使用一次性订阅消息为例。

2.在微信公众平台手动配置获取模板 ID:

登录 https://mp.weixin.qq.com 获取模板,如果没有合适的模板,可以申请添加新模板,审核通过后可使用。
选择先要的公共模板,也可以自己定制,但是公共模板已经可以满足我们绝大多数业务场景了
Alt
选择或者自己定制一个合适的模板,然后可以进行订阅模板的编辑,当然这都属于前端的工作了,
我们只需要在模板中拿到模板ID即可。
在这里插入图片描述

三、获取接口调用凭据wx_access_token

先附上微信官方文档:获取接口调用凭据

1、接口说明

接口英文名:getAccessToken

功能描述:

获取小程序全局唯一后台接口调用凭据,token有效期为7200s,开发者需要进行妥善保存。
如使用云开发,可通过云调用免维护 access_token 调用。
如使用云托管,也可以通过微信令牌/开放接口服务免维护 access_token 调用。

2、调用方式

HTTPS 调用

GET https://api.weixin.qq.com/cgi-bin/token 

请求参数

在这里插入图片描述

3、Java代码实现

/*** 获取接口调用凭证 access_token*/private static final String ACCESSTOKEN_GET = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&";public WxAccessTokenVo getAccessToken() {WxAccessTokenVo accessTokenVo  = null;/*     这个是redis缓存的:没有的话去掉*/String wx_access_token = (String) redisTemplate.opsForValue().get("wx_access_token");if (wx_access_token != null) {accessTokenVo = new WxAccessTokenVo();accessTokenVo.setAccess_token(wx_access_token);return accessTokenVo;}String url = ACCESSTOKEN_GET + "appid=" + appId + "&secret=" + appSecret;RestTemplate restTemplate = new RestTemplate();String response = restTemplate.getForObject(url, String.class);try {accessTokenVo = JSON.parseObject(response, WxAccessTokenVo.class);/* 存储在redis中*/if (accessTokenVo.getExpire_in() > 0) {redisTemplate.opsForValue().set("wx_access_token", accessTokenVo.getAccess_token(),accessTokenVo.getExpire_in(), TimeUnit.SECONDS);}} catch (Exception e) {logger.error("Json转换异常", e);}return accessTokenVo;}

所以在获取到access_token的时候,把access_token存到数据库,或者存到本地缓存,并且还要记录当前时间,后面再用的时候先判断这个access_token有没有超过2个小时,如果超过2个小时的话,就要重新获取了。
附微信官方说明:获取 Access token
在这里插入图片描述

四、发送消息

先附上微信官方文档:发送订阅消息

1、接口说明

接口英文名:sendMessage

功能描述:

该接口用于发送订阅消息。

调用方式

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

请求参数

在这里插入图片描述
这些参数都是我们需要封装好发送给微信官方,调用时候需要的。

返回参数

在这里插入图片描述

2、注意点(需要前端配合)

这里有个需要特别注意的点,我们要给用户发送消息,就必须前端实现引导用户授权,因为用户不点击允许,你是没有办法给用户推送消息的。每一次授权只允许发送一条消息,所以如果你想尽量多的发送消息,就得尽量多的引导用户授权。

3、发送消息的Java代码实现

1)封装前端引导用户授权所需的参数:

@Data
public class AddMessageSubscribeForm {    // 前端模板需要的参数//  小程序的登录凭证codeprivate String code;//订阅消息模版id   TODOprivate String template_id;//默认跳到小程序首页 TODOprivate String page = "pages/index/index";//推送文字private Map<String, TemplateData> data;//   跳转小程序的类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版private String miniprogram_state;//  进入小程序查看的语言类型:支持zh_CN、en_US、zh_HK、zh_TW,默认为zh_CNprivate String lang;}

2)封装后台调用微信官方API所需的参数:

@Data
public class WXMssVO {//用户openidprivate String touser;//订阅消息模版idprivate String template_id;//默认跳到小程序首页 TODOprivate String page = "pages/index/index";//推送内容private Map<String, TemplateData> data;//   跳转小程序的类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版private String miniprogram_state;//  进入小程序查看的语言类型:支持zh_CN、en_US、zh_HK、zh_TW,默认为zh_CNprivate String lang;
}

3)编写发送消息的内容:

@AllArgsConstructor
@Data
public class TemplateData {/***   消息通知的内容*/private String value;
}

4)获取用户的openid

    /*** 获取微信用户唯一标识OpenID*/private static final String CODE2SESSION_GET = "https://api.weixin.qq.com/sns/jscode2session?";/*** code2sessino接口* @param code* @return*/public WxCode2SessionVo getCode2Session(String code) {String url = CODE2SESSION_GET + "appid=" + appId + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code";RestTemplate restTemplate = new RestTemplate();String response = restTemplate.getForObject(url, String.class);WxCode2SessionVo code2SessionVo = null;try {code2SessionVo = JSON.parseObject(response, WxCode2SessionVo.class);} catch (Exception e) {logger.error("Json转换异常", e);}return code2SessionVo;}

5)编写发送消息的函数:

    /***    给用户发送通知*    TODO  参数设置* @param info* @return*/
/***   给用户发送消息*/public static final String SEND_INFO_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=";public String pushMessage(AddMessageSubscribeForm info){RestTemplate restTemplate = new RestTemplate();String url = SEND_INFO_URL + getAccessToken().getAccess_token();// 通过 appId+appsecret+code三个参数获取微信用户信息 获取用户的openidWxCode2SessionVo code2Session = this.getCode2Session(info.getCode());if (code2Session == null || (code2Session.getErrcode() != null && code2Session.getErrcode() != 0)) {return  "获取用户微信信息失败:" + code2Session.toString();}String openid = code2Session.getOpenid();//  拼接推送的模板WXMssVO wxMssVO = new WXMssVO();wxMssVO.setTouser(openid);    // 用户的openIdwxMssVO.setTemplate_id(info.getTemplate_id());    //订阅消息模板idwxMssVO.setLang(info.getLang());     //语言类型wxMssVO.setMiniprogram_state(info.getMiniprogram_state());   //跳转小程序类型//TODO:指定跳转的页面wxMssVO.setPage(info.getPage());// TODO: 推送的内容Map<String, TemplateData> map = new HashMap<>();map.put("msg", new TemplateData("发消息了"));wxMssVO.setData(map);// 发送ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, wxMssVO, String.class);return responseEntity.getBody();}

到这里我们就可以完整的实现Java发送小程序消息的功能了。

总结

以上就是今天要分享给大家的内容,本文简单的记录了一下小程序发送通知的开发,很多内容其实都来自官方文档,欢迎大家批评指正、共同进步!

相关文章:

小程序一次性订阅消息(消息通知):java服务端实现

文章目录 引言一、消息订阅1.1 小程序订阅消息功能介绍1.2 消息分类1.2.1 新版一次性订阅消息Beta1.2.2 一次性订阅消息&#xff08;用户通过弹窗订阅&#xff09;1.2.3 长期订阅消息&#xff08;用户通过弹窗订阅&#xff09;1.2.4 设备订阅消息 二、获取模板ID1.登录[微信公众…...

百度自由DIY小程序源码:PHP+MySQL组合开发 带完整的搭建教程

随着移动互联网的快速发展&#xff0c;小程序已成为企业与用户互动的重要平台。然而&#xff0c;对于许多中小企业和开发者来说&#xff0c;从零开始开发一款小程序需要投入大量的时间和资源。 以下是部分代码示例&#xff1a; 系统特色功能一览&#xff1a; 1.高度自定义&…...

Vue中的选项式 API 和组合式 API,两者有什么区别

Vue中的选项式 API&#xff08;Option API&#xff09;和组合式 API&#xff08;Composition API&#xff09;是两种不同的组件编写方式&#xff0c;它们各有特点和适用场景&#xff1a; 选项式 API&#xff08;Option API&#xff09;: 传统方法&#xff1a;Vue最初的编程范式…...

Linux下误删除后的恢复操作测试之extundelete工具使用

一、工具介绍 extundelete命令的功能可用于系统删除文件的恢复。在使用前&#xff0c;需要先将要恢复的分区卸载&#xff0c;以防数据被意外覆盖。 语法格式&#xff1a;extundelete [参数] 文件或目录名 常用参数&#xff1a; --after 只恢复指定时间后被删除的文件 --bef…...

table表格中使用el-popover 无效问题解决

实例只针对单个的按钮管用在表格里每一列都有el-popover相当于是v-for遍历了 所以我们在触发按钮的时候并不是单个的触发某一个 主要执行 代码 <el-popover placement"left" :ref"popover-${scope.$index}"> 动态绑定了ref 关闭弹窗 执行deltask…...

c++类全面讲解

文章目录 前言类的基本概念基本结构类与结构体的区别示例代码 类的属性和方法属性&#xff08;成员变量&#xff09;方法&#xff08;成员函数&#xff09;访问修饰符示例代码 类的构造函数和析构函数构造函数析构函数示例代码 类的构造函数重载重载构造函数示例代码 类中的拷贝…...

使用Python和Pygame库创建简单的的彩球效果

简介 Pygame是一款强大的游戏开发库&#xff0c;可以用于创建各种有趣的图形效果。为了更好地了解Pygame的功能&#xff0c;今天我们将要做的是在屏幕上随机生成一些彩色的小球&#xff0c;并使它们以不同的速度和方向移动。当小球碰到屏幕边缘时&#xff0c;它们将反弹。 功能…...

第2课 使用FFmpeg读取rtmp流并用openCV显示视频

本课对应源文件下载链接&#xff1a; https://download.csdn.net/download/XiBuQiuChong/88680079 这节课我们开始利用ffmpeg和opencv来实现一个rtmp播放器。播放器的最基本功能其实就两个:显示画面和播放声音。在实现这两个功能前&#xff0c;我们需要先用ffmpeg连接到rtmp服…...

【中小型企业网络实战案例 七】配置限速

相关学习文章&#xff1a; 【中小型企业网络实战案例 一】规划、需求和基本配置 【中小型企业网络实战案例 二】配置网络互连互通【中小型企业网络实战案例 三】配置DHCP动态分配地址 【中小型企业网络实战案例 四】配置OSPF动态路由协议【中小型企业网络实战案例 五】配置可…...

Hive实战:实现数据去重

文章目录 一、实战概述二、提出任务三、完成任务&#xff08;一&#xff09;准备数据1、在虚拟机上创建文本文件2、上传文件到HDFS指定目录 &#xff08;二&#xff09;实现步骤1、启动Hive Metastore服务2、启动Hive客户端3、基于HDFS数据文件创建Hive外部表4、利用Hive SQL实…...

客户满意度调查常用的ChatGPT通用提示词模板

调查目的与范围&#xff1a;如何明确调查的目的和范围&#xff0c;确保调查的针对性&#xff1f; 调查方法选择&#xff1a;如何选择合适的调查方法&#xff0c;如问卷调查、访谈等&#xff1f; 问卷设计&#xff1a;如何设计问卷&#xff0c;确保问题的针对性和客观性&#…...

Android--Jetpack--Paging详解

不尝世间醋与墨&#xff0c;怎知人间酸与苦。 择一业谋食养命&#xff0c;等一运扭转乾坤。 你见过哪些令你膛目结舌的代码技巧&#xff1f; 文章目录 不尝世间醋与墨&#xff0c;怎知人间酸与苦。择一业谋食养命&#xff0c;等一运扭转乾坤。你见过哪些令你膛目结舌的代码技…...

Unity 基于UDP实现本地时间与网络时间校验 防客户端修改日期作弊

新建一个Unity GameObject 挂上NTPComponent脚本 时间校验 源码 using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using UnityEngine.Networking; using System.Text; using System.Net.Sockets; using System.Net; using Sys…...

ArduPilot开源代码之MatekSys Optical Flow 3901-L0X

ArduPilot开源代码之MatekSys Optical Flow 3901-L0X 1. 源由2. 安装3. 参数配置3.1 配置光流定位3.2 配置激光测距3.3 辅助配置 4. 测试4.1 光流数据测试4.2 测距数据测试4.3 飞行注意事项4.4 实际飞行测试 5. 参考资料 1. 源由 之前介绍过MatekSys Optical Flow 3901-L0X模块…...

【时钟】分布式时钟HLC|Logical Time|Vector Clock|True Time

目录 简略 详细 附录 1 分布式系统不能使用NTP的原因 简略 分布式系统中不同于单机系统不能使用NTP(网络时间协议&#xff08;Network Time Protocol&#xff09;)来获取时间&#xff0c;所以我们需要一个特别的方式来获取分布式系统中的时间&#xff0c;mvcc也是使用time保证读…...

人工智能AI与3D视觉技术的结合正在引领新一代移动机器人的革新

随着科技的飞速发展&#xff0c;人工智能AI与3D视觉技术的结合正在引领新一代移动机器人的革新。富唯智能移动机器人&#xff0c;以其独特的3D视觉技术&#xff0c;赋予了移动机器人一双“智慧之眼”&#xff0c;从而为现代工业自动化带来了前所未有的突破。 富唯智能移动机器…...

NSSCTF 简单包含

开启环境: 使用POST传flag&#xff0c;flag目录/var/www/html/flag.php 先使用post来尝试读取该flag.php 没反应: 查看一下源码index.php&#xff0c;看有什么条件 base64解密: <?php$path $_POST["flag"];if (strlen(file_get_contents(php://input)) <…...

FlinkSQL处理Canal-JSON数据

背景信息 Canal是一个CDC&#xff08;ChangeLog Data Capture&#xff0c;变更日志数据捕获&#xff09;工具&#xff0c;可以实时地将MySQL变更传输到其他系统。Canal为变更日志提供了统一的数据格式&#xff0c;并支持使用JSON或protobuf序列化消息&#xff08;Canal默认使用…...

玩转贝启科技BQ3588C开源鸿蒙系统开发板 —— DevEco Studio下载与安装

一、下载DevEco Studio IDE开发工具 1. 登录鸿蒙官网 网址为&#xff1a; ​​​​​​​华为HarmonyOS智能终端操作系统官网 | 应用设备分布式开发者生态 页面如下&#xff1a; 2. 搜索“DevEco Studio IDE” 点击右上角的“请输入关键词”&#xff0c;在其中搜索“DevEc…...

大模型上下文长度的超强扩展:从LongLora到LongQLora

前言 本文一开始是《七月论文审稿GPT第2版&#xff1a;从Meta Nougat、GPT4审稿到Mistral、LongLora Llama》中4.3节的内容&#xff0c;但考虑到 一方面&#xff0c;LongLora的实用性较高二方面&#xff0c;为了把LongLora和LongQLora更好的写清楚&#xff0c;而不至于受篇幅…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

C++实现分布式网络通信框架RPC(2)——rpc发布端

有了上篇文章的项目的基本知识的了解&#xff0c;现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...

Linux操作系统共享Windows操作系统的文件

目录 一、共享文件 二、挂载 一、共享文件 点击虚拟机选项-设置 点击选项&#xff0c;设置文件夹共享为总是启用&#xff0c;点击添加&#xff0c;可添加需要共享的文件夹 查询是否共享成功 ls /mnt/hgfs 如果显示Download&#xff08;这是我共享的文件夹&#xff09;&…...

Selenium 查找页面元素的方式

Selenium 查找页面元素的方式 Selenium 提供了多种方法来查找网页中的元素&#xff0c;以下是主要的定位方式&#xff1a; 基本定位方式 通过ID定位 driver.find_element(By.ID, "element_id")通过Name定位 driver.find_element(By.NAME, "element_name"…...

C++ Saucer 编写Windows桌面应用

文章目录 一、背景二、Saucer 简介核心特性典型应用场景 三、生成自己的项目四、以Win32项目方式构建Win32项目禁用最大化按钮 五、总结 一、背景 使用Saucer框架&#xff0c;开发Windows桌面应用&#xff0c;把一个html页面作为GUI设计放到Saucer里&#xff0c;隐藏掉运行时弹…...