package com.ruoyi.common.utils;
|
|
import lombok.extern.slf4j.Slf4j;
|
import me.chanjar.weixin.common.exception.WxErrorException;
|
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
|
import me.chanjar.weixin.mp.api.WxMpService;
|
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
|
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
|
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
|
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
|
|
import java.util.Map;
|
|
/**
|
* 微信公众号消息发送工具类
|
* 支持:文本客服消息、模板消息
|
*/
|
@Slf4j
|
public class WxMpUtils {
|
|
private final WxMpService wxMpService;
|
|
/**
|
* 构造方法,通过 appId 和 appSecret 初始化微信公众号服务
|
*
|
* @param appId 微信公众号 AppID
|
* @param appSecret 微信公众号 AppSecret
|
*/
|
public WxMpUtils(String appId, String appSecret) {
|
WxMpInMemoryConfigStorage configStorage = new WxMpInMemoryConfigStorage();
|
configStorage.setAppId(appId);
|
configStorage.setSecret(appSecret);
|
wxMpService = new WxMpServiceImpl();
|
wxMpService.setWxMpConfigStorage(configStorage);
|
}
|
|
// -------------------------------------------------------------------------
|
// 文本客服消息
|
// -------------------------------------------------------------------------
|
|
/**
|
* 向指定 openid 的用户发送文本客服消息
|
* 注意:用户需在48小时内与公众号有过交互才可发送
|
*
|
* @param openid 用户的微信 openid
|
* @param content 消息内容
|
* @return 发送成功返回 true,失败返回 false
|
*/
|
public boolean sendTextMessage(String openid, String content) {
|
if (StringUtils.isEmpty(openid)) {
|
log.warn("【WxMpUtils】sendTextMessage 失败:openid 为空");
|
return false;
|
}
|
if (StringUtils.isEmpty(content)) {
|
log.warn("【WxMpUtils】sendTextMessage 失败:content 为空");
|
return false;
|
}
|
try {
|
WxMpKefuMessage message = WxMpKefuMessage.TEXT()
|
.toUser(openid)
|
.content(content)
|
.build();
|
boolean result = wxMpService.getKefuService().sendKefuMessage(message);
|
log.info("【WxMpUtils】文本客服消息发送{},openid:{}", result ? "成功" : "失败", openid);
|
return result;
|
} catch (WxErrorException e) {
|
log.error("【WxMpUtils】文本客服消息发送异常,openid:{},错误:{}", openid, e.getError(), e);
|
return false;
|
}
|
}
|
|
// -------------------------------------------------------------------------
|
// 模板消息
|
// -------------------------------------------------------------------------
|
|
/**
|
* 向指定 openid 的用户发送模板消息(含跳转URL)
|
*
|
* @param openid 用户的微信 openid
|
* @param templateId 模板消息 ID(在微信公众平台配置)
|
* @param url 点击消息后的跳转 URL,不需要跳转可传 null
|
* @param dataMap 模板数据,key 为模板字段名,value 为 WxMpTemplateData(含值和颜色)
|
* 示例:{"first": new WxMpTemplateData("first", "你好", "#173177"), ...}
|
* @return 发送成功返回微信返回的 msgid,失败返回 null
|
*/
|
public String sendTemplateMessage(String openid, String templateId, String url,
|
Map<String, WxMpTemplateData> dataMap) {
|
if (StringUtils.isEmpty(openid)) {
|
log.warn("【WxMpUtils】sendTemplateMessage 失败:openid 为空");
|
return null;
|
}
|
if (StringUtils.isEmpty(templateId)) {
|
log.warn("【WxMpUtils】sendTemplateMessage 失败:templateId 为空");
|
return null;
|
}
|
try {
|
WxMpTemplateMessage templateMessage = new WxMpTemplateMessage();
|
templateMessage.setToUser(openid);
|
templateMessage.setTemplateId(templateId);
|
if (StringUtils.isNotEmpty(url)) {
|
templateMessage.setUrl(url);
|
}
|
if (dataMap != null) {
|
for (WxMpTemplateData data : dataMap.values()) {
|
templateMessage.addData(data);
|
}
|
}
|
String msgId = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
|
log.info("【WxMpUtils】模板消息发送成功,openid:{},msgId:{}", openid, msgId);
|
return msgId;
|
} catch (WxErrorException e) {
|
log.error("【WxMpUtils】模板消息发送异常,openid:{},templateId:{},错误:{}",
|
openid, templateId, e.getError(), e);
|
return null;
|
}
|
}
|
|
/**
|
* 向指定 openid 的用户发送模板消息(简化版,value 不设置颜色)
|
*
|
* @param openid 用户的微信 openid
|
* @param templateId 模板消息 ID
|
* @param url 点击消息后的跳转 URL,不需要跳转可传 null
|
* @param dataMap 模板数据,key 为模板字段名,value 为字段显示的文本内容
|
* 示例:{"first": "你好", "keyword1": "2024-01-01", "remark": "感谢使用"}
|
* @return 发送成功返回微信返回的 msgid,失败返回 null
|
*/
|
public String sendTemplateMessage(String openid, String templateId, String url,
|
Map<String, String> dataMap, String defaultColor) {
|
if (StringUtils.isEmpty(openid)) {
|
log.warn("【WxMpUtils】sendTemplateMessage 失败:openid 为空");
|
return null;
|
}
|
if (StringUtils.isEmpty(templateId)) {
|
log.warn("【WxMpUtils】sendTemplateMessage 失败:templateId 为空");
|
return null;
|
}
|
try {
|
WxMpTemplateMessage templateMessage = new WxMpTemplateMessage();
|
templateMessage.setToUser(openid);
|
templateMessage.setTemplateId(templateId);
|
if (StringUtils.isNotEmpty(url)) {
|
templateMessage.setUrl(url);
|
}
|
if (dataMap != null) {
|
String color = StringUtils.isEmpty(defaultColor) ? "#173177" : defaultColor;
|
for (Map.Entry<String, String> entry : dataMap.entrySet()) {
|
templateMessage.addData(new WxMpTemplateData(entry.getKey(), entry.getValue(), color));
|
}
|
}
|
String msgId = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
|
log.info("【WxMpUtils】模板消息发送成功,openid:{},msgId:{}", openid, msgId);
|
return msgId;
|
} catch (WxErrorException e) {
|
log.error("【WxMpUtils】模板消息发送异常,openid:{},templateId:{},错误:{}",
|
openid, templateId, e.getError(), e);
|
return null;
|
}
|
}
|
|
// -------------------------------------------------------------------------
|
// 静态工厂方法(快速构造)
|
// -------------------------------------------------------------------------
|
|
/**
|
* 快速创建 WxMpUtils 实例
|
*
|
* @param appId 微信公众号 AppID
|
* @param appSecret 微信公众号 AppSecret
|
* @return WxMpUtils 实例
|
*/
|
public static WxMpUtils of(String appId, String appSecret) {
|
return new WxMpUtils(appId, appSecret);
|
}
|
}
|