mirror of
https://gitee.com/dromara/sms4j.git
synced 2025-12-06 08:58:38 +08:00
add 联通一信通平台短信通道
This commit is contained in:
parent
8ec8cf8bd6
commit
f0e018b855
@ -93,4 +93,8 @@ public abstract class SupplierConstant {
|
||||
* danmi sms
|
||||
*/
|
||||
public static final String DAN_MI = "danmi";
|
||||
/**
|
||||
* 联通一信通 sms
|
||||
*/
|
||||
public static final String YIXINTONG = "yixintong";
|
||||
}
|
||||
|
||||
@ -51,6 +51,7 @@ import org.dromara.sms4j.qiniu.config.QiNiuFactory;
|
||||
import org.dromara.sms4j.submail.config.SubMailFactory;
|
||||
import org.dromara.sms4j.tencent.config.TencentFactory;
|
||||
import org.dromara.sms4j.unisms.config.UniFactory;
|
||||
import org.dromara.sms4j.yixintong.config.YiXintongFactory;
|
||||
import org.dromara.sms4j.yunpian.config.YunPianFactory;
|
||||
import org.dromara.sms4j.zhutong.config.ZhutongFactory;
|
||||
|
||||
@ -269,6 +270,7 @@ public class SEInitializer {
|
||||
ProviderFactoryHolder.registerFactory(LuoSiMaoFactory.instance());
|
||||
ProviderFactoryHolder.registerFactory(SubMailFactory.instance());
|
||||
ProviderFactoryHolder.registerFactory(DanMiFactory.instance());
|
||||
ProviderFactoryHolder.registerFactory(YiXintongFactory.instance());
|
||||
if (SmsUtils.isClassExists("com.jdcloud.sdk.auth.CredentialsProvider")) {
|
||||
ProviderFactoryHolder.registerFactory(JdCloudFactory.instance());
|
||||
}
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
package org.dromara.sms4j.yixintong.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.sms4j.comm.constant.SupplierConstant;
|
||||
import org.dromara.sms4j.provider.config.BaseConfig;
|
||||
|
||||
/**
|
||||
* <p>类名: YiXintongConfig
|
||||
* <p>说明:联通一信通平台配置类
|
||||
* <p>所用到配置项:spCode、f、accessKeyId(用户名)、accessKeySecret(接口密钥)、templateId、retryInterval、maxRetries
|
||||
*
|
||||
* @author moat
|
||||
* @create 2024-07-30 16:50
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class YiXintongConfig extends BaseConfig {
|
||||
|
||||
/**
|
||||
* 短信发送请求地址
|
||||
*/
|
||||
private String requestUrl = "https://api.ums86.com:9600/sms/Api/Send.do";
|
||||
|
||||
/**
|
||||
* 企业编号
|
||||
*/
|
||||
private String spCode;
|
||||
|
||||
/**
|
||||
* 提交时检测方式
|
||||
* 1 --- 提交号码中有效的号码仍正常发出短信,无效的号码在返回参数faillist中列出
|
||||
*
|
||||
* 不为1 或该参数不存在 --- 提交号码中只要有无效的号码,那么所有的号码都不发出短信,无效号码在返回参数faillist中列出
|
||||
*/
|
||||
private String f = "1";
|
||||
|
||||
|
||||
@Override
|
||||
public String getSupplier() {
|
||||
return SupplierConstant.YIXINTONG;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package org.dromara.sms4j.yixintong.config;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dromara.sms4j.comm.constant.SupplierConstant;
|
||||
import org.dromara.sms4j.provider.factory.AbstractProviderFactory;
|
||||
import org.dromara.sms4j.yixintong.service.YiXintongSmsImpl;
|
||||
|
||||
/**
|
||||
* <p>类名: YiXintongFactory
|
||||
* <p>说明:联通一信通平台短信对象建造
|
||||
*
|
||||
* @author moat
|
||||
* @create 2024-07-30 17:10
|
||||
*/
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class YiXintongFactory extends AbstractProviderFactory<YiXintongSmsImpl, YiXintongConfig> {
|
||||
|
||||
private static final YiXintongFactory INSTANCE = new YiXintongFactory();
|
||||
|
||||
/**
|
||||
* 获取建造者实例
|
||||
* @return 建造者实例
|
||||
*/
|
||||
public static YiXintongFactory instance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* createSms
|
||||
* <p> 建造一个短信实现对像
|
||||
*/
|
||||
@Override
|
||||
public YiXintongSmsImpl createSms(YiXintongConfig yiXintongConfig) {
|
||||
return new YiXintongSmsImpl(yiXintongConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取供应商
|
||||
* @return 供应商
|
||||
*/
|
||||
@Override
|
||||
public String getSupplier() {
|
||||
return SupplierConstant.YIXINTONG;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,128 @@
|
||||
package org.dromara.sms4j.yixintong.service;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
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.yixintong.config.YiXintongConfig;
|
||||
import org.dromara.sms4j.yixintong.utils.YiXintongUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* <p>类名: YiXintongSmsImpl
|
||||
* <p>说明:联通一信通 sms
|
||||
*
|
||||
* @author moat
|
||||
* @create 2024-07-30 16:59
|
||||
*/
|
||||
@Slf4j
|
||||
public class YiXintongSmsImpl extends AbstractSmsBlend<YiXintongConfig> {
|
||||
|
||||
private int retry = 0;
|
||||
|
||||
public YiXintongSmsImpl(YiXintongConfig config, Executor pool, DelayedTime delayedTime) {
|
||||
super(config, pool, delayedTime);
|
||||
}
|
||||
|
||||
public YiXintongSmsImpl(YiXintongConfig config) {
|
||||
super(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSupplier() {
|
||||
return SupplierConstant.YIXINTONG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsResponse sendMessage(String phone, String message) {
|
||||
return getSmsResponse(phone, message, getConfig().getTemplateId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsResponse massTexting(List<String> phones, String message) {
|
||||
return getSmsResponse(SmsUtils.joinComma(phones), message, getConfig().getTemplateId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsResponse sendMessage(String phone, LinkedHashMap<String, String> messages) {
|
||||
throw new SmsBlendException("不支持此方法");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap<String, String> messages) {
|
||||
throw new SmsBlendException("不支持此方法");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsResponse massTexting(List<String> phones, String templateId, LinkedHashMap<String, String> messages) {
|
||||
throw new SmsBlendException("不支持此方法");
|
||||
}
|
||||
|
||||
|
||||
private SmsResponse getSmsResponse(String phone, String message, String templateId) {
|
||||
final YiXintongConfig config = getConfig();
|
||||
if (StrUtil.isBlank(phone)){
|
||||
log.error("phone is required.");
|
||||
throw new SmsBlendException("phone is required.");
|
||||
}
|
||||
if (StrUtil.isBlank(message)){
|
||||
log.error("message is required.");
|
||||
throw new SmsBlendException("message is required.");
|
||||
}
|
||||
// 生成20位流水号
|
||||
String serialNumber = SmsUtils.getRandomInt(20);
|
||||
|
||||
Map<String, Object> forms = new HashMap<>();
|
||||
forms.put("SpCode", config.getSpCode());
|
||||
forms.put("LoginName", config.getAccessKeyId());
|
||||
forms.put("Password", config.getAccessKeySecret());
|
||||
forms.put("MessageContent", message);
|
||||
forms.put("UserNumber", phone);
|
||||
forms.put("templateId", templateId);
|
||||
forms.put("SerialNumber", serialNumber);
|
||||
forms.put("ScheduleTime", ""); // 立即发送
|
||||
forms.put("f", config.getF());
|
||||
|
||||
SmsResponse smsResponse;
|
||||
try {
|
||||
smsResponse = getResponse(YiXintongUtils.postForm(config.getRequestUrl(), forms));
|
||||
} catch (SmsBlendException e) {
|
||||
smsResponse = errorResp(e.message);
|
||||
}
|
||||
if (smsResponse.isSuccess() || retry == config.getMaxRetries()) {
|
||||
retry = 0;
|
||||
return smsResponse;
|
||||
}
|
||||
return requestRetry(phone, message, templateId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private SmsResponse requestRetry(String phone, String message, String templateId) {
|
||||
http.safeSleep(getConfig().getRetryInterval());
|
||||
retry ++;
|
||||
log.warn("The SMS has been resent for the {}th time.", retry);
|
||||
return getSmsResponse(phone, message, templateId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构造统一短信返回信息
|
||||
* @param body 原始响应信息
|
||||
* @return 短信返回信息
|
||||
*/
|
||||
private SmsResponse getResponse(String body) {
|
||||
return SmsRespUtils.resp(body, StrUtil.contains(body, "result=0&"), getConfigId());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package org.dromara.sms4j.yixintong.utils;
|
||||
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>类名: YiXintongUtils
|
||||
* <p>说明:联通一信通工具类
|
||||
*
|
||||
* @author moat
|
||||
* @create 2024-07-31 9:55
|
||||
*/
|
||||
public class YiXintongUtils {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 发送post form请求
|
||||
*
|
||||
* @param url 请求地址
|
||||
* @param forms 表单参数
|
||||
* @return 返回体
|
||||
*/
|
||||
public static String postForm(String url, Map<String, Object> forms) {
|
||||
return postForm(url, null, forms, "gbk");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 发送post form请求
|
||||
*
|
||||
* @param url 请求地址
|
||||
* @param headers 请求头
|
||||
* @param forms 表单参数
|
||||
* @param charset 字符集编码
|
||||
* @return 返回体
|
||||
*/
|
||||
public static String postForm(String url, Map<String, String> headers, Map<String, Object> forms, String charset) {
|
||||
try (HttpResponse response = HttpRequest.post(url)
|
||||
.addHeaders(headers)
|
||||
.form(forms)
|
||||
.charset(charset)
|
||||
.execute()) {
|
||||
return response.body();
|
||||
} catch (Exception e) {
|
||||
throw new SmsBlendException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -41,6 +41,7 @@ import org.dromara.sms4j.solon.holder.SolonSmsDaoHolder;
|
||||
import org.dromara.sms4j.submail.config.SubMailFactory;
|
||||
import org.dromara.sms4j.tencent.config.TencentFactory;
|
||||
import org.dromara.sms4j.unisms.config.UniFactory;
|
||||
import org.dromara.sms4j.yixintong.config.YiXintongFactory;
|
||||
import org.dromara.sms4j.yunpian.config.YunPianFactory;
|
||||
import org.dromara.sms4j.zhutong.config.ZhutongFactory;
|
||||
import org.noear.solon.core.AppContext;
|
||||
@ -137,6 +138,7 @@ public class SmsBlendsInitializer {
|
||||
ProviderFactoryHolder.registerFactory(LuoSiMaoFactory.instance());
|
||||
ProviderFactoryHolder.registerFactory(SubMailFactory.instance());
|
||||
ProviderFactoryHolder.registerFactory(DanMiFactory.instance());
|
||||
ProviderFactoryHolder.registerFactory(YiXintongFactory.instance());
|
||||
if(SmsUtils.isClassExists("com.jdcloud.sdk.auth.CredentialsProvider")) {
|
||||
ProviderFactoryHolder.registerFactory(JdCloudFactory.instance());
|
||||
}
|
||||
|
||||
@ -155,6 +155,13 @@ sms:
|
||||
accessKeyId: ACCOUNT SID
|
||||
accessKeySecret: AUTH TOKEN
|
||||
action: 默认请求方法 distributor/sendSMS
|
||||
# 一信通
|
||||
yixintong:
|
||||
sp-code: xxxxxx #(必填)企业编号
|
||||
access-key-id: xxxxxx #(必填)用户名
|
||||
access-key-secret: 324gaxxxxxxxxxxxxxxxxx9sdf89 #(必填)接口密钥(正式帐户需要登陆平台,接口业务-接口申请右侧钥匙状图标查看或获取,接口密钥获取后十分钟生效)
|
||||
template-id: #(可选)模板编号(若配置此参数,则会默认使用该模板,以便提高服务方性能)
|
||||
f: 1 #(可选)默认为1,提交时检测方式
|
||||
|
||||
sms-oa:
|
||||
config-type: yaml
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package org.dromara.sms4j.example;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.lang.UUID;
|
||||
@ -526,4 +527,31 @@ public class Sms4jTest {
|
||||
Assert.isTrue(smsResponse5.isSuccess());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 联通一信通模板
|
||||
*/
|
||||
@Test
|
||||
public void yixintongSmsTest() {
|
||||
if (StrUtil.isBlank(PHONE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//短信发送模板:你有一项编号为{xxxxxxxxx}的事务需要处理{x}
|
||||
//其中的{xxxxxx}代表短信模板中的变量部分,可变化,一个x代表一个字或者字符,{}为变量标识,在发送时不用传。实发变量字数小于等于x的个数。
|
||||
|
||||
// 单发
|
||||
String message1 = StrUtil.format("你有一项编号为{}的事务需要处理。", SmsUtils.getRandomInt(6));
|
||||
SmsResponse smsResponse1 = SmsFactory.getBySupplier(SupplierConstant.YIXINTONG).sendMessage(PHONE, message1);
|
||||
log.info(JSONUtil.toJsonStr(smsResponse1));
|
||||
Assert.isTrue(smsResponse1.isSuccess());
|
||||
|
||||
// 群发
|
||||
List<String> phones = CollectionUtil.toList("2222222222");
|
||||
String message2 = StrUtil.format("你有一项编号为{}的事务需要处理。", SmsUtils.getRandomInt(6));
|
||||
SmsResponse smsResponse2 = SmsFactory.getBySupplier(SupplierConstant.YIXINTONG).massTexting(phones, message2);
|
||||
log.info(JSONUtil.toJsonStr(smsResponse2));
|
||||
Assert.isTrue(smsResponse2.isSuccess());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -43,6 +43,7 @@ import org.dromara.sms4j.starter.adepter.ConfigCombineMapAdaptor;
|
||||
import org.dromara.sms4j.submail.config.SubMailFactory;
|
||||
import org.dromara.sms4j.tencent.config.TencentFactory;
|
||||
import org.dromara.sms4j.unisms.config.UniFactory;
|
||||
import org.dromara.sms4j.yixintong.config.YiXintongFactory;
|
||||
import org.dromara.sms4j.yunpian.config.YunPianFactory;
|
||||
import org.dromara.sms4j.zhutong.config.ZhutongFactory;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
@ -152,6 +153,7 @@ public class SmsBlendsInitializer {
|
||||
ProviderFactoryHolder.registerFactory(LuoSiMaoFactory.instance());
|
||||
ProviderFactoryHolder.registerFactory(SubMailFactory.instance());
|
||||
ProviderFactoryHolder.registerFactory(DanMiFactory.instance());
|
||||
ProviderFactoryHolder.registerFactory(YiXintongFactory.instance());
|
||||
if (SmsUtils.isClassExists("com.jdcloud.sdk.auth.CredentialsProvider")) {
|
||||
if (SmsUtils.isClassExists("com.jdcloud.sdk.auth.CredentialsProvider")) {
|
||||
ProviderFactoryHolder.registerFactory(JdCloudFactory.instance());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user