Merge branch 'dev-3.0.x' of gitee.com:dromara/sms4j into dev-3.0.x-budingv2

Signed-off-by: NicholasLD <nicholasld505@gmail.com>
This commit is contained in:
NicholasLD 2024-04-02 03:51:36 +00:00 committed by Gitee
commit 157a19bc8e
34 changed files with 284 additions and 97 deletions

View File

@ -1,9 +1,9 @@
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">sms4j v3.1.0</h1> <h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">sms4j v3.2.0</h1>
<h4 align="center" style="margin: 30px 0 30px; font-weight: bold;">sms4j -- 让发送短信变的更简单</h4> <h4 align="center" style="margin: 30px 0 30px; font-weight: bold;">sms4j -- 让发送短信变的更简单</h4>
<p align="center"> <p align="center">
<a href="https://gitee.com/dromara/sms4j/stargazers"><img src="https://gitee.com/dromara/sms4j/badge/star.svg?theme=gvp"></a> <a href="https://gitee.com/dromara/sms4j/stargazers"><img src="https://gitee.com/dromara/sms4j/badge/star.svg?theme=gvp"></a>
<a href="https://gitee.com/dromara/sms4j/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-green"></a> <a href="https://gitee.com/dromara/sms4j/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-green"></a>
<a href="https://gitee.com/dromara/sms4j"><img src="https://img.shields.io/badge/version-v3.1.0-blue"></a> <a href="https://gitee.com/dromara/sms4j"><img src="https://img.shields.io/badge/version-v3.2.0-blue"></a>
</p> </p>
<img src="/public/logo.png"> <img src="/public/logo.png">
@ -29,9 +29,12 @@
- **[容联云国内短信(原云通讯)](https://www.yuntongxun.com/sms/note-inform)** - **[容联云国内短信(原云通讯)](https://www.yuntongxun.com/sms/note-inform)**
- **[网易云信短信](https://netease.im/sms)** - **[网易云信短信](https://netease.im/sms)**
- **[天翼云短信](https://www.ctyun.cn/products/10020341)** - **[天翼云短信](https://www.ctyun.cn/products/10020341)**
- **[七牛云短信](https://www.qiniu.com/products/sms)**
- **[合一短信](https://unisms.apistd.com/)** - **[合一短信](https://unisms.apistd.com/)**
- **[云片短信](https://www.yunpian.com/product/domestic-sms)** - **[云片短信](https://www.yunpian.com/product/domestic-sms)**
- **[助通短信](https://www.ztinfo.cn/products/sms)** - **[助通短信](https://www.ztinfo.cn/products/sms)**
- **[联麓短信](https://console.shlianlu.com/#/document/smsDoc)**
- **[鼎众短信](http://demoapi.321sms.com:8201/index.html)**
## 在SpringBoot环境集成 ## 在SpringBoot环境集成

View File

@ -52,7 +52,7 @@
</scm> </scm>
<properties> <properties>
<revision>3.0.1-SNAPSHOT</revision> <revision>3.2.0</revision>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
@ -60,7 +60,7 @@
<solon.version>2.6.5</solon.version> <solon.version>2.6.5</solon.version>
<redisson.version>3.17.0</redisson.version> <redisson.version>3.17.0</redisson.version>
<jdcloud.version>1.3.3</jdcloud.version> <jdcloud.version>1.3.3</jdcloud.version>
<hutool.version>5.8.25</hutool.version> <hutool.version>5.8.26</hutool.version>
<xmlblend.version>2.3.0</xmlblend.version> <xmlblend.version>2.3.0</xmlblend.version>
<activation.version>1.1.1</activation.version> <activation.version>1.1.1</activation.version>
<mail.version>1.6.2</mail.version> <mail.version>1.6.2</mail.version>

View File

@ -22,6 +22,9 @@ public interface CoreMethodProcessor extends SmsProcessor {
return param; return param;
} }
if (NumberOfParasmeters.THREE == NumberOfParasmeters.getNumberOfParasmetersEnum(parameterCount)) { if (NumberOfParasmeters.THREE == NumberOfParasmeters.getNumberOfParasmetersEnum(parameterCount)) {
if (null == param[2]){
param[2] = new LinkedHashMap<>();
}
sendMessageByTemplatePreProcess((String)param[0],(String) param[1],(LinkedHashMap<String, String>)param[2]); sendMessageByTemplatePreProcess((String)param[0],(String) param[1],(LinkedHashMap<String, String>)param[2]);
return param; return param;
} }
@ -32,6 +35,9 @@ public interface CoreMethodProcessor extends SmsProcessor {
return param; return param;
} }
if (NumberOfParasmeters.THREE == NumberOfParasmeters.getNumberOfParasmetersEnum(parameterCount)) { if (NumberOfParasmeters.THREE == NumberOfParasmeters.getNumberOfParasmetersEnum(parameterCount)) {
if (null == param[2]){
param[2] = new LinkedHashMap<>();
}
massTextingByTemplatePreProcess((List<String>)param[0],(String)param[1],(LinkedHashMap<String, String>)param[2]); massTextingByTemplatePreProcess((List<String>)param[0],(String)param[1],(LinkedHashMap<String, String>)param[2]);
return param; return param;
} }

View File

@ -0,0 +1,23 @@
package org.dromara.sms4j.api.verify;
/**
* PhoneVerify
* <p> 实现校验手机号合规的接口
* @author :Wind
* 2024/3/28 14:15
**/
public interface PhoneVerify{
/**
* verifyPhone
* <p>用于校验手机号是否合理的规则方法可以尝试重写此方法以改变规则例如你可以选择使用正则表达式来进行
* 一系列更加精准和严格的校验此校验优先级最高会在黑名单和其他拦截之前执行
* 当此校验触发时候将会直接以异常形式进行抛出并终止后续向厂商请求的动作故而不会有返回值
* 当校验手机号合格时返回 true 否则返回 false
* @param phone 被校验的手机号
* @author :Wind
*/
default boolean verifyPhone(String phone){
return phone.length() == 11;
}
}

View File

@ -11,7 +11,7 @@ public abstract class Constant {
/** /**
* 项目版本号 * 项目版本号
*/ */
public static final String VERSION = "V 3.0.1"; public static final String VERSION = "V 3.2.0";
/** /**
* 用于格式化鉴权头域,"Authorization"参数赋值 * 用于格式化鉴权头域,"Authorization"参数赋值

View File

@ -22,4 +22,9 @@ public class SmsBlendException extends RuntimeException{
this.code = code; this.code = code;
this.requestId = requestId; this.requestId = requestId;
} }
public SmsBlendException(Exception e){
super(e);
this.message = e.getMessage();
}
} }

View File

@ -3,6 +3,7 @@ package org.dromara.sms4j.core.proxy;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.sms4j.api.SmsBlend; import org.dromara.sms4j.api.SmsBlend;
import org.dromara.sms4j.api.proxy.SmsProcessor; import org.dromara.sms4j.api.proxy.SmsProcessor;
import org.dromara.sms4j.comm.exception.SmsBlendException;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -36,12 +37,16 @@ public class SmsInvocationHandler implements InvocationHandler {
} catch (Exception e) { } catch (Exception e) {
//错误执行器 //错误执行器
doErrorHandleProcess(smsBlend, method, objects,e); doErrorHandleProcess(smsBlend, method, objects,e);
throw new SmsBlendException(e);
} }
//后置执行器 //后置执行器
doPostrocess(smsBlend, method, objects, result); doPostrocess(smsBlend, method, objects, result);
return result; return result;
} }
/**
* 前置执行器
* */
public Object[] doPreProcess(Object o, Method method, Object[] objects) { public Object[] doPreProcess(Object o, Method method, Object[] objects) {
for (SmsProcessor processor : processors) { for (SmsProcessor processor : processors) {
objects = processor.preProcessor(method, o, objects); objects = processor.preProcessor(method, o, objects);
@ -49,12 +54,18 @@ public class SmsInvocationHandler implements InvocationHandler {
return objects; return objects;
} }
/**
* 异常执行器
* */
public void doErrorHandleProcess(Object o, Method method, Object[] objects,Exception e) { public void doErrorHandleProcess(Object o, Method method, Object[] objects,Exception e) {
for (SmsProcessor processor : processors) { for (SmsProcessor processor : processors) {
processor.exceptionHandleProcessor(method, o, objects,e); processor.exceptionHandleProcessor(method, o, objects,e);
} }
} }
/**
* 后置执行器
* */
public Object doPostrocess(Object o, Method method, Object[] objects, Object result) { public Object doPostrocess(Object o, Method method, Object[] objects, Object result) {
for (SmsProcessor processor : processors) { for (SmsProcessor processor : processors) {
Object overrideResult = processor.postProcessor(result, objects); Object overrideResult = processor.postProcessor(result, objects);

View File

@ -101,7 +101,7 @@ public abstract class SmsProxyFactory {
Class<?> clazz = Class.forName(className); Class<?> clazz = Class.forName(className);
Method getSmsDao = clazz.getMethod("getSmsDao", null); Method getSmsDao = clazz.getMethod("getSmsDao", null);
SmsDao smsDao = (SmsDao) getSmsDao.invoke(null, null); SmsDao smsDao = (SmsDao) getSmsDao.invoke(null, null);
log.info("{}:加载SmsDao成功使用{}", frameworkName,smsDao.getClass().getName()); log.debug("{}:加载SmsDao成功使用{}", frameworkName,smsDao.getClass().getName());
return smsDao; return smsDao;
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
log.debug("{}:尝试其他框架加载......", frameworkName); log.debug("{}:尝试其他框架加载......", frameworkName);

View File

@ -1,8 +1,10 @@
package org.dromara.sms4j.core.proxy.processor; package org.dromara.sms4j.core.proxy.processor;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.sms4j.api.proxy.CoreMethodProcessor; import org.dromara.sms4j.api.proxy.CoreMethodProcessor;
import org.dromara.sms4j.api.verify.PhoneVerify;
import org.dromara.sms4j.comm.exception.SmsBlendException; import org.dromara.sms4j.comm.exception.SmsBlendException;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -16,8 +18,20 @@ import java.util.Objects;
* @author sh1yu * @author sh1yu
* @since 2023/10/27 13:03 * @since 2023/10/27 13:03
*/ */
@Setter
@Slf4j @Slf4j
public class CoreMethodParamValidateProcessor implements CoreMethodProcessor { public class CoreMethodParamValidateProcessor implements CoreMethodProcessor {
/**
* -- SETTER --
* 设置 phoneVerify
*/
private PhoneVerify phoneVerify;
public CoreMethodParamValidateProcessor(PhoneVerify phoneVerify) {
this.phoneVerify = phoneVerify;
}
@Override @Override
public int getOrder() { public int getOrder() {
return -1; return -1;
@ -60,9 +74,12 @@ public class CoreMethodParamValidateProcessor implements CoreMethodProcessor {
} }
public void validatePhone(String phone) { public void validatePhone(String phone) {
if (StrUtil.isNotEmpty(phone)) { if (StrUtil.isBlank(phone)) {
throw new SmsBlendException("cant send message to null!"); throw new SmsBlendException("cant send message to null!");
} }
if (phoneVerify != null && !phoneVerify.verifyPhone(phone)){
throw new SmsBlendException("The mobile phone number format is invalid!");
}
} }
public void validatePhones(List<String> phones) { public void validatePhones(List<String> phones) {
@ -71,14 +88,16 @@ public class CoreMethodParamValidateProcessor implements CoreMethodProcessor {
} }
for (String phone : phones) { for (String phone : phones) {
if (StrUtil.isNotBlank(phone)) { if (StrUtil.isNotBlank(phone)) {
return; if (phoneVerify != null && !phoneVerify.verifyPhone(phone)){
throw new SmsBlendException("The mobile phone number format is invalid!");
}
} }
} }
throw new SmsBlendException("cant send message to null!"); throw new SmsBlendException("cant send message to null!");
} }
public void validateMessages(String templateId, LinkedHashMap<String, String> messages) { public void validateMessages(String templateId, LinkedHashMap<String, String> messages) {
if (StrUtil.isEmpty(templateId) && messages == null) { if (StrUtil.isEmpty(templateId)) {
throw new SmsBlendException("cant use template without template param"); throw new SmsBlendException("cant use template without template param");
} }
} }

View File

@ -13,14 +13,14 @@ public class OaContent {
/** /**
* 钉钉 * 钉钉
*/ */
public static final String DINGTALK = "dingding"; public static final String DING_TALK = "ding_ding";
/** /**
* 飞书 * 飞书
*/ */
public static final String BYTETALK = "feishu"; public static final String BYTE_TALK = "byte_talk";
/** /**
* 微信 * 微信
*/ */
public static final String WETALK = "wetalk"; public static final String WE_TALK = "we_talk";
} }

View File

@ -20,6 +20,9 @@ public class Request implements Comparable<Request> {
// link类型的参数 // link类型的参数
private String messageUrl; private String messageUrl;
// news类型的参数
private List<WeTalkRequestArticle> articleList;
private List<String> phoneList; private List<String> phoneList;
// 用于@,唯一标识:userId/openId // 用于@,唯一标识:userId/openId

View File

@ -0,0 +1,27 @@
package org.dromara.oa.comm.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 图文消息一个图文消息支持1到8条图文
* @author dongfeng
* 2024-03-23 19:25
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WeTalkRequestArticle {
// 标题不超过128个字节超过会自动截断
private String title;
// 描述不超过512个字节超过会自动截断
private String description;
// 点击后跳转的链接
private String url;
// 图文消息的图片链接支持JPGPNG格式较好的效果为大图 1068*455小图150*150
private String picUrl;
}

View File

@ -5,27 +5,27 @@ import lombok.Getter;
@Getter @Getter
public enum MessageType { public enum MessageType {
// 钉钉支持类型 // 钉钉支持类型
DINGTALK_TEXT("text"), DING_TALK_TEXT("text"),
DINGTALK_MARKDOWN("markdown"), DING_TALK_MARKDOWN("markdown"),
DING_TALK_LINK("link"),
DINGTALK_LINK("link"),
// 飞书支持类型 // 飞书支持类型
BYTE_TALK_TEXT("text"),
BYTETALK_TEXT("text"), // BYTE_TALK_MARKDOWN("markdown"),
// BYTETALK_MARKDOWN("markdown"), // BYTE_TALK_LINK("link"),
// BYTETALK_LINK("link"),
// 企业微信支持类型 // 企业微信支持类型
WETETALK_TEXT("text"), WE_TALK_TEXT("text"),
WETETALK_MARKDOWN("markdown"); WE_TALK_MARKDOWN("markdown"),
WE_TALK_NEWS("news");
//暂未支持 //暂未支持
// WETETALK_IMAGE("image"), // WE_TALK_IMAGE("image"),
// WETETALK_NEWS("news"), // WE_TALK_FILE("file"),
// WETETALK_FILE("file"), // WE_TALK_VOICE("voice"),
// WETETALK_VOICE("voice"), // WE_TALK_TEMPLATE_CARD("template_card");
// WETETALK_TEMPLATE_CARD("template_card");
MessageType(String name) { MessageType(String name) {
this.name = name; this.name = name;

View File

@ -6,15 +6,15 @@ public enum OaType {
/** /**
* 钉钉 * 钉钉
*/ */
DINGTALK("dingding", "https://oapi.dingtalk.com/robot/send?access_token=", true), DING_TALK("ding_ding", "https://oapi.dingtalk.com/robot/send?access_token=", true),
/** /**
* 微信 * 微信
*/ */
WETALK("wetalk", "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=", true), WE_TALK("we_talk", "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=", true),
/** /**
* 飞书 * 飞书
*/ */
BYTETALK("feishu", "https://open.feishu.cn/open-apis/bot/v2/hook/", true), BYTE_TALK("byte_talk", "https://open.feishu.cn/open-apis/bot/v2/hook/", true),
; ;
@Getter @Getter

View File

@ -9,10 +9,10 @@ import org.dromara.oa.core.provider.config.OaBaseConfig;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class ByteTalkConfig extends OaBaseConfig { public class ByteTalkConfig extends OaBaseConfig {
private final String requestUrl = OaType.BYTETALK.getUrl(); private final String requestUrl = OaType.BYTE_TALK.getUrl();
@Override @Override
public String getSupplier() { public String getSupplier() {
return OaType.BYTETALK.getType(); return OaType.BYTE_TALK.getType();
} }
} }

View File

@ -25,7 +25,7 @@ public class ByteTalkFactory extends OaAbstractProviderFactory<ByteTalkOaImpl, B
@Override @Override
public String getSupplier() { public String getSupplier() {
return OaContent.BYTETALK; return OaContent.BYTE_TALK;
} }
/** /**

View File

@ -16,7 +16,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import static org.dromara.oa.comm.enums.OaType.BYTETALK; import static org.dromara.oa.comm.enums.OaType.BYTE_TALK;
/** /**
* @author dongfeng * @author dongfeng
@ -33,7 +33,7 @@ public class ByteTalkOaImpl extends AbstractOaBlend<ByteTalkConfig> {
@Override @Override
public String getSupplier() { public String getSupplier() {
return OaType.BYTETALK.getType(); return OaType.BYTE_TALK.getType();
} }
@Override @Override
@ -45,7 +45,7 @@ public class ByteTalkOaImpl extends AbstractOaBlend<ByteTalkConfig> {
StringBuilder webhook = new StringBuilder(); StringBuilder webhook = new StringBuilder();
JSONObject message = null; JSONObject message = null;
ByteTalkConfig config = getConfig(); ByteTalkConfig config = getConfig();
webhook.append(BYTETALK.getUrl()); webhook.append(BYTE_TALK.getUrl());
webhook.append(config.getTokenId()); webhook.append(config.getTokenId());
long now = System.currentTimeMillis() / 1000; long now = System.currentTimeMillis() / 1000;
String sign = ByteTalkBuilder.byteTalkSign(config.getSign(), now); String sign = ByteTalkBuilder.byteTalkSign(config.getSign(), now);

View File

@ -12,7 +12,7 @@ import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import static org.dromara.oa.comm.enums.MessageType.BYTETALK_TEXT; import static org.dromara.oa.comm.enums.MessageType.BYTE_TALK_TEXT;
/** /**
* 飞书通知签名和信息构建 * 飞书通知签名和信息构建
@ -35,7 +35,7 @@ public class ByteTalkBuilder {
public static JSONObject createByteTalkMessage(Request request, MessageType messageType, String sign, Long timestamp) { public static JSONObject createByteTalkMessage(Request request, MessageType messageType, String sign, Long timestamp) {
JSONObject message = new JSONObject(); JSONObject message = new JSONObject();
List<String> userIdList = request.getUserIdList(); List<String> userIdList = request.getUserIdList();
if (messageType == BYTETALK_TEXT) { if (messageType == BYTE_TALK_TEXT) {
message.set("msg_type", "text"); message.set("msg_type", "text");
message.set("timestamp", timestamp); message.set("timestamp", timestamp);
message.set("sign", sign); message.set("sign", sign);

View File

@ -13,10 +13,10 @@ import org.dromara.oa.core.provider.config.OaBaseConfig;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class DingTalkConfig extends OaBaseConfig { public class DingTalkConfig extends OaBaseConfig {
private final String requestUrl = OaType.DINGTALK.getUrl(); private final String requestUrl = OaType.DING_TALK.getUrl();
@Override @Override
public String getSupplier() { public String getSupplier() {
return OaType.DINGTALK.getType(); return OaType.DING_TALK.getType();
} }
} }

View File

@ -27,7 +27,7 @@ public class DingTalkFactory extends OaAbstractProviderFactory<DingTalkOaImpl, D
@Override @Override
public String getSupplier() { public String getSupplier() {
return OaContent.DINGTALK; return OaContent.DING_TALK;
} }
/** /**

View File

@ -16,7 +16,7 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import static org.dromara.oa.comm.enums.OaType.DINGTALK; import static org.dromara.oa.comm.enums.OaType.DING_TALK;
/** /**
* @author dongfeng * @author dongfeng
@ -54,7 +54,7 @@ public class DingTalkOaImpl extends AbstractOaBlend<DingTalkConfig> {
StringBuilder webhook = new StringBuilder(); StringBuilder webhook = new StringBuilder();
JSONObject message = null; JSONObject message = null;
DingTalkConfig config = getConfig(); DingTalkConfig config = getConfig();
webhook.append(DINGTALK.getUrl()); webhook.append(DING_TALK.getUrl());
webhook.append(config.getTokenId()); webhook.append(config.getTokenId());
String sign = config.getSign(); String sign = config.getSign();
if (!Objects.isNull(sign)) { if (!Objects.isNull(sign)) {

View File

@ -15,9 +15,9 @@ import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import static org.dromara.oa.comm.enums.MessageType.DINGTALK_LINK; import static org.dromara.oa.comm.enums.MessageType.DING_TALK_LINK;
import static org.dromara.oa.comm.enums.MessageType.DINGTALK_MARKDOWN; import static org.dromara.oa.comm.enums.MessageType.DING_TALK_MARKDOWN;
import static org.dromara.oa.comm.enums.MessageType.DINGTALK_TEXT; import static org.dromara.oa.comm.enums.MessageType.DING_TALK_TEXT;
/** /**
* 钉钉通知签名和信息构建 * 钉钉通知签名和信息构建
@ -46,18 +46,18 @@ public class DingTalkBuilder {
JSONObject message = new JSONObject(); JSONObject message = new JSONObject();
if (messageType == DINGTALK_TEXT) { if (messageType == DING_TALK_TEXT) {
message.set("msgtype", "text"); message.set("msgtype", "text");
JSONObject text = new JSONObject(); JSONObject text = new JSONObject();
text.set("content", request.getContent()); text.set("content", request.getContent());
message.set("text", text); message.set("text", text);
} else if (messageType == DINGTALK_MARKDOWN) { } else if (messageType == DING_TALK_MARKDOWN) {
message.set("msgtype", "markdown"); message.set("msgtype", "markdown");
JSONObject markdown = new JSONObject(); JSONObject markdown = new JSONObject();
markdown.set("text", request.getContent()); markdown.set("text", request.getContent());
markdown.set("title", request.getTitle()); markdown.set("title", request.getTitle());
message.set("markdown", markdown); message.set("markdown", markdown);
} else if (messageType == DINGTALK_LINK) { } else if (messageType == DING_TALK_LINK) {
message.set("msgtype", "link"); message.set("msgtype", "link");
JSONObject link = new JSONObject(); JSONObject link = new JSONObject();
link.set("text", request.getContent()); link.set("text", request.getContent());

View File

@ -9,10 +9,10 @@ import org.dromara.oa.core.provider.config.OaBaseConfig;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class WeTalkConfig extends OaBaseConfig { public class WeTalkConfig extends OaBaseConfig {
private final String requestUrl = OaType.WETALK.getUrl(); private final String requestUrl = OaType.WE_TALK.getUrl();
@Override @Override
public String getSupplier() { public String getSupplier() {
return OaType.WETALK.getType(); return OaType.WE_TALK.getType();
} }
} }

View File

@ -25,7 +25,7 @@ public class WeTalkFactory extends OaAbstractProviderFactory<WeTalkOaImpl, WeTal
@Override @Override
public String getSupplier() { public String getSupplier() {
return OaContent.WETALK; return OaContent.WE_TALK;
} }
/** /**

View File

@ -14,9 +14,8 @@ import org.dromara.oa.core.weTalk.utils.WeTalkBuilder;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import static org.dromara.oa.comm.enums.OaType.WETALK; import static org.dromara.oa.comm.enums.OaType.WE_TALK;
/** /**
* @author dongfeng * @author dongfeng
@ -33,19 +32,17 @@ public class WeTalkOaImpl extends AbstractOaBlend<WeTalkConfig> {
@Override @Override
public String getSupplier() { public String getSupplier() {
return OaType.WETALK.getType(); return OaType.WE_TALK.getType();
} }
@Override @Override
public Response sender(Request request, MessageType messageType) { public Response sender(Request request, MessageType messageType) {
if (Objects.isNull(request.getContent())) {
throw new OaException("消息体content不能为空");
}
StringBuilder webhook = new StringBuilder(); StringBuilder webhook = new StringBuilder();
JSONObject message = null; JSONObject message = null;
WeTalkConfig config = getConfig(); WeTalkConfig config = getConfig();
webhook.append(WETALK.getUrl()); webhook.append(WE_TALK.getUrl());
webhook.append(config.getTokenId()); webhook.append(config.getTokenId());
message = WeTalkBuilder.createWeTalkMessage(request, messageType); message = WeTalkBuilder.createWeTalkMessage(request, messageType);
String post; String post;

View File

@ -5,13 +5,16 @@ import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.oa.comm.entity.Request; import org.dromara.oa.comm.entity.Request;
import org.dromara.oa.comm.entity.WeTalkRequestArticle;
import org.dromara.oa.comm.enums.MessageType; import org.dromara.oa.comm.enums.MessageType;
import org.dromara.oa.comm.errors.OaException;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import static org.dromara.oa.comm.enums.MessageType.WETETALK_MARKDOWN; import static org.dromara.oa.comm.enums.MessageType.WE_TALK_MARKDOWN;
import static org.dromara.oa.comm.enums.MessageType.WETETALK_TEXT; import static org.dromara.oa.comm.enums.MessageType.WE_TALK_NEWS;
import static org.dromara.oa.comm.enums.MessageType.WE_TALK_TEXT;
/** /**
@ -30,7 +33,10 @@ public class WeTalkBuilder {
List<String> phoneList = request.getPhoneList(); List<String> phoneList = request.getPhoneList();
StringBuilder content = new StringBuilder(); StringBuilder content = new StringBuilder();
Boolean isNoticeAll = request.getIsNoticeAll(); Boolean isNoticeAll = request.getIsNoticeAll();
if (messageType == WETETALK_TEXT) { if (messageType == WE_TALK_TEXT) {
if (Objects.isNull(request.getContent())) {
throw new OaException("消息体content不能为空");
}
message.set("msgtype", "text"); message.set("msgtype", "text");
JSONObject text = new JSONObject(); JSONObject text = new JSONObject();
text.set("content", request.getContent()); text.set("content", request.getContent());
@ -58,7 +64,10 @@ public class WeTalkBuilder {
text.set("mentioned_mobile_list",phoneArray); text.set("mentioned_mobile_list",phoneArray);
} }
message.set("text", text); message.set("text", text);
} else if (messageType == WETETALK_MARKDOWN) { } else if (messageType == WE_TALK_MARKDOWN) {
if (Objects.isNull(request.getContent())) {
throw new OaException("消息体content不能为空");
}
message.set("msgtype", "markdown"); message.set("msgtype", "markdown");
if(!Objects.isNull(userIdList)){ if(!Objects.isNull(userIdList)){
userIdList.forEach(l -> content.append("<@").append(l).append(">")); userIdList.forEach(l -> content.append("<@").append(l).append(">"));
@ -69,8 +78,25 @@ public class WeTalkBuilder {
markdown.set("content", content ); markdown.set("content", content );
markdown.set("title", request.getTitle()); markdown.set("title", request.getTitle());
message.set("markdown", markdown); message.set("markdown", markdown);
} else if (messageType == WE_TALK_NEWS) {
message.set("msgtype", "news");
JSONObject news = new JSONObject();
JSONArray articles = new JSONArray();
List<WeTalkRequestArticle> articleList = request.getArticleList();
if(!articleList.isEmpty()){
articleList.forEach(article -> {
JSONObject articleJson = new JSONObject();
articleJson.set("title", article.getTitle());
articleJson.set("description", article.getDescription());
articleJson.set("url", article.getUrl());
articleJson.set("picurl", article.getPicUrl());
articles.add(articleJson);
});
}
news.set("articles", articles );
message.set("news", news);
} else { } else {
log.error("输入的消息格式不对,message:"+messageType+"应该使用WETETALK前缀的消息类型"); log.error("输入的消息格式不对,message:"+messageType+"应该使用WE_TALK前缀的消息类型");
} }
return message; return message;
} }

View File

@ -3,6 +3,7 @@ package org.dromara.sms4j.huawei.utils;
import cn.hutool.core.codec.Base64; import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import org.dromara.sms4j.comm.constant.Constant; import org.dromara.sms4j.comm.constant.Constant;
import org.dromara.sms4j.comm.exception.SmsBlendException;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
@ -38,14 +39,14 @@ public class HuaweiBuilder {
// Nonce // Nonce
String nonce = UUID.randomUUID().toString().replace("-", ""); String nonce = UUID.randomUUID().toString().replace("-", "");
MessageDigest md; MessageDigest md;
byte[] passwordDigest = null; byte[] passwordDigest;
try { try {
md = MessageDigest.getInstance("SHA-256"); md = MessageDigest.getInstance("SHA-256");
md.update((nonce + time + appSecret).getBytes()); md.update((nonce + time + appSecret).getBytes());
passwordDigest = md.digest(); passwordDigest = md.digest();
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
e.printStackTrace(); throw new SmsBlendException(e);
} }
// PasswordDigest // PasswordDigest
String passwordDigestBase64Str = Base64.encode(passwordDigest); String passwordDigestBase64Str = Base64.encode(passwordDigest);
@ -111,13 +112,13 @@ public class HuaweiBuilder {
} }
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
String temp = ""; String temp;
for (String s : map.keySet()) { for (String s : map.keySet()) {
try { try {
temp = URLEncoder.encode(map.get(s), "UTF-8"); temp = URLEncoder.encode(map.get(s), "UTF-8");
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
e.printStackTrace(); throw new SmsBlendException(e);
} }
sb.append(s).append("=").append(temp).append("&"); sb.append(s).append("=").append(temp).append("&");
} }
@ -126,6 +127,9 @@ public class HuaweiBuilder {
} }
public static String listToString(List<String> list) { public static String listToString(List<String> list) {
if (null == list || list.isEmpty()) {
return null;
}
StringBuilder stringBuffer = new StringBuilder(); StringBuilder stringBuffer = new StringBuilder();
stringBuffer.append("[\""); stringBuffer.append("[\"");
for (String s : list) { for (String s : list) {

View File

@ -4,6 +4,9 @@ import org.dromara.sms4j.comm.constant.SupplierConstant;
import org.dromara.sms4j.lianlu.service.LianLuSmsImpl; import org.dromara.sms4j.lianlu.service.LianLuSmsImpl;
import org.dromara.sms4j.provider.factory.BaseProviderFactory; import org.dromara.sms4j.provider.factory.BaseProviderFactory;
/**
* 联鹿短信
* */
public class LianLuFactory implements BaseProviderFactory<LianLuSmsImpl, LianLuConfig> { public class LianLuFactory implements BaseProviderFactory<LianLuSmsImpl, LianLuConfig> {
private static final LianLuFactory INSTANCE = new LianLuFactory(); private static final LianLuFactory INSTANCE = new LianLuFactory();

View File

@ -6,6 +6,7 @@ import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONArray; import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.sms4j.api.entity.SmsResponse; import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.comm.constant.Constant; import org.dromara.sms4j.comm.constant.Constant;
@ -121,7 +122,14 @@ public class NeteaseSmsImpl extends AbstractSmsBlend<NeteaseConfig> {
JSONArray jsonArray = new JSONArray(); JSONArray jsonArray = new JSONArray();
jsonArray.addAll(phones); jsonArray.addAll(phones);
body.put("mobiles", jsonArray.toString()); body.put("mobiles", jsonArray.toString());
body.put("params", message); //保证模板变量参数使用jsonarray传递
if (!JSONUtil.isTypeJSONArray(message)) {
jsonArray = new JSONArray();
jsonArray.add(message);
body.put("params", jsonArray.toString());
}else {
body.put("params", message);
}
body.put("needUp", getConfig().getNeedUp()); body.put("needUp", getConfig().getNeedUp());
Map<String, String> headers = MapUtil.newHashMap(5, true); Map<String, String> headers = MapUtil.newHashMap(5, true);
@ -132,7 +140,7 @@ public class NeteaseSmsImpl extends AbstractSmsBlend<NeteaseConfig> {
headers.put("CheckSum", checkSum); headers.put("CheckSum", checkSum);
SmsResponse smsResponse; SmsResponse smsResponse;
try { try {
smsResponse = getResponse(http.postJson(requestUrl, headers, body)); smsResponse = getResponse(http.postFrom(requestUrl, headers, body));
} catch (SmsBlendException e) { } catch (SmsBlendException e) {
smsResponse = new SmsResponse(); smsResponse = new SmsResponse();
smsResponse.setSuccess(false); smsResponse.setSuccess(false);

View File

@ -15,14 +15,29 @@ import org.dromara.sms4j.provider.config.BaseConfig;
public class QiNiuConfig extends BaseConfig { public class QiNiuConfig extends BaseConfig {
/**
* 请求地址
*/
private String baseUrl = "https://sms.qiniuapi.com"; private String baseUrl = "https://sms.qiniuapi.com";
/**
* 模板变量名称
*/
private String templateName; private String templateName;
/**
* 单发链接
*/
private String singleMsgUrl = "/v1/message/single"; private String singleMsgUrl = "/v1/message/single";
/**
* 群发链接
* */
private String massMsgUrl = "/v1/message"; private String massMsgUrl = "/v1/message";
/**
* 签名ID
* */
private String signatureId; private String signatureId;
@Override @Override

View File

@ -6,6 +6,9 @@ import org.dromara.sms4j.comm.constant.SupplierConstant;
import org.dromara.sms4j.provider.factory.AbstractProviderFactory; import org.dromara.sms4j.provider.factory.AbstractProviderFactory;
import org.dromara.sms4j.zhutong.service.ZhutongSmsImpl; import org.dromara.sms4j.zhutong.service.ZhutongSmsImpl;
/**
* 助通短信
* */
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ZhutongFactory extends AbstractProviderFactory<ZhutongSmsImpl, ZhutongConfig> { public class ZhutongFactory extends AbstractProviderFactory<ZhutongSmsImpl, ZhutongConfig> {
private static final ZhutongFactory INSTANCE = new ZhutongFactory(); private static final ZhutongFactory INSTANCE = new ZhutongFactory();

View File

@ -150,7 +150,7 @@ public class ZhutongSmsImpl extends AbstractSmsBlend<ZhutongConfig> {
headers.put("Content-Type", Constant.APPLICATION_JSON_UTF8); headers.put("Content-Type", Constant.APPLICATION_JSON_UTF8);
SmsResponse smsResponse; SmsResponse smsResponse;
try { try {
smsResponse = getResponse(http.postJson(requestUrl, headers, json)); smsResponse = getResponse(http.postJson(url, headers, json));
} catch (SmsBlendException e) { } catch (SmsBlendException e) {
smsResponse = new SmsResponse(); smsResponse = new SmsResponse();
smsResponse.setSuccess(false); smsResponse.setSuccess(false);
@ -238,7 +238,7 @@ public class ZhutongSmsImpl extends AbstractSmsBlend<ZhutongConfig> {
headers.put("Content-Type", Constant.APPLICATION_JSON_UTF8); headers.put("Content-Type", Constant.APPLICATION_JSON_UTF8);
SmsResponse smsResponse; SmsResponse smsResponse;
try { try {
smsResponse = getResponse(http.postJson(requestUrl, headers, requestJson.toString())); smsResponse = getResponse(http.postJson(url, headers, requestJson.toString()));
} catch (SmsBlendException e) { } catch (SmsBlendException e) {
smsResponse = new SmsResponse(); smsResponse = new SmsResponse();
smsResponse.setSuccess(false); smsResponse.setSuccess(false);

View File

@ -3,6 +3,7 @@ package org.dromara.sms4j.example;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.oa.api.OaSender; import org.dromara.oa.api.OaSender;
import org.dromara.oa.comm.entity.Request; import org.dromara.oa.comm.entity.Request;
import org.dromara.oa.comm.entity.WeTalkRequestArticle;
import org.dromara.oa.comm.enums.MessageType; import org.dromara.oa.comm.enums.MessageType;
import org.dromara.oa.core.byteTalk.config.ByteTalkConfig; import org.dromara.oa.core.byteTalk.config.ByteTalkConfig;
import org.dromara.oa.core.dingTalk.config.DingTalkConfig; import org.dromara.oa.core.dingTalk.config.DingTalkConfig;
@ -58,7 +59,7 @@ public class SmsOaTest {
// request.setIsNoticeAll(true); // request.setIsNoticeAll(true);
request.setContent("测试消息"); request.setContent("测试消息");
alarm.sender(request, MessageType.DINGTALK_TEXT); alarm.sender(request, MessageType.DING_TALK_TEXT);
} }
@ -82,7 +83,7 @@ public class SmsOaTest {
request.setIsNoticeAll(true); request.setIsNoticeAll(true);
request.setContent("#### 杭州天气 @150XXXXXXXX \n > 9度西北风1级空气良89相对温度73%\n > ![screenshot](https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png)\n > ###### 10点20分发布 [天气](https://www.dingtalk.com) \n"); request.setContent("#### 杭州天气 @150XXXXXXXX \n > 9度西北风1级空气良89相对温度73%\n > ![screenshot](https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png)\n > ###### 10点20分发布 [天气](https://www.dingtalk.com) \n");
request.setTitle("标题"); request.setTitle("标题");
alarm.sender(request, MessageType.DINGTALK_MARKDOWN); alarm.sender(request, MessageType.DING_TALK_MARKDOWN);
} }
@ -106,10 +107,9 @@ public class SmsOaTest {
request.setTitle("点击跳转到钉钉"); request.setTitle("点击跳转到钉钉");
request.setMessageUrl("https://www.dingtalk.com/s?__biz=MzA4NjMwMTA2Ng==&mid=2650316842&idx=1&sn=60da3ea2b29f1dcc43a7c8e4a7c97a16&scene=2&srcid=09189AnRJEdIiWVaKltFzNTw&from=timeline&isappinstalled=0&key=&ascene=2&uin=&devicetype=android-23&version=26031933&nettype=WIFI"); request.setMessageUrl("https://www.dingtalk.com/s?__biz=MzA4NjMwMTA2Ng==&mid=2650316842&idx=1&sn=60da3ea2b29f1dcc43a7c8e4a7c97a16&scene=2&srcid=09189AnRJEdIiWVaKltFzNTw&from=timeline&isappinstalled=0&key=&ascene=2&uin=&devicetype=android-23&version=26031933&nettype=WIFI");
request.setPicUrl("https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png"); request.setPicUrl("https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png");
alarm.sender(request, MessageType.DING_TALK_LINK);
alarm.sender(request, MessageType.DINGTALK_LINK);
} }
/** /**
@ -138,8 +138,8 @@ public class SmsOaTest {
request.setContent("测试消息"); request.setContent("测试消息");
// 异步发送方式 // 异步发送方式
alarm.senderAsync(request, MessageType.DINGTALK_TEXT); alarm.senderAsync(request, MessageType.DING_TALK_TEXT);
alarm.senderAsync(request, MessageType.DINGTALK_TEXT, smsResponse -> System.out.println("ConfigId为" + smsResponse.getOaConfigId() + "的异步任务发送成功")); alarm.senderAsync(request, MessageType.DING_TALK_TEXT, smsResponse -> System.out.println("ConfigId为" + smsResponse.getOaConfigId() + "的异步任务发送成功"));
try { try {
Thread.sleep(3000L); Thread.sleep(3000L);
@ -183,7 +183,7 @@ public class SmsOaTest {
request.setPriority(priority); request.setPriority(priority);
//测试-1-TEXT //测试-1-TEXT
request.setContent("该消息优先级为" + priority); request.setContent("该消息优先级为" + priority);
alarm.senderAsyncByPriority(request, MessageType.DINGTALK_TEXT); alarm.senderAsyncByPriority(request, MessageType.DING_TALK_TEXT);
System.out.println("优先级为" + priority + "的异步任务已提交"); System.out.println("优先级为" + priority + "的异步任务已提交");
}).start(); }).start();
@ -210,7 +210,7 @@ public class SmsOaTest {
// 支持@all // 支持@all
// request.setIsNoticeAll(true); // request.setIsNoticeAll(true);
request.setContent("测试消息"); request.setContent("测试消息");
alarm.sender(request, MessageType.DINGTALK_TEXT); alarm.sender(request, MessageType.DING_TALK_TEXT);
} }
//***********************ByteTalk-Test************************// //***********************ByteTalk-Test************************//
/** /**
@ -247,7 +247,7 @@ public class SmsOaTest {
request.setUserIdList(userIds); request.setUserIdList(userIds);
request.setIsNoticeAll(true); request.setIsNoticeAll(true);
request.setContent("测试消息"); request.setContent("测试消息");
alarm.sender(request, MessageType.BYTETALK_TEXT); alarm.sender(request, MessageType.BYTE_TALK_TEXT);
} }
@ -273,8 +273,8 @@ public class SmsOaTest {
request.setIsNoticeAll(true); request.setIsNoticeAll(true);
request.setContent("测试消息"); request.setContent("测试消息");
alarm.senderAsync(request, MessageType.BYTETALK_TEXT); alarm.senderAsync(request, MessageType.BYTE_TALK_TEXT);
alarm.senderAsync(request, MessageType.BYTETALK_TEXT, smsResponse -> System.out.println("ConfigId为" + smsResponse.getOaConfigId() + "的异步任务发送成功")); alarm.senderAsync(request, MessageType.BYTE_TALK_TEXT, smsResponse -> System.out.println("ConfigId为" + smsResponse.getOaConfigId() + "的异步任务发送成功"));
// 防止主线程挂掉 // 防止主线程挂掉
try { try {
@ -294,7 +294,7 @@ public class SmsOaTest {
request.setUserIdList(userIds); request.setUserIdList(userIds);
request.setIsNoticeAll(true); request.setIsNoticeAll(true);
request.setContent("测试消息"); request.setContent("测试消息");
alarm.sender(request, MessageType.BYTETALK_TEXT); alarm.sender(request, MessageType.BYTE_TALK_TEXT);
} }
//***********************WeTalk-Test************************// //***********************WeTalk-Test************************//
/** /**
@ -332,7 +332,7 @@ public class SmsOaTest {
request.setIsNoticeAll(true); request.setIsNoticeAll(true);
request.setContent("测试消息"); request.setContent("测试消息");
alarm.sender(request, MessageType.WETETALK_TEXT); alarm.sender(request, MessageType.WE_TALK_TEXT);
} }
@ -362,11 +362,32 @@ public class SmsOaTest {
">普通用户反馈:<font color=\"comment\">117例</font>" + ">普通用户反馈:<font color=\"comment\">117例</font>" +
">VIP用户反馈:<font color=\"comment\">15例</font>"); ">VIP用户反馈:<font color=\"comment\">15例</font>");
alarm.sender(request, MessageType.WETETALK_MARKDOWN); alarm.sender(request, MessageType.WE_TALK_MARKDOWN);
} }
/**
* WeTalk的News测试
*/
@Test
public void oaWeTalkNews() {
String key = "oaWeTalk";
WeTalkConfig WeTalkConfig = new WeTalkConfig();
WeTalkConfig.setConfigId(key);
WeTalkConfig.setTokenId(WeTalkTOKENID);
// 根据配置创建服务实例并注册
OaFactory.createAndRegisterOaSender(WeTalkConfig);
OaSender alarm = OaFactory.getSmsOaBlend(key);
Request request = new Request();
ArrayList<WeTalkRequestArticle> articles = new ArrayList<>();
articles.add(new WeTalkRequestArticle("中秋节礼品领取", "今年中秋节公司有豪礼相送", "www.qq.com", "http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png"));
request.setArticleList(articles);
alarm.sender(request, MessageType.WE_TALK_NEWS);
}
/** /**
* WeTalk的异步消息发送 * WeTalk的异步消息发送
@ -391,8 +412,8 @@ public class SmsOaTest {
request.setContent("测试消息"); request.setContent("测试消息");
// 异步发送方式 // 异步发送方式
alarm.senderAsync(request, MessageType.WETETALK_TEXT); alarm.senderAsync(request, MessageType.WE_TALK_TEXT);
alarm.senderAsync(request, MessageType.WETETALK_TEXT, smsResponse -> System.out.println("ConfigId为" + smsResponse.getOaConfigId() + "的异步任务发送成功")); alarm.senderAsync(request, MessageType.WE_TALK_TEXT, smsResponse -> System.out.println("ConfigId为" + smsResponse.getOaConfigId() + "的异步任务发送成功"));
// 防止主线程挂掉 // 防止主线程挂掉
try { try {
@ -401,6 +422,7 @@ public class SmsOaTest {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
@Test @Test
public void oaWeTalkByYamlTest() { public void oaWeTalkByYamlTest() {
String configId = "oaWeTalkByYaml"; String configId = "oaWeTalkByYaml";
@ -411,7 +433,7 @@ public class SmsOaTest {
request.setPhoneList(phones); request.setPhoneList(phones);
request.setIsNoticeAll(true); request.setIsNoticeAll(true);
request.setContent("SMS4JContent"); request.setContent("SMS4JContent");
alarm.sender(request, MessageType.WETETALK_TEXT); alarm.sender(request, MessageType.WE_TALK_TEXT);
} }
} }

View File

@ -8,6 +8,7 @@ import org.dromara.sms4j.aliyun.config.AlibabaFactory;
import org.dromara.sms4j.api.SmsBlend; import org.dromara.sms4j.api.SmsBlend;
import org.dromara.sms4j.api.universal.SupplierConfig; import org.dromara.sms4j.api.universal.SupplierConfig;
import org.dromara.sms4j.budingyun.config.BudingV2Factory; import org.dromara.sms4j.budingyun.config.BudingV2Factory;
import org.dromara.sms4j.api.verify.PhoneVerify;
import org.dromara.sms4j.cloopen.config.CloopenFactory; import org.dromara.sms4j.cloopen.config.CloopenFactory;
import org.dromara.sms4j.comm.constant.Constant; import org.dromara.sms4j.comm.constant.Constant;
import org.dromara.sms4j.comm.enumerate.ConfigType; import org.dromara.sms4j.comm.enumerate.ConfigType;
@ -42,10 +43,11 @@ import org.springframework.beans.factory.ObjectProvider;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.ServiceLoader;
@Slf4j @Slf4j
public class SmsBlendsInitializer { public class SmsBlendsInitializer {
private final List<BaseProviderFactory<? extends SmsBlend, ? extends SupplierConfig>> factoryList; private final List<BaseProviderFactory<? extends SmsBlend, ? extends SupplierConfig>> factoryList;
private final SmsConfig smsConfig; private final SmsConfig smsConfig;
@ -55,7 +57,7 @@ public class SmsBlendsInitializer {
public SmsBlendsInitializer(List<BaseProviderFactory<? extends SmsBlend, ? extends SupplierConfig>> factoryList, public SmsBlendsInitializer(List<BaseProviderFactory<? extends SmsBlend, ? extends SupplierConfig>> factoryList,
SmsConfig smsConfig, SmsConfig smsConfig,
Map<String, Map<String, Object>> blends, Map<String, Map<String, Object>> blends,
ObjectProvider<SmsReadConfig> extendsSmsConfigs){ ObjectProvider<SmsReadConfig> extendsSmsConfigs) {
this.factoryList = factoryList; this.factoryList = factoryList;
this.smsConfig = smsConfig; this.smsConfig = smsConfig;
this.blends = blends; this.blends = blends;
@ -68,7 +70,7 @@ public class SmsBlendsInitializer {
// 注册短信对象工厂 // 注册短信对象工厂
ProviderFactoryHolder.registerFactory(factoryList); ProviderFactoryHolder.registerFactory(factoryList);
if(ConfigType.YAML.equals(this.smsConfig.getConfigType())) { if (ConfigType.YAML.equals(this.smsConfig.getConfigType())) {
//持有初始化配置信息 //持有初始化配置信息
Map<String, Map<String, Object>> blendsInclude = new ConfigCombineMapAdeptor<String, Map<String, Object>>(); Map<String, Map<String, Object>> blendsInclude = new ConfigCombineMapAdeptor<String, Map<String, Object>>();
blendsInclude.putAll(this.blends); blendsInclude.putAll(this.blends);
@ -76,8 +78,8 @@ public class SmsBlendsInitializer {
for (SmsReadConfig smsReadConfig : extendsSmsConfigs) { for (SmsReadConfig smsReadConfig : extendsSmsConfigs) {
String key = SmsReadConfig.class.getSimpleName() + num; String key = SmsReadConfig.class.getSimpleName() + num;
Map<String, Object> insideMap = new HashMap<>(); Map<String, Object> insideMap = new HashMap<>();
insideMap.put(key,smsReadConfig); insideMap.put(key, smsReadConfig);
blendsInclude.put(key,insideMap); blendsInclude.put(key, insideMap);
num++; num++;
} }
EnvirmentHolder.frozenEnvirmet(smsConfig, blendsInclude); EnvirmentHolder.frozenEnvirmet(smsConfig, blendsInclude);
@ -86,15 +88,24 @@ public class SmsBlendsInitializer {
SmsProxyFactory.addProcessor(new BlackListProcessor()); SmsProxyFactory.addProcessor(new BlackListProcessor());
SmsProxyFactory.addProcessor(new BlackListRecordingProcessor()); SmsProxyFactory.addProcessor(new BlackListRecordingProcessor());
SmsProxyFactory.addProcessor(new SingleBlendRestrictedProcessor()); SmsProxyFactory.addProcessor(new SingleBlendRestrictedProcessor());
SmsProxyFactory.addProcessor(new CoreMethodParamValidateProcessor()); //如果手机号校验器存在实现则注册手机号校验器
ServiceLoader<PhoneVerify> loader = ServiceLoader.load(PhoneVerify.class);
if (loader.iterator().hasNext()) {
loader.forEach(f->{
SmsProxyFactory.addProcessor(new CoreMethodParamValidateProcessor(f));
});
}else {
SmsProxyFactory.addProcessor(new CoreMethodParamValidateProcessor(null));
}
// 解析供应商配置 // 解析供应商配置
for(String configId : blends.keySet()) { for (String configId : blends.keySet()) {
Map<String, Object> configMap = blends.get(configId); Map<String, Object> configMap = blends.get(configId);
Object supplierObj = configMap.get(Constant.SUPPLIER_KEY); Object supplierObj = configMap.get(Constant.SUPPLIER_KEY);
String supplier = supplierObj == null ? "" : String.valueOf(supplierObj); String supplier = supplierObj == null ? "" : String.valueOf(supplierObj);
supplier = StrUtil.isEmpty(supplier) ? configId : supplier; supplier = StrUtil.isEmpty(supplier) ? configId : supplier;
BaseProviderFactory<SmsBlend, SupplierConfig> providerFactory = (BaseProviderFactory<SmsBlend, org.dromara.sms4j.api.universal.SupplierConfig>) ProviderFactoryHolder.requireForSupplier(supplier); BaseProviderFactory<SmsBlend, SupplierConfig> providerFactory = (BaseProviderFactory<SmsBlend, org.dromara.sms4j.api.universal.SupplierConfig>) ProviderFactoryHolder.requireForSupplier(supplier);
if(providerFactory == null) { if (providerFactory == null) {
log.warn("创建\"{}\"的短信服务失败,未找到供应商为\"{}\"的服务", configId, supplier); log.warn("创建\"{}\"的短信服务失败,未找到供应商为\"{}\"的服务", configId, supplier);
continue; continue;
} }
@ -128,6 +139,7 @@ public class SmsBlendsInitializer {
ProviderFactoryHolder.registerFactory(QiNiuFactory.instance()); ProviderFactoryHolder.registerFactory(QiNiuFactory.instance());
ProviderFactoryHolder.registerFactory(BudingV2Factory.instance()); ProviderFactoryHolder.registerFactory(BudingV2Factory.instance());
if(SmsUtils.isClassExists("com.jdcloud.sdk.auth.CredentialsProvider")) { if(SmsUtils.isClassExists("com.jdcloud.sdk.auth.CredentialsProvider")) {
if (SmsUtils.isClassExists("com.jdcloud.sdk.auth.CredentialsProvider")) {
ProviderFactoryHolder.registerFactory(JdCloudFactory.instance()); ProviderFactoryHolder.registerFactory(JdCloudFactory.instance());
} }
log.debug("加载内置运营商完成!"); log.debug("加载内置运营商完成!");