微信小程序结合微信公众号进行消息发送
微信小程序结合微信公众号进行消息发送
由于小程序的模板消息已经废弃了,官方让使用订阅消息功能。而订阅消息的使用限制比较大,用户必须得订阅、需要获取用户同意接收消息的权限、用户必须得和小程序有交互的时候才能发送且只能发送一次。而我们的需求有可能是不限时间不限“次数”的发送消息。那么就可以使用官方提供的统一服务消息。
统一服务消息
该功能还是有一点的使用限制的。
第一:小程序和公众号的主体必须是同一个。
第二:用户必须关注公众号。
第三:我们得有消息模板,小程序消息模板和公众号消息模板都可以。
结合文档,使用Java对发送消息的功能进行简单的封装
第一:使用httpClient请求地址,获取access_token
GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
根据官方接口的返回值,我们封装返回值对象
@Data
public class AccessToken {
/** 接口调用凭证 */
private String access_token;
/** 过期时间 */
private Long expires_in;
/** 错误信息代码 */
private String errcode;
/** 错误信息 */
private String errmsg;
}
使用httpClient发送请求
AccessToken accessToken = new AccessToken();
String url = WxMessageConstant.GET_XCX_ACCESS_TOKEN_URL + "&appid=" + WxMessageConstant.APP_ID + "&secret=" + WxMessageConstant.SECRET;
String result = HttpClientUtils.doGet(url);
accessToken = JSON.parseObject(result, AccessToken.class);
注意:获得的token结果可以放在redis里面,设置上过期时间,防止应用重复获取access_token!
第二:构造请求
构造请求url
根据官方提供的接口再加上我们的获取的access_token进行构造
POST https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=ACCESS_TOKEN
构造请求参数
根据官方文档,我们一步一步来构造请求参数对象,我们用的是公众号的消息模板,所以这里没有weapp_template_msg参数
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ReqSendMessageData {
/**
* 消息接收者
*/
private String touser;
/**
* 公众号模板消息信息
*/
private MpTemplateMsg mp_template_msg;
}
构造mp_template_msg对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MpTemplateMsg {
/** 公众号openId */
private String appid;
/** 公众号模板id */
private String template_id;
/** 跳转到公众号的地址,文档上写的必填,我没填,没有报错 */
private String url;
/** 公众号绑定的小程序信息 */
private Miniprogram miniprogram;
/** 数据 */
private Map<String,Object> data;
}
构造小程序信息
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Miniprogram {
/** 小程序appid */
private String appid;
/** 要跳转到小程序的页面 */
private String page;
}
贴出httpClient发送post请求的方式
public static String postSendJsonParam(String url, String param) {
CloseableHttpClient httpClient = HttpClients.createDefault();
String result = null;
// 请求方式
HttpPost httpPost = null;
// 响应
CloseableHttpResponse httpResponse = null;
httpPost = new HttpPost(url);
httpPost.setHeader("Connection", REQUEST_HEADER_CONNECTION);
httpPost.setHeader("User-Agent", REQUEST_HEADER_USER_AGENT);
httpPost.addHeader("content-type", "application/json;charset=utf-8");
httpPost.addHeader("accept", "application/json");
httpPost.setEntity(new StringEntity(param, "UTF-8"));
try {
httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
result = EntityUtils.toString(httpEntity);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
构造返回值对象,我们根据错误代码进行扩展操作
@Data
public class ResSendMessageDTO {
/** 错误代码 */
private String errcode;
/** 错误信息 */
private String errmsg;
}
最后我们可以把这些封装成一个service交给spring管理。
public interface MessageService {
/**
* @author: taoym
* @date: 2020/7/2 9:08
* @desc: 推送消息
*/
ResSendMessageDTO sendMessage(ReqSendMessageData data);
}
具体实现不展示了。
封装消息发送者
@Component
public class MessageSender {
@Autowired
private MessageService messageService;
/**
* @param first 消息标题
* @param keywordMap 消息内容
* @param page 要跳转到小程序的页面
* @param templateId 模板消息编号
* @param touser 消息接收者openId
* @author: taoym
* @date: 2020/9/28 11:25
* @desc: 消息发送者
*/
public ResSendMessageDTO sendMessage(String first, Map<String, Keyword> keywordMap, String touser, String page, String templateId) {
// 消息模板上的数据
Map<String, Object> messageData = Maps.newHashMap();
// first,可以理解为 标题
messageData.put("first", new First(first));
// keywordMap 可以理解为内容
messageData.putAll(keywordMap);
ReqSendMessageData reqSendMessageData = new ReqSendMessageData();
reqSendMessageData.setTouser(PasswordUtils.decrypt(touser));
MpTemplateMsg mpTemplateMsg = new MpTemplateMsg();
Miniprogram miniprogram = new Miniprogram();
miniprogram.setPage(page);
mpTemplateMsg.setMiniprogram(miniprogram);
mpTemplateMsg.setData(messageData);
mpTemplateMsg.setTemplate_id(templateId);
reqSendMessageData.setMp_template_msg(mpTemplateMsg);
ResSendMessageDTO resSendMessageDTO = messageService.sendMessage(reqSendMessageData);
// 0为成功的标志
if (!resSendMessageDTO.getErrcode().equals("0")) {
throw new ExceptionCore(resSendMessageDTO.getErrcode(), resSendMessageDTO.getErrmsg());
}
return resSendMessageDTO;
}
}
最后我们只需要根据模板消息的内容构造合理的参数,然后调用该方法即可发送消息。
微信小程序结合微信公众号进行消息发送的更多相关文章
- 微信小程序和微信公众号的id是一个吗
首先,简单说下我遇到的问题是我们的程序调用微信小程序得到openid,然后通过openID得到用户的唯一标识,用户得以登录,然而,当我们调用微信公众号也同样的到openid,同一以用户两个不同的ope ...
- [转]微信小程序、微信公众号、H5之间相互跳转
本文转自:https://www.cnblogs.com/colorful-paopao1/p/8608609.html 转自慕课网 一.小程序和公众号 答案是:可以相互关联. 在微信公众号里可以添加 ...
- 微信小程序、微信公众号、H5之间相互跳转
转自慕课网 一.小程序和公众号 答案是:可以相互关联. 在微信公众号里可以添加小程序. 图片有点小,我把文字打出来吧: 可关联已有的小程序或快速创建小程序.已关联的小程序可被使用在自定义菜单和模版消息 ...
- 使用Appium 测试微信小程序和微信公众号方法
由于腾讯系QQ.微信等都是基于腾讯自研X5内核,不是google原生webview,需要打开TBS内核Inspector调试功能才能用Chrome浏览器查看页面元素,并实现Appium自动化测试微信小 ...
- 微信小程序与微信公众号同一用户登录问题
微信小程序与微信公众号同一用户登录问题 最近在做微信小程序与微信公众号登录合并的接口.整理相关资料以及个人认识的心得写了这篇文章与大家一起分享. 首先,简单说下我遇到的问题是我们的程序调用微信小程序得 ...
- 微信小程序(原名微信应用号)开发工具0.9版安装教程
微信小程序全称微信公众平台·小程序,原名微信公众平台·应用号(简称微信应用号) 声明 微信小程序开发工具类似于一个轻量级的IDE集成开发环境,目前仅开放给了少部分受微信官方邀请的人士(据说仅200个名 ...
- 微信小程序(微信应用号)开发ide安装解决方法
这两天整个技术圈都炸锅了,微信小程序(微信应用号)发布内测,首批200家收到邀请,但是没受邀请的同学,也不用担心,下面介绍一下解决方法. 首先需要下载ide,昨天只需要下载0.9版本的编辑器并替换文件 ...
- 微信小程序(微信应用号)组件讲解[申明:来源于网络]
微信小程序(微信应用号)组件讲解[申明:来源于网络] 地址:http://www.cnblogs.com/muyixiaoguang/p/5902008.html
- 如何玩转小程序+公众号?手把手教你JeeWx小程序CMS与公众号关联
随着微信小程序新功能.新入口的不断更新,小程序的商业价值逐步增强,特别是小程序与公众号的深度融合,已经让小程序成为各行业新的营销渠道.Jeewx平台专注小程序的开发,逐步完善小程序生态圈,通过简单操作 ...
随机推荐
- springboot的常用注解
1. @SpringBootApplication2. @Repository3. @Service4. @RestController5. @Controller6. @Component7. @R ...
- Kubernetes使用Eedpoints连接外部服务端口
Kubernetes使用Eedpoints连接外部服务端口 背景: 在Kubernetes的使用环境中,我们经常要连接外部的一些服务,比如mysql Elasticsearch kafka 等等外部的 ...
- 问题定位 | Peronca Xtrabackup 8.0近日踩坑总结 - xtrabackup 2.4和8.0区别
目录 前言 适配过程中遇到的坑 xtrabackup 2.4和8.0区别 问题定位 坑一:MySQL 8.0 + Semi-Sync 重建问题 坑二:MySQL 8.0 + Group-Replica ...
- 设计模式C++模板(Template)模式
设计模式C++描述----02.模板(Template)模式(转载) 一. 问题 在面向对象系统的分析与设计过程中经常会遇到这样一种情况:对于某一个业务逻辑(算法实现)在不同的对象中有不同的细节实现, ...
- 557反转字符串中的单词III
class Solution: # 定义一个反转字符串的函数. def str_rever(self,s): length = len(s) s1 = '' for index in range(le ...
- 【Flutter 实战】全局点击空白处隐藏键盘
老孟导读:为什么要实现点击空白处隐藏键盘?因为这是 iOS 平台的默认行为,Android 平台由于其弹出的键盘右上角默认带有关闭键盘的按钮,所以点击空白处不会隐藏键盘. 对于单个页面来说,通过为 T ...
- android 数据绑定(6)自定义绑定方法、双向数据绑定
1.官方文档 https://developer.android.com/topic/libraries/data-binding/binding-adapters https://developer ...
- 初识ABP vNext(8):ABP特征管理
Tips:本篇已加入系列文章阅读目录,可点击查看更多相关文章. 目录 前言 开始 定义特征 应用特征 用户数量 社交登录 最后 前言 上一篇提到了ABP功能管理(特征管理),它来自ABP的Featur ...
- Salesforce LWC学习(二十三) Lightning Message Service 浅谈
本篇参考: https://trailhead.salesforce.com/content/learn/superbadges/superbadge_lwc_specialist https://d ...
- Prometheus 与 国产 TDengine 的对比
通过对比,能加深对这两个系统的理解,方便后续架构选型时作出正确决定.他们的设计思路有很多值得借鉴的地方,虽然工作中需要用到这些知识的地方不多,但是了解他们的设计细节能极大满足我的好奇心. 1.场景和需 ...