mirror of
https://gitee.com/dromara/sms4j.git
synced 2025-12-06 17:08:40 +08:00
1.修改uni-sms短信实现,去除SDK依赖
2.修复回调bug,该bug导致回调未在主线程中执行 3.**暂时注释腾讯云短信JDK不兼容部分等待修复**
This commit is contained in:
parent
d62a4af123
commit
f5625f2c5c
2
.gitignore
vendored
2
.gitignore
vendored
@ -35,4 +35,4 @@ build/
|
||||
### Temp
|
||||
.flattened-pom.xml
|
||||
**/.flattened-pom.xml
|
||||
/.fastRequest/
|
||||
/.fastRequest/**
|
||||
|
||||
50
pom.xml
50
pom.xml
@ -47,7 +47,7 @@
|
||||
</scm>
|
||||
|
||||
<properties>
|
||||
<spring.boot.version>2.7.10</spring.boot.version>
|
||||
<spring.boot.version>2.7.11</spring.boot.version>
|
||||
<revision>2.0.1</revision>
|
||||
<aliyun.version>2.0.23</aliyun.version>
|
||||
<tencent.version>3.1.622</tencent.version>
|
||||
@ -89,6 +89,7 @@
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!--核心模块-->
|
||||
<dependency>
|
||||
<groupId>org.dromara.sms4j</groupId>
|
||||
<artifactId>sms4j-core</artifactId>
|
||||
@ -145,19 +146,6 @@
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!--合一短信依赖-->
|
||||
<dependency>
|
||||
<groupId>com.apistd.uni</groupId>
|
||||
<artifactId>uni-sdk</artifactId>
|
||||
<version>${unisms.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- 京东云短信依赖 -->
|
||||
<dependency>
|
||||
<groupId>com.jdcloud.sdk</groupId>
|
||||
@ -165,12 +153,6 @@
|
||||
<version>${jdcloud.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- okhttp依赖,防止出现java.lang.NoSuchFieldError: Companion异常-->
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>${okhttp.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
@ -239,20 +221,20 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- <!– GPG –>-->
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.apache.maven.plugins</groupId>-->
|
||||
<!-- <artifactId>maven-gpg-plugin</artifactId>-->
|
||||
<!-- <version>1.6</version>-->
|
||||
<!-- <executions>-->
|
||||
<!-- <execution>-->
|
||||
<!-- <phase>verify</phase>-->
|
||||
<!-- <goals>-->
|
||||
<!-- <goal>sign</goal>-->
|
||||
<!-- </goals>-->
|
||||
<!-- </execution>-->
|
||||
<!-- </executions>-->
|
||||
<!-- </plugin>-->
|
||||
<!-- <!– GPG –>-->
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.apache.maven.plugins</groupId>-->
|
||||
<!-- <artifactId>maven-gpg-plugin</artifactId>-->
|
||||
<!-- <version>1.6</version>-->
|
||||
<!-- <executions>-->
|
||||
<!-- <execution>-->
|
||||
<!-- <phase>verify</phase>-->
|
||||
<!-- <goals>-->
|
||||
<!-- <goal>sign</goal>-->
|
||||
<!-- </goals>-->
|
||||
<!-- </execution>-->
|
||||
<!-- </executions>-->
|
||||
<!-- </plugin>-->
|
||||
<!--Compiler -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
/**
|
||||
* 公共API
|
||||
* @author :Wind
|
||||
*/
|
||||
package org.dromara.sms4j.api;
|
||||
@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Spring Boot自动装配配置
|
||||
* @author :Wind
|
||||
*/
|
||||
package org.dromara.sms4j.autoimmit;
|
||||
@ -0,0 +1,5 @@
|
||||
/**
|
||||
* 公共模块
|
||||
* @author :Wind
|
||||
*/
|
||||
package org.dromara.sms4j.comm;
|
||||
@ -0,0 +1,5 @@
|
||||
/**
|
||||
* 核心模块
|
||||
* @author :Wind
|
||||
*/
|
||||
package org.dromara.sms4j.core;
|
||||
@ -20,12 +20,6 @@
|
||||
<artifactId>sms4j-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 合一短信依赖 -->
|
||||
<dependency>
|
||||
<groupId>com.apistd.uni</groupId>
|
||||
<artifactId>uni-sdk</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 京东云短信依赖 -->
|
||||
<dependency>
|
||||
<groupId>com.jdcloud.sdk</groupId>
|
||||
|
||||
@ -17,6 +17,7 @@ import org.dromara.sms4j.comm.factory.BeanFactory;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
@ -111,10 +112,8 @@ public class AlibabaSmsImpl implements SmsBlend {
|
||||
@Override
|
||||
@Restricted
|
||||
public void sendMessageAsync(String phone, String message, CallBack callBack) {
|
||||
pool.execute(() -> {
|
||||
SmsResponse smsResponse = sendMessage(phone, message);
|
||||
callBack.callBack(smsResponse);
|
||||
});
|
||||
CompletableFuture<SmsResponse> smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, message), pool);
|
||||
smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -128,10 +127,8 @@ public class AlibabaSmsImpl implements SmsBlend {
|
||||
@Override
|
||||
@Restricted
|
||||
public void sendMessageAsync(String phone, String templateId, LinkedHashMap<String, String> messages, CallBack callBack) {
|
||||
pool.execute(() -> {
|
||||
SmsResponse smsResponse = sendMessage(phone, templateId, messages);
|
||||
callBack.callBack(smsResponse);
|
||||
});
|
||||
CompletableFuture<SmsResponse> smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone,templateId, messages), pool);
|
||||
smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -14,6 +14,7 @@ import org.dromara.sms4j.comm.annotation.Restricted;
|
||||
import org.dromara.sms4j.comm.delayedTime.DelayedTime;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
@ -75,10 +76,8 @@ public class CloopenSmsImpl implements SmsBlend {
|
||||
@Override
|
||||
@Restricted
|
||||
public void sendMessageAsync(String phone, String message, CallBack callBack) {
|
||||
pool.execute(() -> {
|
||||
SmsResponse smsResponse = sendMessage(phone, message);
|
||||
callBack.callBack(smsResponse);
|
||||
});
|
||||
CompletableFuture<SmsResponse> smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, message), pool);
|
||||
smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -90,10 +89,8 @@ public class CloopenSmsImpl implements SmsBlend {
|
||||
@Override
|
||||
@Restricted
|
||||
public void sendMessageAsync(String phone, String templateId, LinkedHashMap<String, String> messages, CallBack callBack) {
|
||||
pool.execute(() -> {
|
||||
SmsResponse smsResponse = sendMessage(phone, templateId, messages);
|
||||
callBack.callBack(smsResponse);
|
||||
});
|
||||
CompletableFuture<SmsResponse> smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone,templateId, messages), pool);
|
||||
smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -14,6 +14,7 @@ import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||
import org.dromara.sms4j.comm.factory.BeanFactory;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@ -89,10 +90,8 @@ public class EmaySmsImpl implements SmsBlend {
|
||||
@Override
|
||||
@Restricted
|
||||
public void sendMessageAsync(String phone, String message, CallBack callBack) {
|
||||
pool.execute(() -> {
|
||||
SmsResponse smsResponse = sendMessage(phone, message);
|
||||
callBack.callBack(smsResponse);
|
||||
});
|
||||
CompletableFuture<SmsResponse> smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, message), pool);
|
||||
smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -104,10 +103,8 @@ public class EmaySmsImpl implements SmsBlend {
|
||||
@Override
|
||||
@Restricted
|
||||
public void sendMessageAsync(String phone, String templateId, LinkedHashMap<String, String> messages, CallBack callBack) {
|
||||
pool.execute(() -> {
|
||||
SmsResponse smsResponse = sendMessage(phone, templateId, messages);
|
||||
callBack.callBack(smsResponse);
|
||||
});
|
||||
CompletableFuture<SmsResponse> smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, templateId, messages), pool);
|
||||
smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -15,6 +15,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.sms4j.api.SmsBlend;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import static org.dromara.sms4j.huawei.utils.HuaweiBuilder.listToString;
|
||||
@ -94,10 +95,8 @@ public class HuaweiSmsImpl implements SmsBlend {
|
||||
@Override
|
||||
@Restricted
|
||||
public void sendMessageAsync(String phone, String message, CallBack callBack) {
|
||||
pool.execute(() -> {
|
||||
SmsResponse smsResponse = sendMessage(phone, message);
|
||||
callBack.callBack(smsResponse);
|
||||
});
|
||||
CompletableFuture<SmsResponse> smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, message), pool);
|
||||
smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -109,10 +108,8 @@ public class HuaweiSmsImpl implements SmsBlend {
|
||||
@Override
|
||||
@Restricted
|
||||
public void sendMessageAsync(String phone, String templateId, LinkedHashMap<String, String> messages, CallBack callBack) {
|
||||
pool.execute(() -> {
|
||||
SmsResponse smsResponse = sendMessage(phone, templateId, messages);
|
||||
callBack.callBack(smsResponse);
|
||||
});
|
||||
CompletableFuture<SmsResponse> smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, templateId, messages), pool);
|
||||
smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -17,6 +17,7 @@ import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -87,10 +88,8 @@ public class JdCloudSmsImpl implements SmsBlend {
|
||||
@Override
|
||||
@Restricted
|
||||
public void sendMessageAsync(String phone, String message, CallBack callBack) {
|
||||
pool.execute(() -> {
|
||||
SmsResponse smsResponse = sendMessage(phone, message);
|
||||
callBack.callBack(smsResponse);
|
||||
});
|
||||
CompletableFuture<SmsResponse> smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, message), pool);
|
||||
smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -102,10 +101,8 @@ public class JdCloudSmsImpl implements SmsBlend {
|
||||
@Override
|
||||
@Restricted
|
||||
public void sendMessageAsync(String phone, String templateId, LinkedHashMap<String, String> messages, CallBack callBack) {
|
||||
pool.execute(() -> {
|
||||
SmsResponse smsResponse = sendMessage(phone, templateId, messages);
|
||||
callBack.callBack(smsResponse);
|
||||
});
|
||||
CompletableFuture<SmsResponse> smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, templateId, messages), pool);
|
||||
smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
/**
|
||||
* 厂商模块
|
||||
* @author :Wind
|
||||
*/
|
||||
package org.dromara.sms4j;
|
||||
@ -16,6 +16,7 @@ import org.dromara.sms4j.tencent.config.TencentConfig;
|
||||
import org.dromara.sms4j.tencent.utils.TencentUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Slf4j
|
||||
@ -119,10 +120,8 @@ public class TencentSmsImpl implements SmsBlend {
|
||||
@Override
|
||||
@Restricted
|
||||
public void sendMessageAsync(String phone, String message, CallBack callBack) {
|
||||
pool.execute(() -> {
|
||||
SmsResponse smsResponse = sendMessage(phone, message);
|
||||
callBack.callBack(smsResponse);
|
||||
});
|
||||
CompletableFuture<SmsResponse> smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, message), pool);
|
||||
smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -136,10 +135,8 @@ public class TencentSmsImpl implements SmsBlend {
|
||||
@Override
|
||||
@Restricted
|
||||
public void sendMessageAsync(String phone, String templateId, LinkedHashMap<String, String> messages, CallBack callBack) {
|
||||
pool.execute(() -> {
|
||||
SmsResponse smsResponse = sendMessage(phone, templateId, messages);
|
||||
callBack.callBack(smsResponse);
|
||||
});
|
||||
CompletableFuture<SmsResponse> smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, templateId, messages), pool);
|
||||
smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -6,7 +6,7 @@ import org.dromara.sms4j.tencent.config.TencentConfig;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
//import javax.xml.bind.DatatypeConverter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.text.SimpleDateFormat;
|
||||
@ -44,7 +44,8 @@ public class TencentUtils {
|
||||
private static String sha256Hex(String s) throws Exception {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||
byte[] d = md.digest(s.getBytes(StandardCharsets.UTF_8));
|
||||
return DatatypeConverter.printHexBinary(d).toLowerCase();
|
||||
// return DatatypeConverter.printHexBinary(d).toLowerCase();
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -85,10 +86,10 @@ public class TencentUtils {
|
||||
byte[] secretDate = hmac256(("TC3" + tencentConfig.getAccessKeySecret()).getBytes(StandardCharsets.UTF_8), date);
|
||||
byte[] secretService = hmac256(secretDate, tencentConfig.getService());
|
||||
byte[] secretSigning = hmac256(secretService, "tc3_request");
|
||||
String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();
|
||||
// String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();
|
||||
// ************* 步骤 4:拼接 Authorization *************
|
||||
return ALGORITHM + " " + "Credential=" + tencentConfig.getAccessKeyId() + "/" + credentialScope + ", "
|
||||
+ "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;
|
||||
return ALGORITHM + " " + "Credential=" + tencentConfig.getAccessKeyId() + "/" + credentialScope + ", ";
|
||||
// + "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package org.dromara.sms4j.unisms.config;
|
||||
|
||||
import com.apistd.uni.Uni;
|
||||
import org.dromara.sms4j.comm.factory.BeanFactory;
|
||||
import org.dromara.sms4j.unisms.core.Uni;
|
||||
import org.dromara.sms4j.unisms.service.UniSmsImpl;
|
||||
|
||||
/**
|
||||
|
||||
@ -0,0 +1,93 @@
|
||||
package org.dromara.sms4j.unisms.core;
|
||||
|
||||
|
||||
/**
|
||||
* 初始化统一环境的单例类.
|
||||
*/
|
||||
public class Uni {
|
||||
/** 模仿SDK版本*/
|
||||
public static final String VERSION = "0.0.4";
|
||||
|
||||
public static String signingAlgorithm = "hmac-sha256";
|
||||
public static String endpoint = System.getenv().getOrDefault("UNI_ENDPOINT", "https://uni.apistd.com");
|
||||
public static String accessKeyId = System.getenv("UNI_ACCESS_KEY_ID");
|
||||
|
||||
private static String accessKeySecret = System.getenv("UNI_ACCESS_KEY_SECRET");
|
||||
private static volatile UniClient client;
|
||||
|
||||
private Uni() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化Uni环境(简单验证模式).
|
||||
*
|
||||
* @param accessKeyId access key ID
|
||||
* @author :Wind
|
||||
*/
|
||||
public static void init(final String accessKeyId) {
|
||||
Uni.setAccessKeyId(accessKeyId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化Uni环境(HMAC验证模式).
|
||||
*
|
||||
* @param accessKeyId access key ID
|
||||
* @param accessKeySecret access key secret
|
||||
* @author :Wind
|
||||
*/
|
||||
public static void init(final String accessKeyId, final String accessKeySecret) {
|
||||
Uni.setAccessKeyId(accessKeyId);
|
||||
Uni.setAccessKeySecret(accessKeySecret);
|
||||
}
|
||||
|
||||
|
||||
public static void setAccessKeyId(final String accessKeyId) {
|
||||
Uni.accessKeyId = accessKeyId;
|
||||
}
|
||||
|
||||
|
||||
public static void setAccessKeySecret(final String accessKeySecret) {
|
||||
Uni.accessKeySecret = accessKeySecret;
|
||||
}
|
||||
|
||||
|
||||
public static void setEndpoint(final String endpoint) {
|
||||
Uni.endpoint = endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回(如果未初始化则初始化)统一客户端.
|
||||
*
|
||||
* @return the Uni Client
|
||||
* @author :Wind
|
||||
*/
|
||||
public static UniClient getClient() {
|
||||
if (Uni.client == null) {
|
||||
synchronized (Uni.class) {
|
||||
if (Uni.client == null) {
|
||||
Uni.client = buildClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
return Uni.client;
|
||||
}
|
||||
|
||||
public static void setClient(final UniClient client) {
|
||||
synchronized (Uni.class) {
|
||||
Uni.client = client;
|
||||
}
|
||||
}
|
||||
|
||||
private static UniClient buildClient() {
|
||||
UniClient.Builder builder = new UniClient.Builder(Uni.accessKeyId);
|
||||
|
||||
if (Uni.accessKeySecret != null) {
|
||||
builder.accessKeySecret(Uni.accessKeySecret);
|
||||
}
|
||||
|
||||
builder.endpoint(Uni.endpoint);
|
||||
builder.signingAlgorithm(Uni.signingAlgorithm);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,152 @@
|
||||
package org.dromara.sms4j.unisms.core;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.dtflys.forest.config.ForestConfiguration;
|
||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||
import org.dromara.sms4j.comm.factory.BeanFactory;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.util.Base64;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public class UniClient {
|
||||
|
||||
public static final String USER_AGENT = "uni-java-sdk" + "/" + Uni.VERSION;
|
||||
private final ForestConfiguration http = BeanFactory.getForestConfiguration();
|
||||
|
||||
private final String accessKeyId;
|
||||
private final String accessKeySecret;
|
||||
private final String endpoint;
|
||||
private final String signingAlgorithm;
|
||||
|
||||
protected UniClient(Builder b) {
|
||||
this.accessKeyId = b.accessKeyId;
|
||||
this.accessKeySecret = b.accessKeySecret;
|
||||
this.endpoint = b.endpoint;
|
||||
this.signingAlgorithm = b.signingAlgorithm;
|
||||
}
|
||||
|
||||
private static String getSignature(final String message, final String secretKey) {
|
||||
try {
|
||||
Mac hmac = Mac.getInstance("HmacSHA256");
|
||||
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256");
|
||||
hmac.init(secretKeySpec);
|
||||
|
||||
byte[] bytes = hmac.doFinal(message.getBytes());
|
||||
return Base64.getEncoder().encodeToString(bytes);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static String queryStringify(final Map<String, Object> params) {
|
||||
Map<String, Object> sortedMap = new TreeMap<>(new MapKeyComparator());
|
||||
sortedMap.putAll(params);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Iterator<?> iter = sortedMap.entrySet().iterator();
|
||||
|
||||
while (iter.hasNext()) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append('&');
|
||||
}
|
||||
Entry<?, ?> entry = (Entry<?, ?>) iter.next();
|
||||
sb.append(entry.getKey()).append("=").append(entry.getValue());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private Map<String, Object> sign(final Map<String, Object> query) {
|
||||
if (this.accessKeySecret != null) {
|
||||
query.put("algorithm", this.signingAlgorithm);
|
||||
query.put("timestamp", new Date().getTime());
|
||||
query.put("nonce", UUID.randomUUID().toString().replaceAll("-", ""));
|
||||
|
||||
String strToSign = UniClient.queryStringify(query);
|
||||
query.put("signature", UniClient.getSignature(strToSign, this.accessKeySecret));
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* request
|
||||
* <p>向 uni-sms发送请求
|
||||
* @param action 接口名称
|
||||
* @author :Wind
|
||||
*/
|
||||
public UniResponse request(final String action, final Map<String, Object> data) throws SmsBlendException {
|
||||
Map<String, Object> query = new HashMap<String, Object>();
|
||||
query.put("action", action);
|
||||
query.put("accessKeyId", this.accessKeyId);
|
||||
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", USER_AGENT);
|
||||
headers.put("Content-Type", "application/json;charset=utf-8");
|
||||
headers.put("Accept", "application/json");
|
||||
return new UniResponse(
|
||||
JSONObject.parseObject(
|
||||
http.post(this.endpoint)
|
||||
.addHeader(headers)
|
||||
.addQuery(this.sign(query))
|
||||
.addBody(JSONObject.toJSONString(data))
|
||||
.successWhen(((req, res) -> {
|
||||
return res.noException() && // 请求过程没有异常
|
||||
res.statusIsNot(500); // 不能是 500
|
||||
}))
|
||||
.onError((ex, req, res) -> {
|
||||
throw new SmsBlendException(ex.getMessage());
|
||||
})
|
||||
.executeAsString()
|
||||
));
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String accessKeyId;
|
||||
private String accessKeySecret;
|
||||
private String endpoint;
|
||||
private String signingAlgorithm;
|
||||
|
||||
public Builder(final String accessKeyId) {
|
||||
this.accessKeyId = accessKeyId;
|
||||
}
|
||||
|
||||
public Builder(final String accessKeyId, final String accessKeySecret) {
|
||||
this.accessKeyId = accessKeyId;
|
||||
this.accessKeySecret = accessKeySecret;
|
||||
}
|
||||
|
||||
public Builder accessKeySecret(final String accessKeySecret) {
|
||||
this.accessKeySecret = accessKeySecret;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder endpoint(final String endpoint) {
|
||||
this.endpoint = endpoint;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder signingAlgorithm(final String signingAlgorithm) {
|
||||
this.signingAlgorithm = signingAlgorithm;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UniClient build() {
|
||||
return new UniClient(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MapKeyComparator implements Comparator<String> {
|
||||
@Override
|
||||
public int compare(String str1, String str2) {
|
||||
return str1.compareTo(str2);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
package org.dromara.sms4j.unisms.core;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||
|
||||
|
||||
public class UniResponse {
|
||||
public static final String REQUEST_ID_HEADER_KEY = "x-uni-request-id";
|
||||
public String requestId;
|
||||
public String code;
|
||||
public String message;
|
||||
public String status;
|
||||
public JSONObject data = null;
|
||||
public Object raw;
|
||||
|
||||
/**
|
||||
* Create a new Uni Response.
|
||||
*
|
||||
* @param response raw HTTP response
|
||||
*/
|
||||
public UniResponse(final JSONObject response) throws SmsBlendException {
|
||||
JSONObject body = response.getJSONObject("data");
|
||||
this.status = body.getJSONArray("messages").getJSONObject(0).getString("status");
|
||||
this.requestId = body.getJSONArray("messages").getJSONObject(0).getString("id");
|
||||
this.raw = body;
|
||||
|
||||
if (this.status != "400") {
|
||||
String code = response.getString("code");
|
||||
String message = body.getJSONArray("messages").getString(0);
|
||||
if (!"0".equals(code)) {
|
||||
throw new SmsBlendException(message, code, this.requestId);
|
||||
}
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
this.data = body;
|
||||
}
|
||||
else {
|
||||
throw new SmsBlendException(response.getString("message"), "-1");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UniResponse{" +
|
||||
"requestId='" + requestId + '\'' +
|
||||
", code='" + code + '\'' +
|
||||
", message='" + message + '\'' +
|
||||
", status='" + status + '\'' +
|
||||
", data=" + data +
|
||||
", raw=" + raw +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,5 @@
|
||||
package org.dromara.sms4j.unisms.service;
|
||||
|
||||
import com.apistd.uni.UniResponse;
|
||||
import com.apistd.uni.sms.UniMessage;
|
||||
import com.apistd.uni.sms.UniSMS;
|
||||
import org.dromara.sms4j.api.SmsBlend;
|
||||
import org.dromara.sms4j.api.callback.CallBack;
|
||||
import org.dromara.sms4j.api.entity.SmsResponse;
|
||||
@ -11,11 +8,19 @@ import org.dromara.sms4j.comm.delayedTime.DelayedTime;
|
||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||
import org.dromara.sms4j.unisms.config.UniConfig;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.sms4j.unisms.core.Uni;
|
||||
import org.dromara.sms4j.unisms.core.UniResponse;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
||||
/**
|
||||
@ -52,10 +57,12 @@ public class UniSmsImpl implements SmsBlend {
|
||||
@Override
|
||||
@Restricted
|
||||
public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap<String, String> messages) {
|
||||
UniMessage uniMes = UniSMS.buildMessage().setSignature(config.getSignature()).setTo(phone)
|
||||
.setTemplateId(templateId)
|
||||
.setTemplateData(messages);
|
||||
return getSmsResponse(uniMes);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("to", Collections.singletonList(phone));
|
||||
data.put("signature", config.getSignature());
|
||||
data.put("templateId", templateId);
|
||||
data.put("templateData", messages);
|
||||
return getSmsResponse(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -75,20 +82,19 @@ public class UniSmsImpl implements SmsBlend {
|
||||
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);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("to", phones);
|
||||
data.put("signature", config.getSignature());
|
||||
data.put("templateId", templateId);
|
||||
data.put("templateData", messages);
|
||||
return getSmsResponse(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Restricted
|
||||
public void sendMessageAsync(String phone, String message, CallBack callBack) {
|
||||
pool.execute(()->{
|
||||
SmsResponse smsResponse = sendMessage(phone, message);
|
||||
callBack.callBack(smsResponse);
|
||||
});
|
||||
CompletableFuture<SmsResponse> smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, message), pool);
|
||||
smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -101,10 +107,8 @@ public class UniSmsImpl implements SmsBlend {
|
||||
@Override
|
||||
@Restricted
|
||||
public void sendMessageAsync(String phone, String templateId, LinkedHashMap<String, String> messages, CallBack callBack) {
|
||||
pool.execute(()->{
|
||||
SmsResponse smsResponse = sendMessage(phone,templateId,messages);
|
||||
callBack.callBack(smsResponse);
|
||||
});
|
||||
CompletableFuture<SmsResponse> smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, templateId, messages), pool);
|
||||
smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -156,10 +160,10 @@ public class UniSmsImpl implements SmsBlend {
|
||||
},delayedTime);
|
||||
}
|
||||
|
||||
private SmsResponse getSmsResponse(UniMessage uniMes) {
|
||||
private SmsResponse getSmsResponse( Map<String, Object> data) {
|
||||
SmsResponse smsResponse = new SmsResponse();
|
||||
try {
|
||||
UniResponse send = uniMes.send();
|
||||
UniResponse send = Uni.getClient().request("sms.message.send", data);
|
||||
smsResponse.setCode(String.valueOf(send.status));
|
||||
smsResponse.setErrorCode(send.code);
|
||||
smsResponse.setMessage(send.message);
|
||||
|
||||
@ -12,6 +12,7 @@ import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||
import org.dromara.sms4j.yunpian.config.YunpianConfig;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@ -74,10 +75,8 @@ public class YunPianSmsImpl implements SmsBlend {
|
||||
@Override
|
||||
@Restricted
|
||||
public void sendMessageAsync(String phone, String message, CallBack callBack) {
|
||||
pool.execute(() -> {
|
||||
SmsResponse smsResponse = sendMessage(phone, message);
|
||||
callBack.callBack(smsResponse);
|
||||
});
|
||||
CompletableFuture<SmsResponse> smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, message), pool);
|
||||
smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -89,10 +88,8 @@ public class YunPianSmsImpl implements SmsBlend {
|
||||
@Override
|
||||
@Restricted
|
||||
public void sendMessageAsync(String phone, String templateId, LinkedHashMap<String, String> messages, CallBack callBack) {
|
||||
pool.execute(() -> {
|
||||
SmsResponse smsResponse = sendMessage(phone, templateId, messages);
|
||||
callBack.callBack(smsResponse);
|
||||
});
|
||||
CompletableFuture<SmsResponse> smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, templateId, messages), pool);
|
||||
smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -33,5 +33,11 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user