diff --git a/sms4j-api/src/main/java/org/dromara/sms4j/api/utils/SmsRespUtils.java b/sms4j-api/src/main/java/org/dromara/sms4j/api/utils/SmsRespUtils.java new file mode 100644 index 00000000..865c80c2 --- /dev/null +++ b/sms4j-api/src/main/java/org/dromara/sms4j/api/utils/SmsRespUtils.java @@ -0,0 +1,52 @@ +package org.dromara.sms4j.api.utils; + +import org.dromara.sms4j.api.entity.SmsResponse; + +public class SmsRespUtils { + private SmsRespUtils() { + } //私有构造防止实例化 + + public static SmsResponse error(){ + return error("error no response", null); + } + + public static SmsResponse error(String configId){ + return error("error no response", configId); + } + + public static SmsResponse error(String detailMessage, String configId){ + return resp(detailMessage, false, configId); + } + + public static SmsResponse success(){ + return success(null); + } + + public static SmsResponse success(Object data){ + return success(data, null); + } + + public static SmsResponse resp(Object data, boolean success){ + return resp(data, success, null); + } + + public static SmsResponse success(Object data, String configId){ + return resp(data, true, configId); + } + + public static SmsResponse resp(boolean success){ + return success ? success() : error(); + } + + public static SmsResponse resp(boolean success, String configId){ + return resp(null, success, configId); + } + + public static SmsResponse resp(Object data, boolean success, String configId){ + SmsResponse error = new SmsResponse(); + error.setSuccess(success); + error.setData(data); + error.setConfigId(configId); + return error; + } +} diff --git a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/SupplierConstant.java b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/SupplierConstant.java index f586a9f2..e078a491 100644 --- a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/SupplierConstant.java +++ b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/SupplierConstant.java @@ -61,6 +61,14 @@ public abstract class SupplierConstant { * 七牛云 */ public static final String QINIU = "qiniu"; + /** + * 创蓝 + */ + public static final String CHUANGLAN = "chuanglan"; + /** + * 极光 + */ + public static final String JIGUANG = "jiguang"; /** * 布丁云V2 */ diff --git a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsUtils.java b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsUtils.java index b4f3de24..27a1f621 100644 --- a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsUtils.java +++ b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsUtils.java @@ -7,10 +7,9 @@ import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.function.Function; +import java.util.function.Predicate; /** * @author wind @@ -144,20 +143,20 @@ public class SmsUtils { /** * 将Map中所有key的分隔符转换为新的分隔符 * @param map map对象 - * @param seperator 旧分隔符 - * @param newSeperator 新分隔符 + * @param separator 旧分隔符 + * @param newSeparator 新分隔符 */ - public static void replaceKeysSeperator(Map map, String seperator, String newSeperator) { + public static void replaceKeysSeparator(Map map, String separator, String newSeparator) { if(CollUtil.isEmpty(map)) { return; } List keySet = new ArrayList<>(map.keySet()); for(String key : keySet) { - if(StrUtil.isEmpty(key) || !key.contains(seperator)) { + if(StrUtil.isEmpty(key) || !key.contains(separator)) { continue; } String value = String.valueOf(map.get(key)); - String newKey = key.replaceAll(seperator, newSeperator); + String newKey = key.replaceAll(separator, newSeparator); map.putIfAbsent(newKey, value); map.remove(key); } @@ -172,4 +171,32 @@ public class SmsUtils { } } + public static LinkedHashMap buildMessageByAmpersand(String message) { + if (isEmpty(message)){ + return new LinkedHashMap<>(); + } + String[] split = message.split("&"); + LinkedHashMap map = new LinkedHashMap<>(split.length); + for (int i = 0; i < split.length; i++) { + map.put(String.valueOf(i), split[i]); + } + return map; + } + + /** + * 将任意类型集合转成想要的数组 + * @param list 需要转换的集合 + * @param predicate 过滤条件 + * @param mapper 对此流的元素执行函数 + * @param array 想要的数组 + * @return 数组 + * @param 集合泛型 + * @param 想要的数组类型 + */ + public static E[] toArray(Collection list, Predicate predicate, Function mapper, E[] array) { + if (isEmpty(list)) { + return array.clone(); + } + return list.stream().filter(predicate).map(mapper).toArray(size -> array.clone()); + } } \ No newline at end of file diff --git a/sms4j-javase-plugin/src/main/java/org/dromara/sms4j/javase/config/SEInitializer.java b/sms4j-javase-plugin/src/main/java/org/dromara/sms4j/javase/config/SEInitializer.java index b0b7a779..be3a312a 100644 --- a/sms4j-javase-plugin/src/main/java/org/dromara/sms4j/javase/config/SEInitializer.java +++ b/sms4j-javase-plugin/src/main/java/org/dromara/sms4j/javase/config/SEInitializer.java @@ -36,6 +36,8 @@ import org.dromara.sms4j.emay.config.EmayFactory; import org.dromara.sms4j.huawei.config.HuaweiFactory; import org.dromara.sms4j.javase.util.YamlUtils; import org.dromara.sms4j.jdcloud.config.JdCloudFactory; +import org.dromara.sms4j.chuanglan.config.ChuangLanFactory; +import org.dromara.sms4j.jg.config.JgFactory; import org.dromara.sms4j.lianlu.config.LianLuFactory; import org.dromara.sms4j.mas.config.MasFactory; import org.dromara.sms4j.netease.config.NeteaseFactory; @@ -255,6 +257,8 @@ public class SEInitializer { ProviderFactoryHolder.registerFactory(ZhutongFactory.instance()); ProviderFactoryHolder.registerFactory(LianLuFactory.instance()); ProviderFactoryHolder.registerFactory(DingZhongFactory.instance()); + ProviderFactoryHolder.registerFactory(ChuangLanFactory.instance()); + ProviderFactoryHolder.registerFactory(JgFactory.instance()); ProviderFactoryHolder.registerFactory(QiNiuFactory.instance()); ProviderFactoryHolder.registerFactory(BudingV2Factory.instance()); ProviderFactoryHolder.registerFactory(MasFactory.instance()); diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/service/AlibabaSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/service/AlibabaSmsImpl.java index 507e3848..b0015401 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/service/AlibabaSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/service/AlibabaSmsImpl.java @@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.aliyun.config.AlibabaConfig; import org.dromara.sms4j.aliyun.utils.AliyunUtils; import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; import org.dromara.sms4j.comm.constant.Constant; import org.dromara.sms4j.comm.constant.SupplierConstant; import org.dromara.sms4j.comm.delayedTime.DelayedTime; @@ -113,9 +114,7 @@ public class AlibabaSmsImpl extends AbstractSmsBlend { try { smsResponse = getResponse(http.postJson(requestUrl, headers, paramStr)); } catch (SmsBlendException e) { - smsResponse = new SmsResponse(); - smsResponse.setSuccess(false); - smsResponse.setData(e.getMessage()); + smsResponse = SmsRespUtils.error(e.getMessage(), getConfigId()); } if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { retry = 0; @@ -132,11 +131,7 @@ public class AlibabaSmsImpl extends AbstractSmsBlend { } private SmsResponse getResponse(JSONObject resJson) { - SmsResponse smsResponse = new SmsResponse(); - smsResponse.setSuccess("OK".equals(resJson.getStr("Code"))); - smsResponse.setData(resJson); - smsResponse.setConfigId(getConfigId()); - return smsResponse; + return SmsRespUtils.resp(resJson, "OK".equals(resJson.getStr("Code")), getConfigId()); } } \ No newline at end of file diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/baidu/service/BaiduSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/baidu/service/BaiduSmsImpl.java index d265e2cd..8494d8a2 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/baidu/service/BaiduSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/baidu/service/BaiduSmsImpl.java @@ -5,6 +5,7 @@ import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; import org.dromara.sms4j.comm.constant.SupplierConstant; import org.dromara.sms4j.comm.delayedTime.DelayedTime; import org.dromara.sms4j.comm.exception.SmsBlendException; @@ -157,9 +158,7 @@ public class BaiduSmsImpl extends AbstractSmsBlend { try { smsResponse = getResponse(http.postJson(config.getHost() + config.getAction(), headers, body)); } catch (SmsBlendException e) { - smsResponse = new SmsResponse(); - smsResponse.setSuccess(false); - smsResponse.setData(e.getMessage()); + smsResponse = SmsRespUtils.error(e.getMessage(), getConfigId()); } if (smsResponse.isSuccess() || retry == config.getMaxRetries()) { retry = 0; @@ -176,11 +175,7 @@ public class BaiduSmsImpl extends AbstractSmsBlend { } private SmsResponse getResponse(JSONObject resJson) { - SmsResponse smsResponse = new SmsResponse(); - smsResponse.setSuccess("1000".equals(resJson.getStr("code"))); - smsResponse.setData(resJson); - smsResponse.setConfigId(getConfigId()); - return smsResponse; + return SmsRespUtils.resp(resJson, "1000".equals(resJson.getStr("code")), getConfigId()); } } \ No newline at end of file diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/budingyun/service/BudingV2SmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/budingyun/service/BudingV2SmsImpl.java index 05e01a42..d7bcb986 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/budingyun/service/BudingV2SmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/budingyun/service/BudingV2SmsImpl.java @@ -3,6 +3,7 @@ package org.dromara.sms4j.budingyun.service; import cn.hutool.json.JSONObject; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; import org.dromara.sms4j.budingyun.config.BudingV2Config; import org.dromara.sms4j.comm.constant.Constant; import org.dromara.sms4j.comm.constant.SupplierConstant; @@ -46,7 +47,6 @@ public class BudingV2SmsImpl extends AbstractSmsBlend { @Override public SmsResponse sendMessage(String phone, String message) { - System.out.println("sendMessage"); Map body = new HashMap<>(); System.out.println(getConfig().getSignKey()); @@ -70,9 +70,7 @@ public class BudingV2SmsImpl extends AbstractSmsBlend { try { smsResponse = getResponse(http.postFrom(URL + "/Api/Sent", headers, body)); } catch (SmsBlendException e) { - smsResponse = new SmsResponse(); - smsResponse.setSuccess(false); - smsResponse.setData(e.getMessage()); + smsResponse = SmsRespUtils.error(e.getMessage(), getConfigId()); } if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { retry = 0; @@ -88,17 +86,11 @@ public class BudingV2SmsImpl extends AbstractSmsBlend { return sendMessage(phone, message); } - private SmsResponse getResponse(JSONObject entries) { - System.out.println(entries); - SmsResponse smsResponse = new SmsResponse(); - if (entries == null) { - smsResponse.setSuccess(false); - return smsResponse; + private SmsResponse getResponse(JSONObject resJson) { + if (resJson == null) { + return SmsRespUtils.error(getConfigId()); } - smsResponse.setSuccess(entries.getBool("bool")); - smsResponse.setData(entries); - smsResponse.setConfigId(getConfigId()); - return smsResponse; + return SmsRespUtils.resp(resJson, resJson.getBool("bool"), getConfigId()); } /** @@ -116,9 +108,7 @@ public class BudingV2SmsImpl extends AbstractSmsBlend { failed++; } } - SmsResponse smsResponse = new SmsResponse(); - smsResponse.setSuccess(failed == 0); - return smsResponse; + return SmsRespUtils.resp(failed == 0, getConfigId()); } /** @@ -148,9 +138,7 @@ public class BudingV2SmsImpl extends AbstractSmsBlend { failed++; } } - SmsResponse smsResponse = new SmsResponse(); - smsResponse.setSuccess(failed == 0); - return smsResponse; + return SmsRespUtils.resp(failed == 0, getConfigId()); } /** diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/chuanglan/config/ChuangLanConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/chuanglan/config/ChuangLanConfig.java new file mode 100644 index 00000000..ddd9668d --- /dev/null +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/chuanglan/config/ChuangLanConfig.java @@ -0,0 +1,33 @@ +package org.dromara.sms4j.chuanglan.config; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.sms4j.comm.constant.SupplierConstant; +import org.dromara.sms4j.provider.config.BaseConfig; + +/** + * @author YYM + * @Date: 2024/1/31 17:56 44 + * @描述: ChuangLanConfig + **/ +@EqualsAndHashCode(callSuper = true) +@Data +public class ChuangLanConfig extends BaseConfig { + + /** + * 基础路径 + */ + private String baseUrl = "https://smssh1.253.com/msg"; + + /** + * 短信发送路径 + * 普通短信发送 /v1/send/json 此接口支持单发、群发短信 + * 变量短信发送 /variable/json 单号码对应单内容批量下发 + */ + private String msgUrl = "/variable/json"; + + @Override + public String getSupplier() { + return SupplierConstant.CHUANGLAN; + } +} \ No newline at end of file diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/chuanglan/config/ChuangLanFactory.java b/sms4j-provider/src/main/java/org/dromara/sms4j/chuanglan/config/ChuangLanFactory.java new file mode 100644 index 00000000..c49d2f34 --- /dev/null +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/chuanglan/config/ChuangLanFactory.java @@ -0,0 +1,37 @@ +package org.dromara.sms4j.chuanglan.config; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.dromara.sms4j.chuanglan.service.ChuangLanSmsImpl; +import org.dromara.sms4j.comm.constant.SupplierConstant; +import org.dromara.sms4j.provider.factory.AbstractProviderFactory; + +/** + * @author YYM + * @Date: 2024/2/1 9:03 44 + * @描述: ChuangLanFactory + **/ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class ChuangLanFactory extends AbstractProviderFactory { + + private static final ChuangLanFactory INSTANCE = new ChuangLanFactory(); + + /** + * 获取建造者实例 + * + * @return 建造者实例 + */ + public static ChuangLanFactory instance() { + return INSTANCE; + } + + @Override + public ChuangLanSmsImpl createSms(ChuangLanConfig chuangLanConfig) { + return new ChuangLanSmsImpl(chuangLanConfig); + } + + @Override + public String getSupplier() { + return SupplierConstant.CHUANGLAN; + } +} \ No newline at end of file diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/chuanglan/service/ChuangLanSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/chuanglan/service/ChuangLanSmsImpl.java new file mode 100644 index 00000000..c08149a3 --- /dev/null +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/chuanglan/service/ChuangLanSmsImpl.java @@ -0,0 +1,130 @@ +package org.dromara.sms4j.chuanglan.service; + +import cn.hutool.json.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; +import org.dromara.sms4j.chuanglan.config.ChuangLanConfig; +import org.dromara.sms4j.comm.constant.SupplierConstant; +import org.dromara.sms4j.comm.delayedTime.DelayedTime; +import org.dromara.sms4j.comm.exception.SmsBlendException; +import org.dromara.sms4j.comm.utils.SmsUtils; +import org.dromara.sms4j.provider.service.AbstractSmsBlend; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.concurrent.Executor; + +/** + * @author YYM + * @Date: 2024/2/1 9:04 27 + * @描述: ChuangLanSmsImpl + **/ +@Slf4j +public class ChuangLanSmsImpl extends AbstractSmsBlend { + + private int retry = 0; + + public ChuangLanSmsImpl(ChuangLanConfig config, Executor pool, DelayedTime delayed) { + super(config, pool, delayed); + } + + public ChuangLanSmsImpl(ChuangLanConfig config) { + super(config); + } + + @Override + public String getSupplier() { + return SupplierConstant.CHUANGLAN; + } + + @Override + public SmsResponse sendMessage(String phone, String message) { + return sendMessage(phone, getConfig().getTemplateId(), SmsUtils.buildMessageByAmpersand(message)); + } + + @Override + public SmsResponse sendMessage(String phone, LinkedHashMap messages) { + return sendMessage(phone, getConfig().getTemplateId(), messages); + } + + @Override + public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages) { + if (SmsUtils.isEmpty(messages)){ + messages = new LinkedHashMap<>(); + } + String message = String.join(",", messages.values()); + ChuangLanConfig config = getConfig(); + LinkedHashMap body = buildBody(config.getAccessKeyId(), config.getAccessKeySecret(), templateId); + body.put("params", phone + "," + message); + return getSmsResponse(body); + } + + @Override + public SmsResponse massTexting(List phones, String message) { + return massTexting(phones, getConfig().getTemplateId(), SmsUtils.buildMessageByAmpersand(message)); + } + + @Override + public SmsResponse massTexting(List phones, String templateId, LinkedHashMap messages) { + if (SmsUtils.isEmpty(messages)){ + messages = new LinkedHashMap<>(); + } + String message = String.join(",", messages.values()); + StringBuilder param = new StringBuilder(); + phones.forEach(phone -> param.append(phone).append(",").append(message).append(";")); + ChuangLanConfig config = getConfig(); + LinkedHashMap params = buildBody(config.getAccessKeyId(), config.getAccessKeySecret(), templateId); + params.put("params", param.toString()); + return getSmsResponse(params); + } + + private static String buildUrl(String baseUrl, String msgUrl){ + return baseUrl + msgUrl; + } + + private static LinkedHashMap buildHeaders(){ + LinkedHashMap headers = new LinkedHashMap<>(1); + headers.put("Content-Type", "application/json"); + return headers; + } + + private static LinkedHashMap buildBody(String accessKeyId, String accessKeySecret, String templateId){ + LinkedHashMap body = new LinkedHashMap<>(3); + body.put("account", accessKeyId); + body.put("password", accessKeySecret); + body.put("msg", templateId); + return body; + } + + private SmsResponse getSmsResponse(LinkedHashMap body) { + ChuangLanConfig config = getConfig(); + SmsResponse smsResponse; + String reqUrl = buildUrl(config.getBaseUrl(), config.getMsgUrl()); + try { + smsResponse = getResponse(http.postJson(reqUrl, buildHeaders(), body)); + }catch (SmsBlendException e) { + smsResponse = SmsRespUtils.error(e.getMessage(), getConfigId()); + } + if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { + retry = 0; + return smsResponse; + } + http.safeSleep(getConfig().getRetryInterval()); + retry++; + log.warn("短信第 {" + retry + "} 次重新发送"); + return requestRetry(body); + } + + private SmsResponse requestRetry(LinkedHashMap body) { + http.safeSleep(getConfig().getRetryInterval()); + retry ++; + log.warn("短信第 {} 次重新发送", retry); + return getSmsResponse(body); + } + + private SmsResponse getResponse(JSONObject resJson) { + return SmsRespUtils.resp(resJson, resJson.containsKey("code") && "0".equals(resJson.getStr("code")), getConfigId()); + } + +} \ No newline at end of file diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/util/CloopenHelper.java b/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/util/CloopenHelper.java index 6b5674ac..ac4d0f08 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/util/CloopenHelper.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/cloopen/util/CloopenHelper.java @@ -8,6 +8,7 @@ import cn.hutool.crypto.SecureUtil; import cn.hutool.json.JSONObject; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; import org.dromara.sms4j.cloopen.config.CloopenConfig; import org.dromara.sms4j.comm.constant.Constant; import org.dromara.sms4j.comm.exception.SmsBlendException; @@ -46,13 +47,11 @@ public class CloopenHelper { headers.put("Accept", Constant.ACCEPT); headers.put("Content-Type", Constant.APPLICATION_JSON_UTF8); headers.put("Authorization", this.generateAuthorization(config.getAccessKeyId(), timestamp)); - SmsResponse smsResponse = null; + SmsResponse smsResponse; try { smsResponse = getResponse(http.postJson(url, headers, paramMap)); } catch (SmsBlendException e) { - smsResponse = new SmsResponse(); - smsResponse.setSuccess(false); - smsResponse.setData(e.getMessage()); + smsResponse = SmsRespUtils.error(e.message, config.getConfigId()); } if (smsResponse.isSuccess() || retry == config.getMaxRetries()) { retry = 0; @@ -70,11 +69,7 @@ public class CloopenHelper { } private SmsResponse getResponse(JSONObject resJson) { - SmsResponse smsResponse = new SmsResponse(); - smsResponse.setSuccess("000000".equals(resJson.getStr("statusCode"))); - smsResponse.setData(resJson); - smsResponse.setConfigId(this.config.getConfigId()); - return smsResponse; + return SmsRespUtils.resp(resJson, "000000".equals(resJson.getStr("statusCode")), config.getConfigId()); } /** diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/ctyun/service/CtyunSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/ctyun/service/CtyunSmsImpl.java index 038b0498..0fc411fb 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/ctyun/service/CtyunSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/ctyun/service/CtyunSmsImpl.java @@ -4,6 +4,7 @@ import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; import org.dromara.sms4j.comm.constant.SupplierConstant; import org.dromara.sms4j.comm.delayedTime.DelayedTime; import org.dromara.sms4j.comm.exception.SmsBlendException; @@ -83,11 +84,12 @@ public class CtyunSmsImpl extends AbstractSmsBlend { } private SmsResponse getSmsResponse(String phone, String message, String templateId) { + CtyunConfig config = getConfig(); String requestUrl; String paramStr; try { - requestUrl = getConfig().getRequestUrl(); - paramStr = CtyunUtils.generateParamJsonStr(getConfig(), phone, message, templateId); + requestUrl = config.getRequestUrl(); + paramStr = CtyunUtils.generateParamJsonStr(config, phone, message, templateId); } catch (Exception e) { log.error("ctyun send message error", e); throw new SmsBlendException(e.getMessage()); @@ -96,14 +98,12 @@ public class CtyunSmsImpl extends AbstractSmsBlend { SmsResponse smsResponse; try { smsResponse = getResponse(http.postJson(requestUrl, - CtyunUtils.signHeader(paramStr, getConfig().getAccessKeyId(), getConfig().getAccessKeySecret()), + CtyunUtils.signHeader(paramStr, config.getAccessKeyId(), config.getAccessKeySecret()), paramStr)); } catch (SmsBlendException e) { - smsResponse = new SmsResponse(); - smsResponse.setSuccess(false); - smsResponse.setData(e.getMessage()); + smsResponse = SmsRespUtils.error(e.message, config.getConfigId()); } - if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { + if (smsResponse.isSuccess() || retry == config.getMaxRetries()) { retry = 0; return smsResponse; } @@ -118,11 +118,7 @@ public class CtyunSmsImpl extends AbstractSmsBlend { } private SmsResponse getResponse(JSONObject resJson) { - SmsResponse smsResponse = new SmsResponse(); - smsResponse.setSuccess("OK".equals(resJson.getStr("code"))); - smsResponse.setData(resJson); - smsResponse.setConfigId(getConfigId()); - return smsResponse; + return SmsRespUtils.resp(resJson, "OK".equals(resJson.getStr("code")), getConfigId()); } } \ No newline at end of file diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/dingzhong/util/DingZhongHelper.java b/sms4j-provider/src/main/java/org/dromara/sms4j/dingzhong/util/DingZhongHelper.java index 628a3c40..d336fe09 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/dingzhong/util/DingZhongHelper.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/dingzhong/util/DingZhongHelper.java @@ -4,6 +4,7 @@ import cn.hutool.core.map.MapUtil; import cn.hutool.json.JSONObject; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; import org.dromara.sms4j.comm.constant.Constant; import org.dromara.sms4j.comm.exception.SmsBlendException; import org.dromara.sms4j.comm.utils.SmsHttpUtils; @@ -35,13 +36,11 @@ public class DingZhongHelper { Map headers = MapUtil.newHashMap(2, true); headers.put("Accept", Constant.ACCEPT); headers.put("Content-Type", Constant.FROM_URLENCODED); - SmsResponse smsResponse = null; + SmsResponse smsResponse; try { smsResponse = getResponse(http.postFrom(url, headers, paramMap)); } catch (SmsBlendException e) { - smsResponse = new SmsResponse(); - smsResponse.setSuccess(false); - smsResponse.setData(e.getMessage()); + smsResponse = SmsRespUtils.error(e.message, config.getConfigId()); } if (smsResponse.isSuccess() || retry == config.getMaxRetries()) { retry = 0; @@ -59,10 +58,6 @@ public class DingZhongHelper { } private SmsResponse getResponse(JSONObject resJson) { - SmsResponse smsResponse = new SmsResponse(); - smsResponse.setSuccess("0".equals(resJson.getStr("resCode"))); - smsResponse.setData(resJson); - smsResponse.setConfigId(this.config.getConfigId()); - return smsResponse; + return SmsRespUtils.resp(resJson, "0".equals(resJson.getStr("resCode")), config.getConfigId()); } } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/emay/service/EmaySmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/emay/service/EmaySmsImpl.java index 3f5a293d..c6d1a08d 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/emay/service/EmaySmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/emay/service/EmaySmsImpl.java @@ -4,6 +4,7 @@ import cn.hutool.core.map.MapUtil; import cn.hutool.json.JSONObject; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; import org.dromara.sms4j.comm.constant.Constant; import org.dromara.sms4j.comm.constant.SupplierConstant; import org.dromara.sms4j.comm.delayedTime.DelayedTime; @@ -44,8 +45,9 @@ public class EmaySmsImpl extends AbstractSmsBlend { @Override public SmsResponse sendMessage(String phone, String message) { - String url = getConfig().getRequestUrl(); - Map params = EmayBuilder.buildRequestBody(getConfig().getAccessKeyId(), getConfig().getAccessKeySecret(), phone, message); + EmayConfig config = getConfig(); + String url = config.getRequestUrl(); + Map params = EmayBuilder.buildRequestBody(config.getAccessKeyId(), config.getAccessKeySecret(), phone, message); Map headers = MapUtil.newHashMap(1, true); headers.put("Content-Type", Constant.FROM_URLENCODED); @@ -53,11 +55,9 @@ public class EmaySmsImpl extends AbstractSmsBlend { try { smsResponse = getResponse(http.postUrl(url, headers, params)); } catch (SmsBlendException e) { - smsResponse = new SmsResponse(); - smsResponse.setSuccess(false); - smsResponse.setData(e.getMessage()); + smsResponse = SmsRespUtils.error(e.message, config.getConfigId()); } - if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { + if (smsResponse.isSuccess() || retry == config.getMaxRetries()) { retry = 0; return smsResponse; } @@ -113,11 +113,7 @@ public class EmaySmsImpl extends AbstractSmsBlend { } private SmsResponse getResponse(JSONObject resJson) { - SmsResponse smsResponse = new SmsResponse(); - smsResponse.setSuccess("success".equalsIgnoreCase(resJson.getStr("code"))); - smsResponse.setData(resJson); - smsResponse.setConfigId(getConfigId()); - return smsResponse; + return SmsRespUtils.resp(resJson, "success".equalsIgnoreCase(resJson.getStr("code")), getConfigId()); } } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/service/HuaweiSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/service/HuaweiSmsImpl.java index 7bb860da..ad8955a8 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/service/HuaweiSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/service/HuaweiSmsImpl.java @@ -5,6 +5,7 @@ import cn.hutool.core.map.MapUtil; import cn.hutool.json.JSONObject; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; import org.dromara.sms4j.comm.constant.Constant; import org.dromara.sms4j.comm.constant.SupplierConstant; import org.dromara.sms4j.comm.delayedTime.DelayedTime; @@ -77,9 +78,7 @@ public class HuaweiSmsImpl extends AbstractSmsBlend { try { smsResponse = getResponse(http.postJson(url, headers, requestBody)); } catch (SmsBlendException e) { - smsResponse = new SmsResponse(); - smsResponse.setSuccess(false); - smsResponse.setData(e.getMessage()); + smsResponse = SmsRespUtils.error(e.getMessage(), getConfigId()); } if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { retry = 0; @@ -109,11 +108,7 @@ public class HuaweiSmsImpl extends AbstractSmsBlend { } private SmsResponse getResponse(JSONObject resJson) { - SmsResponse smsResponse = new SmsResponse(); - smsResponse.setSuccess("000000".equals(resJson.getStr("code"))); - smsResponse.setData(resJson); - smsResponse.setConfigId(getConfigId()); - return smsResponse; + return SmsRespUtils.resp(resJson, "000000".equals(resJson.getStr("code")), getConfigId()); } } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/service/JdCloudSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/service/JdCloudSmsImpl.java index b37b875e..0167a2d4 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/service/JdCloudSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/service/JdCloudSmsImpl.java @@ -6,6 +6,7 @@ import com.jdcloud.sdk.service.sms.model.BatchSendRequest; import com.jdcloud.sdk.service.sms.model.BatchSendResult; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; import org.dromara.sms4j.comm.constant.SupplierConstant; import org.dromara.sms4j.comm.delayedTime.DelayedTime; import org.dromara.sms4j.comm.exception.SmsBlendException; @@ -96,9 +97,7 @@ public class JdCloudSmsImpl extends AbstractSmsBlend { try { smsResponse = getSmsResponse(result); } catch (SmsBlendException e) { - smsResponse = new SmsResponse(); - smsResponse.setSuccess(false); - smsResponse.setData(e.getMessage()); + smsResponse = SmsRespUtils.error(e.getMessage(), getConfigId()); } if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { retry = 0; @@ -121,10 +120,6 @@ public class JdCloudSmsImpl extends AbstractSmsBlend { * @return 发送短信返回信息 */ private SmsResponse getSmsResponse(BatchSendResult res) { - SmsResponse smsResponse = new SmsResponse(); - smsResponse.setSuccess(res.getStatus() != null && res.getStatus()); - smsResponse.setData(res); - smsResponse.setConfigId(getConfigId()); - return smsResponse; + return SmsRespUtils.resp(res, res.getStatus() != null && res.getStatus(), getConfigId()); } } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/jg/config/JgConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/jg/config/JgConfig.java new file mode 100644 index 00000000..82ac7de1 --- /dev/null +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/jg/config/JgConfig.java @@ -0,0 +1,71 @@ +package org.dromara.sms4j.jg.config; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.sms4j.comm.constant.SupplierConstant; +import org.dromara.sms4j.provider.config.BaseConfig; + +/** + *

类名: JgConfig + *

说明:极光 sms + * + * @author :SmartFire + * 2024/3/15 + **/ +@Data +@EqualsAndHashCode(callSuper = true) +public class JgConfig extends BaseConfig { + /** + * 签名 ID,该字段为空则使用应用默认签名 + */ + private String signId; + + /** + * 调用地址 + */ + private String requestUrl = "https://api.sms.jpush.cn/v1/"; + + /** + * 默认请求方法 messages + * 发送文本验证码短信 codes + * 发送语音验证码短信 voice_codes + * 验证验证码是否有效 valid + * 注意:此处直接写valid即为验证码验证请求 系统会自动补充完整请求地址为codes/{msg_id}/valid (注:msg_id 为调用发送验证码 API 的返回值) + * 发送单条模板短信 messages + * 发送批量模板短信 messages/batch + */ + private String action = "messages"; + + /** + * 模板变量名称 + */ + private String templateName; + + /** + * action设置为voice_codes有效 + * 语音验证码播报语言选择,0:中文播报,1:英文播报,2:中英混合播报 + */ + private String voice; + + /** + * action设置为voice_codes有效 + * 验证码有效期,默认为 60 秒 + */ + private Integer ttl = 60; + + /** + * action设置为messages/batch有效 + * 标签 + */ + private String tag; + + /** + * 获取供应商 + * + * @since 3.0.0 + */ + @Override + public String getSupplier() { + return SupplierConstant.JIGUANG; + } +} diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/jg/config/JgFactory.java b/sms4j-provider/src/main/java/org/dromara/sms4j/jg/config/JgFactory.java new file mode 100644 index 00000000..0ca36aa5 --- /dev/null +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/jg/config/JgFactory.java @@ -0,0 +1,48 @@ +package org.dromara.sms4j.jg.config; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.dromara.sms4j.comm.constant.SupplierConstant; +import org.dromara.sms4j.jg.service.JgSmsImpl; +import org.dromara.sms4j.provider.factory.AbstractProviderFactory; + +/** + *

类名: JgFactory + *

说明:极光 sms + * + * @author :SmartFire + * 2024/3/15 + **/ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class JgFactory extends AbstractProviderFactory { + + private static final JgFactory INSTANCE = new JgFactory(); + + /** + * 获取建造者实例 + * @return 建造者实例 + */ + public static JgFactory instance() { + return INSTANCE; + } + + /** + * 创建短信实现对象 + * @param config 短信配置对象 + * @return 短信实现对象 + */ + @Override + public JgSmsImpl createSms(JgConfig config) { + return new JgSmsImpl(config); + } + + /** + * 获取供应商 + * @return 供应商 + */ + @Override + public String getSupplier() { + return SupplierConstant.JIGUANG; + } + +} diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/jg/service/JgSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/jg/service/JgSmsImpl.java new file mode 100644 index 00000000..a0213843 --- /dev/null +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/jg/service/JgSmsImpl.java @@ -0,0 +1,140 @@ +package org.dromara.sms4j.jg.service; + +import cn.hutool.json.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; +import org.dromara.sms4j.comm.constant.SupplierConstant; +import org.dromara.sms4j.comm.delayedTime.DelayedTime; +import org.dromara.sms4j.comm.exception.SmsBlendException; +import org.dromara.sms4j.comm.utils.SmsUtils; +import org.dromara.sms4j.jg.config.JgConfig; +import org.dromara.sms4j.jg.util.JgHelper; +import org.dromara.sms4j.provider.service.AbstractSmsBlend; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; + +/** + *

类名: JgSmsImpl + *

说明:极光 sms + * + * @author :SmartFire + * 2024/3/15 + **/ +@Slf4j +public class JgSmsImpl extends AbstractSmsBlend { + private int retry = 0; + + public JgSmsImpl(JgConfig config, Executor pool, DelayedTime delayedTime) { + super(config, pool, delayedTime); + } + + public JgSmsImpl(JgConfig config) { + super(config); + } + + @Override + public String getSupplier() { + return SupplierConstant.JIGUANG; + } + + @Override + public SmsResponse sendMessage(String phone, String message) { + LinkedHashMap map = new LinkedHashMap<>(1); + if (SmsUtils.isNotEmpty(getConfig().getTemplateName()) && + SmsUtils.isNotEmpty(message)){ + map.put(getConfig().getTemplateName(), message); + } + return sendMessage(phone, getConfig().getTemplateId(), map); + } + + @Override + public SmsResponse sendMessage(String phone, LinkedHashMap messages) { + if (SmsUtils.isEmpty(messages)){ + messages = new LinkedHashMap<>(); + } + return sendMessage(phone, getConfig().getTemplateId(), messages); + } + + @Override + public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages) { + if (SmsUtils.isEmpty(messages)){ + messages = new LinkedHashMap<>(); + } + return getSmsResponse(phone, messages, templateId, null, null); + } + + @Override + public SmsResponse massTexting(List phones, String message) { + LinkedHashMap map = new LinkedHashMap<>(1); + if (SmsUtils.isNotEmpty(getConfig().getTemplateName()) && + SmsUtils.isNotEmpty(message)){ + map.put(getConfig().getTemplateName(), message); + } + return massTexting(phones, getConfig().getTemplateId(), map); + } + + @Override + public SmsResponse massTexting(List phones, String templateId, LinkedHashMap messages) { + if (SmsUtils.isEmpty(messages)){ + messages = new LinkedHashMap<>(); + } + return getSmsResponse(SmsUtils.arrayToString(phones), messages, templateId, null, null); + } + + /** + * 自定义方法 + * 发送语音验证码短信 请确保action配置为voice_codes + * @param phone 手机号 + * @param code 语音验证码 可不填 + */ + public SmsResponse sendVoiceCode(String phone, String code){ + return getSmsResponse(phone, null, null, code, null); + } + + /** + * 自定义方法 + * 验证验证码是否有效 请确保action配置为voice_codes + * @param msgId 为调用发送验证码 API 的返回值 + * @param code 验证码 + */ + public SmsResponse verifyCode(String code, String msgId){ + return getSmsResponse(null, null, null, code, msgId); + } + + private SmsResponse getSmsResponse(String phone, LinkedHashMap messages, + String templateId, String code, String msgId) { + SmsResponse smsResponse; + JgConfig config = getConfig(); + String url = JgHelper.buildUrl(config.getRequestUrl(), config.getAction(), msgId); + Map headers = JgHelper.buildHeaders(config.getAccessKeyId(), config.getAccessKeySecret()); + Map body= JgHelper.buildBody(phone, messages, templateId, config, code); + String jsonKey = JgHelper.buildJsonKey(config.getAction()); + try { + smsResponse = getResponse(http.postJson(url, headers, body), jsonKey); + } catch (SmsBlendException e) { + smsResponse = SmsRespUtils.error(e.message, config.getConfigId()); + } + + if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { + retry = 0; + return smsResponse; + } + return requestRetry(phone, messages, templateId, code, msgId); + } + + private SmsResponse requestRetry(String phone, LinkedHashMap messages, + String templateId, String code, String msgId) { + http.safeSleep(getConfig().getRetryInterval()); + retry ++; + log.warn("短信第 {} 次重新发送", retry); + return getSmsResponse(phone, messages, templateId, code, msgId); + } + + private SmsResponse getResponse(JSONObject resJson, String jsonKey) { + return SmsRespUtils.resp(resJson, resJson.getObj(jsonKey) != null, getConfigId()); + } +} diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/jg/util/JgHelper.java b/sms4j-provider/src/main/java/org/dromara/sms4j/jg/util/JgHelper.java new file mode 100644 index 00000000..329e6f32 --- /dev/null +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/jg/util/JgHelper.java @@ -0,0 +1,262 @@ +package org.dromara.sms4j.jg.util; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import lombok.extern.slf4j.Slf4j; +import org.dromara.sms4j.comm.constant.Constant; +import org.dromara.sms4j.comm.exception.SmsBlendException; +import org.dromara.sms4j.comm.utils.SmsUtils; +import org.dromara.sms4j.jg.config.JgConfig; + +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.stream.Collectors; + +/** + *

类名: JgHelper + *

说明:极光 sms + * + * @author :SmartFire + * 2024/3/15 + **/ +@Slf4j +public class JgHelper { + + /** + * 构造请求地址 + * @param baseUrl 配置的baseUrl + * @param action 请求方法 + * @param msgId 验证验证码是否有效时使用 msgId 为调用发送验证码 API 的返回值 + * @return url + */ + public static String buildUrl(String baseUrl, String action, String msgId) { + if ("valid".equals(action)){ + check(msgId); + return baseUrl + "codes/" + msgId + "/" + action; + }else { + return baseUrl + action; + } + } + + /** + * 构造请求头 + * @param accessKeyId appKey + * @param accessKeySecret appKey + * @return 请求头 + */ + public static Map buildHeaders(String accessKeyId, String accessKeySecret){ + check(accessKeyId); + check(accessKeySecret); + Map headers = new LinkedHashMap<>(3); + headers.put("Accept", Constant.ACCEPT); + headers.put("Content-Type", Constant.APPLICATION_JSON_UTF8); + headers.put("Authorization", "Basic " + Base64.encode(accessKeyId + ":" + accessKeySecret, StandardCharsets.UTF_8)); + return headers; + } + + /** + * 构造请求body + * @param phone 手机号 + * @param messages 消息体 + * @param templateId 模板 ID + * @param config 配置 + * @param code 验证码 + * @return 请求body + */ + public static Map buildBody(String phone, LinkedHashMap messages, + String templateId, JgConfig config, String code) { + checkAction(config.getAction()); + switch (config.getAction()){ + case "codes": + return buildBody(phone, config.getSignId(), templateId); + case "voice_codes": + return buildBody(phone, code, config.getVoice(), config.getTtl()); + case "valid": + return buildBody(code); + case "messages/batch": + return buildBody(phone, config.getSignId(), templateId, config.getTag(), messages); + default: + return buildBody(phone, config.getSignId(), templateId, messages); + } + } + + /** + * 构造返回json验证Key值 + * @param action 请求方法 + * @return 返回json验证Key值 + */ + public static String buildJsonKey(String action){ + checkAction(action); + switch (action){ + case "valid": + return "is_valid"; + case "messages/batch": + return "success_count"; + default: + return "msg_id"; + } + } + + /** + * 构造请求body 发送文本验证码短信 + * @param phone 手机号 + * @param signId 签名 ID,该字段为空则使用应用默认签名 + * @param templateId 模板 ID + * @return 请求body + */ + private static Map buildBody(String phone, String signId, String templateId) { + checkSingle(phone); + Map map = new LinkedHashMap<>(2); + map.put("mobile", phone); + check(templateId); + map.put("temp_id", templateId); + if (SmsUtils.isNotEmpty(signId)){ + map.put("sign_id", signId); + } + return map; + } + + /** + * 构造请求body 发送语音验证码短信 + * @param phone 手机号 + * @param code 语音验证码的值,验证码仅支持 4-8 个数字 可为空 + * @param voice 语音验证码播报语言选择,0:中文播报,1:英文播报,2:中英混合播报 + * @param ttl 验证码有效期,默认为 60 秒 + * @return 请求body + */ + private static Map buildBody(String phone, String code, String voice, Integer ttl) { + checkSingle(phone); + Map map = new LinkedHashMap<>(1); + map.put("mobile", phone); + if (SmsUtils.isNotEmpty(code)) { + map.put("code", code); + } + if (SmsUtils.isNotEmpty(voice)){ + checkVoice(voice); + map.put("voice_lang", voice); + } + if (ttl == null || ttl <= 0){ + map.put("ttl", 60); + }else { + map.put("ttl", ttl); + } + return map; + } + + /** + * 构造请求body 验证验证码是否有效 + * @param code 验证码 + * @return 请求body + */ + private static Map buildBody(String code) { + check(code); + Map map = new LinkedHashMap<>(1); + map.put("code", code); + return map; + } + + /** + * 构造请求body 发送单条模板短信 + * @param phone 手机号码 + * @param signId 签名 ID,该字段为空则使用应用默认签名 + * @param templateId 模板 ID + * @param messages 模板参数,需要替换的参数名和 value 的键值对 可为空 + * @return 请求body + */ + private static Map buildBody(String phone, String signId, String templateId, LinkedHashMap messages) { + checkSingle(phone); + Map map = new LinkedHashMap<>(1); + map.put("mobile", phone); + if (SmsUtils.isNotEmpty(signId)){ + map.put("sign_id", signId); + } + check(templateId); + map.put("temp_id", templateId); + checkMessages(messages); + map.put("temp_para", messages); + return map; + } + + /** + * 构造请求body 发送批量模板短信 + * @param phone 手机号码列表 + * @param signId 签名 ID,该字段为空则使用应用默认签名 + * @param templateId 模板 ID + * @param tag 标签 可为空 + * @param messages 模板参数,需要替换的参数名和 value 的键值对 + * @return 请求body + */ + private static Map buildBody(String phone, String signId, String templateId, + String tag, LinkedHashMap messages) { + Set phones = build(phone); + Map map = new LinkedHashMap<>(1); + if (SmsUtils.isNotEmpty(signId)){ + map.put("sign_id", signId); + } + if (SmsUtils.isNotEmpty(tag)){ + map.put("tag", tag); + } + if (SmsUtils.isEmpty(templateId)){ + log.error("templateId is required"); + throw new SmsBlendException("templateId is required"); + } + map.put("temp_id", templateId); + if (SmsUtils.isEmpty(messages)){ + log.error("temp_para is required"); + throw new SmsBlendException("temp_para is required"); + } + List> recipients = new ArrayList<>(phones.size()); + phones.forEach(mobile -> { + Map params = new LinkedHashMap<>(1); + params.put("temp_para", messages); + recipients.add(params); + }); + map.put("recipients", recipients); + return map; + } + + private static Set build(String phone){ + check(phone); + return Arrays.stream(phone.split(",")) + .filter(SmsUtils::isNotEmpty) + .map(String::trim) + .collect(Collectors.toSet()); + } + + private static void checkSingle(String phone){ + Set phones = build(phone); + if (phones.size() > 1) { + log.error("Only a single mobile number is supported"); + throw new SmsBlendException("Only a single mobile number is supported"); + } + } + + private static void checkMessages(LinkedHashMap messages){ + if (SmsUtils.isEmpty(messages)){ + log.error("temp_para is required"); + throw new SmsBlendException("temp_para is required"); + } + } + + private static void checkVoice(String voice){ + if (!StrUtil.equalsAny(voice, "0", "1", "2")){ + log.error("voice_lang is error, the value of an is only [1,2,3]"); + throw new SmsBlendException("voice_lang is error, the value of an is only [1,2,3]"); + } + } + + private static void checkAction(String action){ + if (SmsUtils.isEmpty(action) || !StrUtil.equalsAny(action, "codes", "voice_codes", "valid", "messages", "messages/batch")){ + log.error("Unknown action method"); + throw new SmsBlendException("Unknown action method"); + } + } + + private static void check(String str){ + if (SmsUtils.isEmpty(str)){ + String error = str + " is required"; + log.error(error); + throw new SmsBlendException(error); + } + } +} diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/lianlu/service/LianLuSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/lianlu/service/LianLuSmsImpl.java index 9c0b7c16..c4759698 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/lianlu/service/LianLuSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/lianlu/service/LianLuSmsImpl.java @@ -3,6 +3,8 @@ package org.dromara.sms4j.lianlu.service; import cn.hutool.json.JSONObject; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; +import org.dromara.sms4j.comm.constant.Constant; import org.dromara.sms4j.comm.constant.SupplierConstant; import org.dromara.sms4j.comm.delayedTime.DelayedTime; import org.dromara.sms4j.comm.exception.SmsBlendException; @@ -177,8 +179,8 @@ public class LianLuSmsImpl extends AbstractSmsBlend { try { Map headers = new HashMap<>(2); - headers.put("Content-Type", "application/json;charset=utf-8"); - headers.put("Accept", "application/json"); + headers.put("Content-Type", Constant.APPLICATION_JSON_UTF8); + headers.put("Accept", Constant.ACCEPT); SmsResponse smsResponse = this.getResponse(this.http.postJson(reqUrl, headers, requestBody)); if (!smsResponse.isSuccess() && this.retry != this.getConfig().getMaxRetries()) { return this.requestRetry(req); @@ -199,10 +201,6 @@ public class LianLuSmsImpl extends AbstractSmsBlend { } private SmsResponse getResponse(JSONObject resJson) { - SmsResponse smsResponse = new SmsResponse(); - smsResponse.setSuccess("00".equals(resJson.getStr("status"))); - smsResponse.setData(resJson); - smsResponse.setConfigId(this.getConfigId()); - return smsResponse; + return SmsRespUtils.resp(resJson, "00".equals(resJson.getStr("status")), getConfigId()); } } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/mas/service/MasSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/mas/service/MasSmsImpl.java index 52d18117..a745f7de 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/mas/service/MasSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/mas/service/MasSmsImpl.java @@ -5,6 +5,7 @@ import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; import org.dromara.sms4j.comm.constant.SupplierConstant; import org.dromara.sms4j.comm.delayedTime.DelayedTime; import org.dromara.sms4j.comm.exception.SmsBlendException; @@ -94,9 +95,7 @@ public class MasSmsImpl extends AbstractSmsBlend { try { smsResponse = getResponse(http.postJson(requestUrl, null, base64Code)); } catch (SmsBlendException e) { - smsResponse = new SmsResponse(); - smsResponse.setSuccess(false); - smsResponse.setData(e.getMessage()); + smsResponse = SmsRespUtils.error(e.getMessage(), getConfigId()); } if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { retry = 0; @@ -113,11 +112,7 @@ public class MasSmsImpl extends AbstractSmsBlend { } private SmsResponse getResponse(JSONObject resJson) { - SmsResponse smsResponse = new SmsResponse(); - smsResponse.setSuccess("success".equals(resJson.getStr("rspcod")) && resJson.getBool("success")); - smsResponse.setData(resJson); - smsResponse.setConfigId(getConfigId()); - return smsResponse; + return SmsRespUtils.resp(resJson, "success".equals(resJson.getStr("rspcod")) && resJson.getBool("success"), getConfigId()); } } \ No newline at end of file diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/netease/service/NeteaseSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/netease/service/NeteaseSmsImpl.java index 45ca581c..b32fb9fe 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/netease/service/NeteaseSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/netease/service/NeteaseSmsImpl.java @@ -9,6 +9,7 @@ import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; import org.dromara.sms4j.comm.constant.Constant; import org.dromara.sms4j.comm.constant.SupplierConstant; import org.dromara.sms4j.comm.delayedTime.DelayedTime; @@ -142,9 +143,7 @@ public class NeteaseSmsImpl extends AbstractSmsBlend { try { smsResponse = getResponse(http.postFrom(requestUrl, headers, body)); } catch (SmsBlendException e) { - smsResponse = new SmsResponse(); - smsResponse.setSuccess(false); - smsResponse.setData(e.getMessage()); + smsResponse = SmsRespUtils.error(e.getMessage(), getConfigId()); } if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { retry = 0; @@ -161,11 +160,7 @@ public class NeteaseSmsImpl extends AbstractSmsBlend { } private SmsResponse getResponse(JSONObject jsonObject) { - SmsResponse smsResponse = new SmsResponse(); - smsResponse.setSuccess(jsonObject.getInt("code") <= 200); - smsResponse.setData(jsonObject); - smsResponse.setConfigId(getConfigId()); - return smsResponse; + return SmsRespUtils.resp(jsonObject, jsonObject.getInt("code") <= 200, getConfigId()); } } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/config/QiNiuConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/config/QiNiuConfig.java index 0c93838e..3f85ca01 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/config/QiNiuConfig.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/config/QiNiuConfig.java @@ -6,7 +6,7 @@ import org.dromara.sms4j.comm.constant.SupplierConstant; import org.dromara.sms4j.provider.config.BaseConfig; /** - * @author Administrator + * @author YYM * @Date: 2024/1/30 15:56 30 * @描述: QiNiuConfig **/ diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/config/QiNiuFactory.java b/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/config/QiNiuFactory.java index bfd673bb..a1fcd8d6 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/config/QiNiuFactory.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/config/QiNiuFactory.java @@ -7,7 +7,7 @@ import org.dromara.sms4j.provider.factory.AbstractProviderFactory; import org.dromara.sms4j.qiniu.service.QiNiuSmsImpl; /** - * @author Administrator + * @author YYM * @Date: 2024/1/30 16:06 29 * @描述: QiNiuFactory **/ diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/service/QiNiuSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/service/QiNiuSmsImpl.java index 3947e19b..b054ae86 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/service/QiNiuSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/service/QiNiuSmsImpl.java @@ -1,11 +1,13 @@ package org.dromara.sms4j.qiniu.service; -import cn.hutool.core.util.ObjectUtil; import cn.hutool.json.JSONObject; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; import org.dromara.sms4j.comm.constant.SupplierConstant; import org.dromara.sms4j.comm.delayedTime.DelayedTime; +import org.dromara.sms4j.comm.exception.SmsBlendException; +import org.dromara.sms4j.comm.utils.SmsUtils; import org.dromara.sms4j.provider.service.AbstractSmsBlend; import org.dromara.sms4j.qiniu.config.QiNiuConfig; import org.dromara.sms4j.qiniu.util.QiNiuUtils; @@ -17,7 +19,7 @@ import java.util.Objects; import java.util.concurrent.Executor; /** - * @author Administrator + * @author YYM * @Date: 2024/1/30 16:06 59 * @描述: QiNiuSmsImpl **/ @@ -71,7 +73,6 @@ public class QiNiuSmsImpl extends AbstractSmsBlend { return senMassMsg(phones, templateId, messages); } - /** * @return SmsResponse * @author 初拥。 @@ -79,11 +80,14 @@ public class QiNiuSmsImpl extends AbstractSmsBlend { * @Description: 统一处理返回结果 */ public SmsResponse handleRes(String url, HashMap params) { - JSONObject jsonObject = http.postJson(url, QiNiuUtils.getHeaderAndSign(url, params, getConfig()), params); - SmsResponse smsResponse = new SmsResponse(); - smsResponse.setSuccess(ObjectUtil.isEmpty(jsonObject.getStr("error"))); - smsResponse.setData(jsonObject); - smsResponse.setConfigId(getConfigId()); + JSONObject jsonObject; + SmsResponse smsResponse; + try { + jsonObject = http.postJson(url, QiNiuUtils.getHeaderAndSign(url, params, getConfig()), params); + smsResponse = SmsRespUtils.resp(jsonObject, SmsUtils.isEmpty(jsonObject.getStr("error")), getConfigId()); + }catch (SmsBlendException e){ + smsResponse = SmsRespUtils.error(e.getMessage(), getConfigId()); + } if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { retry = 0; return smsResponse; diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/util/QiNiuUtils.java b/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/util/QiNiuUtils.java index e48df1b0..7094fbcd 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/util/QiNiuUtils.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/util/QiNiuUtils.java @@ -20,7 +20,7 @@ import java.util.Map; import java.util.TimeZone; /** - * @author Administrator + * @author YYM * @Date: 2024/1/30 16:37 50 * @描述: QiNiuUtils **/ diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/service/TencentSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/service/TencentSmsImpl.java index 79d2d474..36f035a7 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/service/TencentSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/service/TencentSmsImpl.java @@ -5,6 +5,7 @@ import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; import org.dromara.sms4j.comm.constant.Constant; import org.dromara.sms4j.comm.constant.SupplierConstant; import org.dromara.sms4j.comm.delayedTime.DelayedTime; @@ -14,11 +15,9 @@ import org.dromara.sms4j.provider.service.AbstractSmsBlend; import org.dromara.sms4j.tencent.config.TencentConfig; import org.dromara.sms4j.tencent.utils.TencentUtils; -import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.concurrent.Executor; /** @@ -44,12 +43,7 @@ public class TencentSmsImpl extends AbstractSmsBlend { @Override public SmsResponse sendMessage(String phone, String message) { - String[] split = message.split("&"); - LinkedHashMap map = new LinkedHashMap<>(); - for (int i = 0; i < split.length; i++) { - map.put(String.valueOf(i), split[i]); - } - return sendMessage(phone, getConfig().getTemplateId(), map); + return sendMessage(phone, getConfig().getTemplateId(), SmsUtils.buildMessageByAmpersand(message)); } @Override @@ -59,38 +53,21 @@ public class TencentSmsImpl extends AbstractSmsBlend { @Override public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages) { - if (Objects.isNull(messages)){ - messages = new LinkedHashMap<>(); - } - List list = new ArrayList<>(); - for (Map.Entry entry : messages.entrySet()) { - list.add(entry.getValue()); - } - String[] s = new String[list.size()]; - return getSmsResponse(new String[]{StrUtil.addPrefixIfNot(phone, "+86")}, list.toArray(s), templateId); + return getSmsResponse(new String[]{StrUtil.addPrefixIfNot(phone, "+86")}, toArray(messages), templateId); } @Override public SmsResponse massTexting(List phones, String message) { - String[] split = message.split("&"); - LinkedHashMap map = new LinkedHashMap<>(); - for (int i = 0; i < split.length; i++) { - map.put(String.valueOf(i), split[i]); - } - return massTexting(phones, getConfig().getTemplateId(), map); + return massTexting(phones, getConfig().getTemplateId(), SmsUtils.buildMessageByAmpersand(message)); } @Override public SmsResponse massTexting(List phones, String templateId, LinkedHashMap messages) { - if (Objects.isNull(messages)){ - messages = new LinkedHashMap<>(); - } - List list = new ArrayList<>(); - for (Map.Entry entry : messages.entrySet()) { - list.add(entry.getValue()); - } - String[] s = new String[list.size()]; - return getSmsResponse(SmsUtils.listToArray(phones), list.toArray(s), templateId); + return getSmsResponse(SmsUtils.listToArray(phones), toArray(messages), templateId); + } + + private String[] toArray(LinkedHashMap messages){ + return SmsUtils.toArray(messages.values(), SmsUtils::isNotEmpty, s -> s, new String[0]); } private SmsResponse getSmsResponse(String[] phones, String[] messages, String templateId) { @@ -112,9 +89,7 @@ public class TencentSmsImpl extends AbstractSmsBlend { try { smsResponse = getResponse(http.postJson(url, headsMap, requestBody)); } catch (SmsBlendException e) { - smsResponse = new SmsResponse(); - smsResponse.setSuccess(false); - smsResponse.setData(e.getMessage()); + smsResponse = SmsRespUtils.error(e.getMessage(), getConfigId()); } if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { retry = 0; @@ -131,15 +106,12 @@ public class TencentSmsImpl extends AbstractSmsBlend { } private SmsResponse getResponse(JSONObject resJson) { - SmsResponse smsResponse = new SmsResponse(); JSONObject response = resJson.getJSONObject("Response"); // 根据 Error 判断是否配置错误 - String error = response.getStr("Error"); - smsResponse.setSuccess(StrUtil.isBlank(error)); + boolean success = StrUtil.isBlank(response.getStr("Error")); // 根据 SendStatusSet 判断是否不为Ok JSONArray sendStatusSet = response.getJSONArray("SendStatusSet"); if (sendStatusSet != null) { - boolean success = true; for (Object obj : sendStatusSet) { JSONObject jsonObject = (JSONObject) obj; String code = jsonObject.getStr("Code"); @@ -148,11 +120,8 @@ public class TencentSmsImpl extends AbstractSmsBlend { break; } } - smsResponse.setSuccess(success); } - smsResponse.setData(resJson); - smsResponse.setConfigId(getConfigId()); - return smsResponse; + return SmsRespUtils.resp(resJson, success, getConfigId()); } } \ No newline at end of file diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/core/UniResponse.java b/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/core/UniResponse.java index 33f1c415..4dd2e33e 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/core/UniResponse.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/core/UniResponse.java @@ -6,7 +6,6 @@ import org.dromara.sms4j.comm.exception.SmsBlendException; import java.util.Objects; public class UniResponse { - public static final String REQUEST_ID_HEADER_KEY = "x-uni-request-id"; public String requestId; public String code; public String message; diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/service/UniSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/service/UniSmsImpl.java index 090b1bb5..d316ed08 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/service/UniSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/unisms/service/UniSmsImpl.java @@ -3,6 +3,7 @@ package org.dromara.sms4j.unisms.service; import cn.hutool.core.map.MapUtil; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; import org.dromara.sms4j.comm.constant.SupplierConstant; import org.dromara.sms4j.comm.delayedTime.DelayedTime; import org.dromara.sms4j.comm.exception.SmsBlendException; @@ -96,16 +97,12 @@ public class UniSmsImpl extends AbstractSmsBlend { } private SmsResponse getSmsResponse(Map data) { - SmsResponse smsResponse = new SmsResponse(); try { UniResponse send = Uni.getClient(getConfig().getRetryInterval(), getConfig().getMaxRetries()).request("sms.message.send", data); - smsResponse.setSuccess("0".equals(send.code)); - smsResponse.setData(send); - smsResponse.setConfigId(getConfigId()); + return SmsRespUtils.resp(send, "0".equals(send.code), getConfigId()); } catch (Exception e) { - smsResponse.setSuccess(false); + return SmsRespUtils.error(e.getMessage(), getConfigId()); } - return smsResponse; } } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/service/YunPianSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/service/YunPianSmsImpl.java index b7b9e20a..debdf8b1 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/service/YunPianSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/service/YunPianSmsImpl.java @@ -3,6 +3,7 @@ package org.dromara.sms4j.yunpian.service; import cn.hutool.json.JSONObject; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; import org.dromara.sms4j.comm.constant.Constant; import org.dromara.sms4j.comm.constant.SupplierConstant; import org.dromara.sms4j.comm.delayedTime.DelayedTime; @@ -40,15 +41,10 @@ public class YunPianSmsImpl extends AbstractSmsBlend { } private SmsResponse getResponse(JSONObject execute) { - SmsResponse smsResponse = new SmsResponse(); if (execute == null) { - smsResponse.setSuccess(false); - return smsResponse; + return SmsRespUtils.error(getConfigId()); } - smsResponse.setSuccess(execute.getInt("code") == 0); - smsResponse.setData(execute); - smsResponse.setConfigId(getConfigId()); - return smsResponse; + return SmsRespUtils.resp(execute, execute.getInt("code") == 0, getConfigId()); } @Override @@ -60,9 +56,7 @@ public class YunPianSmsImpl extends AbstractSmsBlend { try { smsResponse = getResponse(http.postFrom(Constant.YUNPIAN_URL + "/sms/tpl_single_send.json", headers, body)); } catch (SmsBlendException e) { - smsResponse = new SmsResponse(); - smsResponse.setSuccess(false); - smsResponse.setData(e.getMessage()); + smsResponse = SmsRespUtils.error(e.getMessage(), getConfigId()); } if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { retry = 0; diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/zhutong/service/ZhutongSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/zhutong/service/ZhutongSmsImpl.java index 1c39904e..aa2ca1d8 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/zhutong/service/ZhutongSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/zhutong/service/ZhutongSmsImpl.java @@ -10,6 +10,7 @@ import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; import org.dromara.sms4j.comm.constant.Constant; import org.dromara.sms4j.comm.constant.SupplierConstant; import org.dromara.sms4j.comm.delayedTime.DelayedTime; @@ -152,9 +153,7 @@ public class ZhutongSmsImpl extends AbstractSmsBlend { try { smsResponse = getResponse(http.postJson(url, headers, json)); } catch (SmsBlendException e) { - smsResponse = new SmsResponse(); - smsResponse.setSuccess(false); - smsResponse.setData(e.getMessage()); + smsResponse = SmsRespUtils.error(e.getMessage(), getConfigId()); } if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { retry = 0; @@ -240,9 +239,7 @@ public class ZhutongSmsImpl extends AbstractSmsBlend { try { smsResponse = getResponse(http.postJson(url, headers, requestJson.toString())); } catch (SmsBlendException e) { - smsResponse = new SmsResponse(); - smsResponse.setSuccess(false); - smsResponse.setData(e.getMessage()); + smsResponse = SmsRespUtils.error(e.getMessage(), getConfigId()); } if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { retry = 0; @@ -263,11 +260,7 @@ public class ZhutongSmsImpl extends AbstractSmsBlend { } private SmsResponse getResponse(JSONObject jsonObject) { - SmsResponse smsResponse = new SmsResponse(); - smsResponse.setSuccess(jsonObject.getInt("code", -1) <= 200); - smsResponse.setData(jsonObject); - smsResponse.setConfigId(getConfigId()); - return smsResponse; + return SmsRespUtils.resp(jsonObject, jsonObject.getInt("code", -1) <= 200, getConfigId()); } private void validator(String requestUrl, String username, String password) { diff --git a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsBlendsInitializer.java b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsBlendsInitializer.java index 961382fc..16546e44 100644 --- a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsBlendsInitializer.java +++ b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsBlendsInitializer.java @@ -26,6 +26,8 @@ import org.dromara.sms4j.dingzhong.config.DingZhongFactory; import org.dromara.sms4j.emay.config.EmayFactory; import org.dromara.sms4j.huawei.config.HuaweiFactory; import org.dromara.sms4j.jdcloud.config.JdCloudFactory; +import org.dromara.sms4j.chuanglan.config.ChuangLanFactory; +import org.dromara.sms4j.jg.config.JgFactory; import org.dromara.sms4j.lianlu.config.LianLuFactory; import org.dromara.sms4j.mas.config.MasFactory; import org.dromara.sms4j.netease.config.NeteaseFactory; @@ -122,6 +124,8 @@ public class SmsBlendsInitializer { ProviderFactoryHolder.registerFactory(YunPianFactory.instance()); ProviderFactoryHolder.registerFactory(ZhutongFactory.instance()); ProviderFactoryHolder.registerFactory(LianLuFactory.instance()); + ProviderFactoryHolder.registerFactory(ChuangLanFactory.instance()); + ProviderFactoryHolder.registerFactory(JgFactory.instance()); ProviderFactoryHolder.registerFactory(DingZhongFactory.instance()); ProviderFactoryHolder.registerFactory(QiNiuFactory.instance()); ProviderFactoryHolder.registerFactory(BudingV2Factory.instance()); diff --git a/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunSmsImpl.java b/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunSmsImpl.java index 55f9192b..d3b387b9 100644 --- a/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunSmsImpl.java +++ b/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunSmsImpl.java @@ -4,6 +4,7 @@ import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import lombok.extern.slf4j.Slf4j; import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.api.utils.SmsRespUtils; import org.dromara.sms4j.comm.delayedTime.DelayedTime; import org.dromara.sms4j.comm.exception.SmsBlendException; import org.dromara.sms4j.comm.utils.SmsUtils; @@ -90,9 +91,7 @@ public class ZhangJunSmsImpl extends AbstractSmsBlend { try { smsResponse = getResponse(http.postJson(getConfig().getUrl(), null, message)); } catch (SmsBlendException e) { - smsResponse = new SmsResponse(); - smsResponse.setSuccess(false); - smsResponse.setData(e.getMessage()); + smsResponse = SmsRespUtils.error(e.getMessage(), getConfigId()); } if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { retry = 0; @@ -109,11 +108,7 @@ public class ZhangJunSmsImpl extends AbstractSmsBlend { } private SmsResponse getResponse(JSONObject resJson) { - SmsResponse smsResponse = new SmsResponse(); - smsResponse.setSuccess("OK".equals(resJson.getStr("Code"))); - smsResponse.setData(resJson); - smsResponse.setConfigId(getConfigId()); - return smsResponse; + return SmsRespUtils.resp(resJson, "OK".equals(resJson.getStr("Code")), getConfigId()); } } \ No newline at end of file diff --git a/sms4j-spring-boot-example/src/main/resources/application.yml b/sms4j-spring-boot-example/src/main/resources/application.yml index 7bfc48a3..9c0bce54 100644 --- a/sms4j-spring-boot-example/src/main/resources/application.yml +++ b/sms4j-spring-boot-example/src/main/resources/application.yml @@ -112,17 +112,31 @@ sms: template-id: # 可为空 不为空时请遵守中国移动云MAS开发文档中的描述[服务代码加扩展码总长度不能超过20位。] add-serial: - # 中百度智能云 sms - baidu: - access-key-id: 访问密钥ID - access-key-secret: 用户密钥 - ec-name: 企业名称 - signature: 签名编码 - template-id: 模板ID - # 模板变量名称 - template-name: code - custom: 用户自定义参数,格式为字符串,状态回调时会回传该值 可不传 - user-ext-id: 通道自定义扩展码 可不传 + # 中百度智能云 sms + baidu: + access-key-id: 访问密钥ID + access-key-secret: 用户密钥 + ec-name: 企业名称 + signature: 签名编码 + template-id: 模板ID + # 模板变量名称 + template-name: code + custom: 用户自定义参数,格式为字符串,状态回调时会回传该值 可不传 + user-ext-id: 通道自定义扩展码 可不传 + # 创蓝 + chuanglan: + access-key-id: 111111 + access-key-secret: 111111 + templateId: 【253云通讯】{$var}您的验证码是:{$var},{$var}分钟内有效 + # 极光 + jiguang: + supplier: jiguang + signId: 签名 ID,该字段为空则使用应用默认签名 + action: 默认请求方法 messages + templateName: 模板变量名称 + voice: action设置为voice_codes有效 语音验证码播报语言选择,0:中文播报,1:英文播报,2:中英混合播报 + ttl: action设置为voice_codes有效 验证码有效期,默认为 60 秒 + tag: action设置为messages/batch有效 标签 sms-oa: config-type: yaml diff --git a/sms4j-spring-boot-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java b/sms4j-spring-boot-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java index 6f059468..5c61676c 100644 --- a/sms4j-spring-boot-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java +++ b/sms4j-spring-boot-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java @@ -13,6 +13,7 @@ import org.dromara.sms4j.baidu.service.BaiduSmsImpl; import org.dromara.sms4j.comm.constant.SupplierConstant; import org.dromara.sms4j.comm.utils.SmsUtils; import org.dromara.sms4j.core.factory.SmsFactory; +import org.dromara.sms4j.jg.service.JgSmsImpl; import org.dromara.sms4j.lianlu.service.LianLuSmsImpl; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @@ -357,4 +358,80 @@ class Sms4jTest { clientToken); log.info(JSONUtil.toJsonStr(respWithClientToken)); } + + /** + * 创蓝短信 + */ + @Test + public void chungLanTest() { + if (StrUtil.isBlank(PHONE)) { + return; + } + + //测试群发【模板】 + List arrayList = new ArrayList<>(); + arrayList.add(PHONE); + arrayList.add("135****000"); + LinkedHashMap map = new LinkedHashMap<>(); + map.put("1", "1544"); + map.put("2", "2222"); + SmsResponse smsResponse2 = SmsFactory.getBySupplier(SupplierConstant.CHUANGLAN).massTexting(arrayList, "[test]你的验证码是{$val},{$val}", map); + log.info("smsResponse2:{}", smsResponse2); + + //测试单条发送 + SmsResponse smsResponse1 = SmsFactory.getBySupplier(SupplierConstant.CHUANGLAN).sendMessage(PHONE, "1544&2222"); + log.info("smsResponse1:{}", smsResponse1); + + //测试单条模板发送 + LinkedHashMap map3 = new LinkedHashMap<>(); + map3.put("1", "1544"); + map3.put("2", "2222"); + SmsResponse smsResponse3 = SmsFactory.getBySupplier(SupplierConstant.CHUANGLAN).sendMessage(PHONE, "[test]你的验证码是{$val},{$val}", map3); + log.info("smsResponse3:{}", smsResponse3); + } + + /** + * 极光短信 + */ + @Test + public void jgSmsTest() { + // 极光 发送文本验证码短信 API 不需要传入具体验证码 返回 {"msg_id": "288193860302"} + SmsResponse smsResponse1 = SmsFactory.getBySupplier(SupplierConstant.JIGUANG).sendMessage(PHONE, ""); + Assert.isTrue(smsResponse1.isSuccess()); + + // 极光 发送语音验证码短信 请确保action配置为voice_codes + JgSmsImpl voiceCode = (JgSmsImpl) SmsFactory.getBySupplier(SupplierConstant.JIGUANG); + SmsResponse voiceResp = voiceCode.sendVoiceCode(PHONE, + SmsUtils.getRandomInt(6)); + Assert.isTrue(voiceResp.isSuccess()); + + // 验证验证码是否有效 请确保action配置为voice_codes + JgSmsImpl verify = (JgSmsImpl) SmsFactory.getBySupplier(SupplierConstant.JIGUANG); + SmsResponse verifyResp = verify.verifyCode("123456", "288193860302"); + Assert.isTrue(verifyResp.isSuccess()); + + // 极光 发送单条模板短信 API 发送自定义验证码 sendTemplateSMS + LinkedHashMap map1 = new LinkedHashMap<>(); + map1.put("code", "123456"); + SmsResponse smsResponse2 = SmsFactory.getBySupplier(SupplierConstant.JIGUANG).sendMessage(PHONE, map1); + Assert.isTrue(smsResponse2.isSuccess()); + + // 极光 发送单条模板短信 API 发送多参数自定义模板短信 sendTemplateSMS_with_multipleParameters + LinkedHashMap map2 = new LinkedHashMap<>(); + map2.put("name", "test"); + map2.put("password", "test"); + SmsResponse smsResponse3 = SmsFactory.getBySupplier(SupplierConstant.JIGUANG).sendMessage(PHONE, "226992", map2); + Assert.isTrue(smsResponse3.isSuccess()); + + // sendBatchTemplateSMS + LinkedHashMap map3 = new LinkedHashMap<>(); + map3.put("name", "test"); + map3.put("password", "test"); + List phones = new ArrayList<>(); + phones.add(PHONE); + phones.add("xxx"); + SmsResponse smsResponse4 = SmsFactory.getBySupplier(SupplierConstant.JIGUANG).massTexting(phones, "226992", map3); + Assert.isTrue(smsResponse4.isSuccess()); + } + } \ No newline at end of file diff --git a/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SmsBlendsInitializer.java b/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SmsBlendsInitializer.java index 971527a0..8e15d804 100644 --- a/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SmsBlendsInitializer.java +++ b/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SmsBlendsInitializer.java @@ -28,6 +28,8 @@ import org.dromara.sms4j.dingzhong.config.DingZhongFactory; import org.dromara.sms4j.emay.config.EmayFactory; import org.dromara.sms4j.huawei.config.HuaweiFactory; import org.dromara.sms4j.jdcloud.config.JdCloudFactory; +import org.dromara.sms4j.chuanglan.config.ChuangLanFactory; +import org.dromara.sms4j.jg.config.JgFactory; import org.dromara.sms4j.lianlu.config.LianLuFactory; import org.dromara.sms4j.mas.config.MasFactory; import org.dromara.sms4j.netease.config.NeteaseFactory; @@ -139,6 +141,8 @@ public class SmsBlendsInitializer { ProviderFactoryHolder.registerFactory(LianLuFactory.instance()); ProviderFactoryHolder.registerFactory(DingZhongFactory.instance()); ProviderFactoryHolder.registerFactory(QiNiuFactory.instance()); + ProviderFactoryHolder.registerFactory(ChuangLanFactory.instance()); + ProviderFactoryHolder.registerFactory(JgFactory.instance()); ProviderFactoryHolder.registerFactory(BudingV2Factory.instance()); ProviderFactoryHolder.registerFactory(MasFactory.instance()); ProviderFactoryHolder.registerFactory(BaiduFactory.instance());