微信小程序订阅消息通过服务通知发送

article/2025/8/15 4:18:50

第一步:申请模板获取模板ID: 登录微信公众平台 -> 功能 -> 订阅消息 -> 对里面的模板进行选用或者自定义
在这里插入图片描述
在这里插入图片描述

公共模板库里面的模板分为一次性订阅 和永久订阅,这个是根据你创建小程序时选择的行业进行区分的。
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/subscribe-message.html 官方文档中有详细说明

第二步: 消息订阅接口:需要在小程序端调起订阅接口,需要前端完成。官方地址:https://developers.weixin.qq.com/miniprogram/dev/api/open-api/subscribe-message/wx.requestSubscribeMessage.html
第三步: 服务端发送消息到服务通知,官方文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html
我这里采用的是https的调用方式

代码实现:

  • 核心代码
package com.minapp.management.service;import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Strings;
import com.minapp.management.config.WxProperties;
import com.minapp.management.entity.dto.AppletTemplateMessageSendDTO;
import com.minapp.management.utils.CacheManager;
import com.minapp.management.utils.HttpClientUtil;
import lombok.Synchronized;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.io.IOException;
import java.util.Map;@Component
public class WxAppletRemoteService {private Logger logger = LoggerFactory.getLogger(WxAppletRemoteService.class);private static final String WXAPPLETURl="https://api.weixin.qq.com/cgi-bin";@Autowiredprivate WxProperties properties;@Autowiredprivate ObjectMapper objectMapper;/*** 获取AccessToken* @return*/@Synchronizedpublic String getAccessToken() {String appid=null;String secret=null;// 这里我是从配置文件中取得appid和appsecretappid=properties.getAppId();secret=properties.getAppSecret();//查询token是否存在String key="dowin"+appid+"_AccessToken";// 使用缓存先查询AccessToken是否存在,我这里使用的是本地缓存,如果只是存一个token,本地缓存足以,不需要使用专门缓存的服务,比如reids。String accessToken = CacheManager.getData(key);// 存在直接返回,不存在重新获取AccessTokenif (!Strings.isNullOrEmpty(accessToken)){return accessToken;}// 获取AccessToken的urlString grantType="client_credential";String url=WXAPPLETURl+"/token?grant_type="+grantType+"&appid="+appid+"&secret="+secret;// 获取到AccessTokenString token = HttpClientUtil.get(url);Map<String,Object> map = null;try {map = objectMapper.readValue(token, Map.class);} catch (IOException e) {logger.error("小程序异常通知-获取AccessToken-转化异常",e);}String access_token = String.valueOf(map.get("access_token"));// 把AccessToken存入缓存中,并设置过期时间,因为access_token的过期时间是两小时,我们缓存的时间一定要小于两小时,CacheManager.setData(key,access_token,5000);if (map.get("errcode")!=null || map.get("errmsg")!=null){String errcode = String.valueOf(map.get("errcode"));String errmsg = String.valueOf(map.get("errmsg"));if (!errcode.equals("0")){logger.error("获取token失败:code="+errcode+"msg="+errmsg);return null;}}return access_token;}/*** 同一消息发送接口* AppletTemplateMessageSendDTO   是一个传输类*/public String uniformMessageSend(AppletTemplateMessageSendDTO data) {String token = getAccessToken();// 调用发型接口String url=WXAPPLETURl+"/message/subscribe/send?access_token="+token;String returnData = HttpClientUtil.post(url,JSON.toJSONString(data));Map<String,Object> map = null;try {map = objectMapper.readValue(returnData, Map.class);} catch (IOException e) {logger.error("小程序异常通知-同一消息发送-转化异常",e);}String errcode = String.valueOf(map.get("errcode"));String errmsg = String.valueOf(map.get("errmsg"));if (!errcode.equals("0")){logger.error("消息发送失败:code="+errcode+"msg="+errmsg);}return errcode;}}
  • 传输实体类
package com.minapp.management.entity.dto;import lombok.Data;import java.io.Serializable;//小程序模板消息发送模板
@Data
public class AppletTemplateMessageSendDTO implements Serializable {//接收者(用户)的 openidprivate String touser;//所需下发的订阅模板idprivate String template_id;//所跳转的页面private String page;//模板消息内容private Object data;}
  • 本地缓存类
package com.minapp.management.utils;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;// 本地缓存类
public class CacheManager {private static Map<String, CacheData> CACHE_DATA = new ConcurrentHashMap<>();public static <T> T getData(String key, Load<T> load, int expire) {T data = getData(key);if (data == null && load != null) {data = load.load();if (data != null) {setData(key, data, expire);}}return data;}// 根据key获取数据public static <T> T getData(String key) {CacheData<T> data = CACHE_DATA.get(key);if (data != null && (data.getExpire() <= 0 || data.getSaveTime() >= System.currentTimeMillis())) {return data.getData();}return null;}// 存入数据并设置过期时间public static <T> void setData(String key, T data, int expire) {CACHE_DATA.put(key, new CacheData(data, expire));}// 根据key清除数据public static void clear(String key) {CACHE_DATA.remove(key);}// 清除所有缓存数据public static void clearAll() {CACHE_DATA.clear();}public interface Load<T> {T load();}private static class CacheData<T> {CacheData(T t, int expire) {this.data = t;this.expire = expire <= 0 ? 0 : expire * 1000;this.saveTime = System.currentTimeMillis() + this.expire;}private T data;private long saveTime; // 存活时间private long expire;   // 过期时间 小于等于0标识永久存活public T getData() {return data;}public long getExpire() {return expire;}public long getSaveTime() {return saveTime;}}
}

测试:

AppletTemplateMessageSendDTO appletTemplateMessageSendDTO = new AppletTemplateMessageSendDTO();appletTemplateMessageSendDTO.setTouser("openid");appletTemplateMessageSendDTO.setTemplate_id("模板id");appletTemplateMessageSendDTO.setPage("跳转的页面");Map<String,Object> map = new HashMap<>();Map<String,Object> thing6 = new HashMap<>();Map<String,Object> time8 = new HashMap<>();Map<String,Object> phone_number7 = new HashMap<>();Map<String,Object> thing10 = new HashMap<>();thing6.put("value","xqd");time8.put("value","2020-12-29");phone_number7.put("value", "17600026666");thing10.put("value","测试一下订阅消息");map.put("thing6",thing6);map.put("time8",time8);map.put("phone_number7",phone_number7);map.put("thing10",thing10);appletTemplateMessageSendDTO.setData(map);wxAppletRemoteService.uniformMessageSend(appletTemplateMessageSendDTO);

发送成功
在这里插入图片描述


http://chatgpt.dhexx.cn/article/Ao0T0Nma.shtml

相关文章

给微信小程序发送消息

给微信小程序发送消息 所用技术&#xff1a;后台&#xff1a;jeecgboot 数据库&#xff1a;oracle 前台&#xff1a;vue2.0 首先登陆微信公众平台 链接: https://mp.weixin.qq.com/ 1.登陆之后每个公司 都会有自己得相关参数例如 appid之类得 后面代码里时要用到的 2.然后先…

微信小程序通过公众号服务号发送消息

一、基础概念: 准备条件&#xff1a; 1、公众号和小程序必须在同一个公司主体下。 2、在公众号后台需要对小程序进程绑定操作。 公众号提供了两种消息&#xff0c;一种是订阅消息&#xff0c;一种是模板消息。 订阅消息需要用户主动订阅&#xff0c;然后才能接收消息&#x…

六、微信小程序发布流程

目录 1、上传2、提交审核 1、上传 当我们写完代码后 点击微信开发者工具的上传 要么是体验版 要么是1.0.1最新版 直接点击确定或上传即可 【前提是你本人必须是小程序的管理员或项目成员】 上传成功会有提示弹窗 2、提交审核 在版本管理中我们能看到上传的小程序版本 在这里我…

微信小程序发布全流程

1.在微信公众平台注册 我选的是用QQ邮箱注册的&#xff0c;因为我的163邮箱和微信绑定的&#xff0c;不能使用注册。 登陆进来就是这个页面啦。 2.npm打包&#xff08;假设您的电脑已经安装了nodeJS&#xff09; 选中您的项目&#xff0c;然后到项目的根目录下 执行npm ins…

微信小程序申请+开发+发布流程

框架用的Taro&#xff0c;开发工具用的是VSCode微信开发者工具&#xff0c;VSCode主要用来编码&#xff0c;微信开发者工具主要用来看和最后上传那么一下&#xff0c;其他没什么好说的。放张图&#xff0c;大家自行体会&#xff1a; 利用taro发布web程序如下&#xff1a; 过程整…

微信小程序发布流程

1.授权 登录微信公众平台微信公众平台&#xff0c;给相应人员授权&#xff1b;最好同时添加体验成员&#xff08;用于验证测试&#xff09;。 2.开发工具及代码 下载官方的微信开发者工具&#xff0c;使用微信扫一扫登录&#xff1b;同时下载最新的项目代码&#xff0c;导入…

信号与系统(四)

注&#xff1a;本博客是基于奥本海姆的《信号与系统》第二版编写&#xff0c;主要是为了自己考研&#xff0c;准备专业课。 (转载&#xff1a;https://blog.csdn.net/Explorer_day/article/details/77177542) 一、基本系统性质 1、记忆系统与无记忆系统 ①无记忆系统 如果对…

信号与系统 | 信号与系统概述 | 信号的基本概念和分类

文章目录 常见的概念信号的描述信号的分类确定信号和随机信号连续信号和离散信号周期信号和非周期信号能量信号和功率信号一维信号和多维信号因果信号和非因果信号 信号的matlab表示与绘图 常见的概念 消息&#xff0c;来自外界的各种报道统称为消息信息&#xff0c;消息中有意…

城市轨道交通信号系统学习笔记(四)信号机

信号机 <font face"楷体" size5>一、地面信号机的设置</font><font face"楷体" size5>二、信号显示</font> 城市轨道交通采用与铁路相同的色灯信号机&#xff0c;但设置位置和信号显示不同于铁路&#xff0c;信号显示距离也有自己…

信号与系统(一)

注&#xff1a;本博客是基于奥本海姆的《信号与系统》第二版编写&#xff0c;主要是为了自己考研&#xff0c;准备专业课。 (转载&#xff1a;https://blog.csdn.net/Explorer_day/article/details/76910002) 一、连续时间和离散时间信号 1、信号的定义 ①在物理上&#xf…

操作系统:信号

文章目录 一 信号概念1. 信号简介2. 信号/事件 产生方式3. 信号处理方式 二 信号实现1. 不可靠信号2. 可靠与不可靠信号类型3. 被中断的系统调用4. 信号函数4.1 信号发送函数 kill/raise4.2 定时发送信号函数 alarm4.3 信号捕获等待函数 pause 5. 信号集5.1 信号集来由5.2 信号…

信号与系统—信号的描述与分类

信号的描述和分类 信号的描述 函数表示 信号通常是时间变量t的函数&#xff0c;所以对于某一类信号可以用时间函数来表示&#xff0c;如 c ( u ) { 0 &#xff0c; t < 0 e − t τ &#xff0c; t ≥ 0 c(u)\begin{cases} 0&#xff0c;t<0\\ e^{-\frac{t}{\tau}}&…

操作系统——信号

信号的概念 信号的产生 信号的注册 信号的注销 自定义信号处理方式 信号的捕捉流程 信号阻塞 信号的概念&#xff1a; 1.信号是一个软件中断 2.信号的种类&#xff1a; kill -l命令的时候&#xff0c;我们会看到62种信号 1~31 &#xff1a; 非可靠信号&#xff0c; 信号有可能…

信号与系统(典型信号)

1.信号的描述与信号的分类 1.1基于信号维度分类 一维信号&#xff08;声音&#xff09;、二维信号&#xff08;图像&#xff09;、三维信号&#xff08;视频&#xff09;、四维信号&#xff08;VR中看到的信号&#xff09;、…N维。 信号与系统中只讨论一维信号 1.2一维信号…

信号与系统1-概述

目录&#xff1a; 一、概述 1、信号与系统概念 1&#xff09;信号 2&#xff09;系统 2、信号的描述、分类与典型信号 1&#xff09;描述方式 2&#xff09;信号的分类 &#xff08;1&#xff09;确定信号/随机信号 &#xff08;2&#xff09;周期信号/非周期信号 &#xff0…

【信号与系统】(四)信号与系统概述——系统的概念及分类

文章目录 第一章 信号与系统概述1.4 系统的概念及分类1.4.1 系统定义与典型系统举例1.4.1.1 系统定义1.4.1.2 系统模型1.4.1.3 系统的状态1.4.1.4 典型系统举例 1.4.2 系统分类1.4.2.1 连续系统与离散系统1.4.2.2 动态系统与即时系统1.4.2.3 单输入单输出系统与多输入多输出系统…

信号系统 | 信号的概念与常用信号

信号的本质是函数&#xff0c;因此信号处理方法具有普适性&#xff0c;应用领域非常广泛。本篇介绍信号的基本概念以及一些典型的信号&#xff0c;主要参考奥本海姆的经典教材《信号与系统》&#xff0c;微信搜索公众号PurePlay&#xff0c;后台回复Oppenheim即可获取中文PDF。…

【信号与系统】(二)信号与系统概述——基本信号

文章目录 第一章 信号与系统概述1.2基本信号1.2.1 阶跃函数1.2.2 冲激函数1.2.3 冲激函数的广义函数定义1.2.4 冲激函数的取样性质1.2.4.1 f ( t ) f(t) f(t)乘以 δ ( t ) δ(t) δ(t)1.2.4.2 f ( t ) f(t) f(t)乘以 δ ( t − a ) δ(t-a) δ(t−a) 1.2.5 冲激函数的导数1.…

【信号与系统|吴大正】1:信号与系统概述

信号与系统概述 写在前面&#xff1a; 自己也感觉最近基础类课程开了好多坑…因为发现未来研究领域跟数字信号处理也脱离不了关系&#xff0c;打算从《信号系统与线性分析》开始慢慢往后补&#xff1b;大二下期的时候学习过了这门课&#xff0c;但其实现在回过头来知识也不剩多…

城市轨道交通信号系统学习笔记(二)信号系统的组成

信号系统的组成 一、列车自动控制&#xff08;ATC&#xff09;系统 二、车联段联锁设备 城市轨道交通信号系统通常由列车自动控制&#xff08;Automatic Train Control&#xff0c;ATC&#xff09;系统和车辆段/停车场信号控制系统两大部分组成。用于列车进路控制、列车间隔控制…