diff --git a/pom.xml b/pom.xml index af5bda5c..d136db3b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ kim.wind sms_aggregation 1.0.0 - sms_aggregation + sms-aggregation pom sms_aggregation https://gitee.com/the-wind-is-like-a-song/sms_aggregation @@ -52,6 +52,7 @@ 2.0.23 2.0.15 3.14.9 + 0.0.4 @@ -101,12 +102,14 @@ ${modules.version} + kim.wind sms-aggregation-comm ${modules.version} + kim.wind sms-aggregation-api @@ -155,6 +158,13 @@ provided + + + com.apistd.uni + uni-sdk + ${unisms.version} + + @@ -165,6 +175,7 @@ true + org.springframework.boot spring-boot-configuration-processor @@ -186,90 +197,90 @@ - - - - org.apache.maven.plugins - maven-source-plugin - 2.2.1 - - - package - - jar-no-fork - - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.9.1 - - private - true - UTF-8 - UTF-8 - UTF-8 - -Xdoclint:none - - - - - package - - jar - - - - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.6 - - - verify - - sign - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.0 - - 1.8 - 1.8 - true - true - UTF-8 - - - - - org.apache.maven.plugins - maven-release-plugin - 2.5.1 - - - org.apache.maven.plugins - maven-jar-plugin - 3.2.2 - - - - true - - - - + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + package + + jar-no-fork + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + private + true + UTF-8 + UTF-8 + UTF-8 + -Xdoclint:none + + + + + package + + jar + + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + verify + + sign + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.0 + + 1.8 + 1.8 + true + true + UTF-8 + + + + + org.apache.maven.plugins + maven-release-plugin + 2.5.1 + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.2 + + + + true + + + + - + diff --git a/sms-aggregation-aliyun/src/main/java/kim/wind/sms/aliyun/service/AlibabaSmsImpl.java b/sms-aggregation-aliyun/src/main/java/kim/wind/sms/aliyun/service/AlibabaSmsImpl.java index 5e215c4a..4977957a 100644 --- a/sms-aggregation-aliyun/src/main/java/kim/wind/sms/aliyun/service/AlibabaSmsImpl.java +++ b/sms-aggregation-aliyun/src/main/java/kim/wind/sms/aliyun/service/AlibabaSmsImpl.java @@ -26,6 +26,13 @@ import java.util.List; import java.util.TimerTask; import java.util.concurrent.Executor; +/** + *

类名: AlibabaSmsImpl + *

说明: 阿里云短信实现 + * + * @author :Wind + * 2023/3/26 17:16 + **/ @EnableConfigurationProperties({AlibabaSmsConfig.class}) @Slf4j public class AlibabaSmsImpl implements SmsBlend { @@ -132,6 +139,13 @@ public class AlibabaSmsImpl implements SmsBlend { }); } + @Override + public void sendMessageAsync(String phone, String message) { + pool.execute(() -> { + sendMessage(phone, message); + }); + } + @Override @Restricted public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages, CallBack callBack) { @@ -141,6 +155,13 @@ public class AlibabaSmsImpl implements SmsBlend { }); } + @Override + public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages) { + pool.execute(()->{ + sendMessage(phone,templateId,messages); + }); + } + @Override @Restricted public void delayedMessage(String phone, String message, Long delayedTime) { @@ -162,4 +183,24 @@ public class AlibabaSmsImpl implements SmsBlend { } },delayedTime); } + + @Override + public void delayMassTexting(List phones, String message, Long delayedTime) { + this.delayed.schedule(new TimerTask() { + @Override + public void run() { + massTexting(phones,message); + } + },delayedTime); + } + + @Override + public void delayMassTexting(List phones, String templateId, LinkedHashMap messages, Long delayedTime) { + this.delayed.schedule(new TimerTask() { + @Override + public void run() { + massTexting(phones,templateId,messages); + } + },delayedTime); + } } diff --git a/sms-aggregation-api/src/main/java/kim/wind/sms/api/SmsBlend.java b/sms-aggregation-api/src/main/java/kim/wind/sms/api/SmsBlend.java index f65ffaeb..8f96b7bd 100644 --- a/sms-aggregation-api/src/main/java/kim/wind/sms/api/SmsBlend.java +++ b/sms-aggregation-api/src/main/java/kim/wind/sms/api/SmsBlend.java @@ -58,6 +58,15 @@ public interface SmsBlend { void sendMessageAsync(String phone, String message, CallBack callBack); + /** + *

说明:异步发送短信,不关注发送结果 + * sendMessageAsync + * @param phone 要发送的号码 + * @param message 发送内容 + * @author :Wind + */ + void sendMessageAsync(String phone, String message); + /** *

说明:异步短信发送,使用自定义模板发送短信 * sendMessage @@ -70,7 +79,16 @@ public interface SmsBlend { void sendMessageAsync(String phone, String templateId, LinkedHashMap messages, CallBack callBack); /** - *

说明: + *

说明:异步短信发送,使用自定义模板发送短信,不关注发送结果 + * sendMessageAsync + * @param templateId 模板id + * @param messages key为模板变量名称 value为模板变量值 + * @author :Wind + */ + void sendMessageAsync(String phone, String templateId, LinkedHashMap messages); + + /** + *

说明:使用固定模板发送延时短信 * delayedMessage * @param phone 接收短信的手机号 * @param message 要发送的短信 @@ -89,4 +107,23 @@ public interface SmsBlend { * @author :Wind */ void delayedMessage(String phone ,String templateId, LinkedHashMap messages,Long delayedTime); + + /** + *

说明:群发延迟短信 + * delayMassTexting + * @param phones 要群体发送的手机号码 + * @author :Wind + */ + void delayMassTexting(List phones, String message,Long delayedTime); + + /** + *

说明:使用自定义模板发送群体延迟短信 + * delayMassTexting + * @param phones 要群体发送的手机号码 + * @param templateId 模板id + * @param messages key为模板变量名称 value为模板变量值 + * @param delayedTime 延迟的时间 + * @author :Wind + */ + void delayMassTexting(List phones,String templateId, LinkedHashMap messages,Long delayedTime); } diff --git a/sms-aggregation-comm/src/main/java/kim/wind/sms/comm/annotation/Restricted.java b/sms-aggregation-comm/src/main/java/kim/wind/sms/comm/annotation/Restricted.java index 251f87cd..23c44c3a 100644 --- a/sms-aggregation-comm/src/main/java/kim/wind/sms/comm/annotation/Restricted.java +++ b/sms-aggregation-comm/src/main/java/kim/wind/sms/comm/annotation/Restricted.java @@ -6,6 +6,13 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + *

类名: Restricted + *

说明: 发送短信限制 + * + * @author :Wind + * 2023/3/26 17:12 + **/ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Restricted { diff --git a/sms-aggregation-spring-boot-starter/src/main/java/kim/wind/sms/starter/config/SmsMainConfig.java b/sms-aggregation-spring-boot-starter/src/main/java/kim/wind/sms/starter/config/SmsMainConfig.java index 289bf1ee..f3b557ea 100644 --- a/sms-aggregation-spring-boot-starter/src/main/java/kim/wind/sms/starter/config/SmsMainConfig.java +++ b/sms-aggregation-spring-boot-starter/src/main/java/kim/wind/sms/starter/config/SmsMainConfig.java @@ -1,5 +1,6 @@ package kim.wind.sms.starter.config; +import com.example.sms.unisms.service.UniSmsImpl; import kim.wind.sms.aliyun.service.AlibabaSmsImpl; import kim.wind.sms.api.SmsBlend; import kim.wind.sms.comm.delayedTime.DelayedTime; @@ -69,6 +70,10 @@ public class SmsMainConfig { switch (supplier){ case "alibaba": smsBlend = new AlibabaSmsImpl(); + break; + case "uniSms": + smsBlend = new UniSmsImpl(); + break; } return smsBlend; } @@ -79,8 +84,8 @@ public class SmsMainConfig { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(corePoolSize); executor.setMaxPoolSize(maxPoolSize); - executor.setQueueCapacity(100); - executor.setKeepAliveSeconds(60); + executor.setQueueCapacity(queueCapacity); + executor.setKeepAliveSeconds(keepAliveSeconds); executor.setThreadNamePrefix(threadNamePrefix); executor.setWaitForTasksToCompleteOnShutdown(true); // 线程池对拒绝任务的处理策略,当线程池没有处理能力的时候,该策略会直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务 @@ -103,6 +108,7 @@ public class SmsMainConfig { return new RedisUtils(redisTemplate); } + /** 注入一个定时器*/ @Bean public DelayedTime delayedTime(){ return new DelayedTime(); diff --git a/sms-aggregation-unisms/pom.xml b/sms-aggregation-unisms/pom.xml index db8d2a1b..cb23236e 100644 --- a/sms-aggregation-unisms/pom.xml +++ b/sms-aggregation-unisms/pom.xml @@ -18,6 +18,20 @@ + + com.apistd.uni + uni-sdk + + + + kim.wind + sms-aggregation-comm + + + + kim.wind + sms-aggregation-api + diff --git a/sms-aggregation-unisms/src/main/java/com/example/sms/unisms/config/UniSmsConfig.java b/sms-aggregation-unisms/src/main/java/com/example/sms/unisms/config/UniSmsConfig.java new file mode 100644 index 00000000..b570a347 --- /dev/null +++ b/sms-aggregation-unisms/src/main/java/com/example/sms/unisms/config/UniSmsConfig.java @@ -0,0 +1,38 @@ +package com.example.sms.unisms.config; + +import com.apistd.uni.Uni; +import lombok.Data; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "sms.uni-sms") //指定配置文件注入属性前缀 +@Data +@ConditionalOnProperty(prefix = "sms", name = "supplier", havingValue = "uni-sms") +public class UniSmsConfig { + + /** 访问键标识*/ + private String accessKeyId; + /** 访问键秘钥 简易模式不需要配置*/ + private String accessKeySecret; + /** 是否为简易模式*/ + private String isSimple = "true"; + /** 短信签名*/ + private String signature; + /** 模板Id*/ + private String templateId; + /** 模板变量名称*/ + private String templateName; + + /** 自动注入短信配置*/ + @Bean + public void buildSms(){ + if ("true".equals(isSimple)){ + Uni.init(accessKeyId); + }else { + Uni.init(accessKeyId,accessKeySecret); + } + } +} diff --git a/sms-aggregation-unisms/src/main/java/com/example/sms/unisms/service/UniSmsImpl.java b/sms-aggregation-unisms/src/main/java/com/example/sms/unisms/service/UniSmsImpl.java new file mode 100644 index 00000000..01710463 --- /dev/null +++ b/sms-aggregation-unisms/src/main/java/com/example/sms/unisms/service/UniSmsImpl.java @@ -0,0 +1,179 @@ +package com.example.sms.unisms.service; + +import com.apistd.uni.UniResponse; +import com.apistd.uni.sms.UniMessage; +import com.apistd.uni.sms.UniSMS; +import com.example.sms.unisms.config.UniSmsConfig; +import kim.wind.sms.api.SmsBlend; +import kim.wind.sms.api.callback.CallBack; +import kim.wind.sms.comm.annotation.Restricted; +import kim.wind.sms.comm.delayedTime.DelayedTime; +import kim.wind.sms.comm.entity.SmsResponse; +import kim.wind.sms.comm.exception.SmsBlendException; +import kim.wind.sms.comm.utils.HTTPUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.EnableConfigurationProperties; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.TimerTask; +import java.util.concurrent.Executor; + + +/** + *

类名: UniSmsImpl + *

说明: uniSms短信实现 + * + * @author :Wind + * 2023/3/26 17:10 + **/ +@EnableConfigurationProperties({UniSmsConfig.class}) +@Slf4j +public class UniSmsImpl implements SmsBlend { + + @Autowired + private UniSmsConfig config; + + @Autowired + @Qualifier("smsExecutor") + private Executor pool; + + @Autowired + private DelayedTime delayed; + + @Override + @Restricted + public SmsResponse sendMessage(String phone, String message) { + if ("".equals(config.getTemplateId()) && "".equals(config.getTemplateName())){ + throw new SmsBlendException("配置文件模板id和模板变量不能为空!"); + } + LinkedHashMapmap = new LinkedHashMap<>(); + map.put(config.getTemplateName(),message); + return sendMessage(phone, config.getTemplateId(),map); + } + + @Override + @Restricted + public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages) { + UniMessage uniMes = UniSMS.buildMessage().setSignature(config.getSignature()).setTo(phone) + .setTemplateId(templateId) + .setTemplateData(messages); + return getSmsResponse(uniMes); + } + + @Override + @Restricted + public SmsResponse massTexting(List phones, String message) { + if ("".equals(config.getTemplateId()) && "".equals(config.getTemplateName())){ + throw new SmsBlendException("配置文件模板id和模板变量不能为空!"); + } + LinkedHashMapmap = new LinkedHashMap<>(); + map.put(config.getTemplateName(),message); + return massTexting(phones, config.getTemplateId(),map); + } + + @Override + @Restricted + public SmsResponse massTexting(List phones, String templateId, LinkedHashMap messages) { + if (phones.size()>1000){ + throw new SmsBlendException("单次发送超过最大发送上限,建议每次群发短信人数低于1000"); + } + String[] s = new String[phones.size()]; + UniMessage uniMes = UniSMS.buildMessage().setSignature(config.getSignature()).setTo(phones.toArray(s)) + .setTemplateId(templateId) + .setTemplateData(messages); + return getSmsResponse(uniMes); + } + + @Override + @Restricted + public void sendMessageAsync(String phone, String message, CallBack callBack) { + pool.execute(()->{ + SmsResponse smsResponse = sendMessage(phone, message); + callBack.callBack(smsResponse); + }); + } + + @Override + public void sendMessageAsync(String phone, String message) { + pool.execute(()->{ + sendMessage(phone, message); + }); + } + + @Override + @Restricted + public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages, CallBack callBack) { + pool.execute(()->{ + SmsResponse smsResponse = sendMessage(phone,templateId,messages); + callBack.callBack(smsResponse); + }); + } + + @Override + public void sendMessageAsync(String phone, String templateId, LinkedHashMap messages) { + pool.execute(()->{ + sendMessage(phone,templateId,messages); + }); + } + + @Override + @Restricted + public void delayedMessage(String phone, String message, Long delayedTime) { + this.delayed.schedule(new TimerTask() { + @Override + public void run() { + sendMessage(phone,message); + } + },delayedTime); + } + + @Override + @Restricted + public void delayedMessage(String phone, String templateId, LinkedHashMap messages, Long delayedTime) { + this.delayed.schedule(new TimerTask() { + @Override + public void run() { + sendMessage(phone,templateId,messages); + } + },delayedTime); + } + + @Override + public void delayMassTexting(List phones, String message, Long delayedTime) { + this.delayed.schedule(new TimerTask() { + @Override + public void run() { + massTexting(phones,message); + } + },delayedTime); + } + + @Override + public void delayMassTexting(List phones, String templateId, LinkedHashMap messages, Long delayedTime) { + this.delayed.schedule(new TimerTask() { + @Override + public void run() { + massTexting(phones,templateId,messages); + } + },delayedTime); + } + + private SmsResponse getSmsResponse(UniMessage uniMes) { + SmsResponse smsResponse = new SmsResponse(); + try { + UniResponse send = uniMes.send(); + smsResponse.setCode(send.status); + smsResponse.setErrorCode(send.code); + smsResponse.setMessage(send.message); + smsResponse.setBizId(send.requestId); + smsResponse.setData(HTTPUtils.getJSONObject(send)); + }catch(Exception e){ + smsResponse.setErrMessage(e.getMessage()); + } + + return smsResponse; + } +}