mirror of
https://gitee.com/dromara/sms4j.git
synced 2025-12-07 17:38:38 +08:00
add 新增天翼云通信
This commit is contained in:
parent
55ac38175e
commit
901327b8b6
@ -26,6 +26,8 @@ public enum SupplierType {
|
|||||||
* 亿美软通
|
* 亿美软通
|
||||||
*/
|
*/
|
||||||
EMAY("亿美软通"),
|
EMAY("亿美软通"),
|
||||||
|
/** 天翼云 */
|
||||||
|
CTYUN("天翼云短信"),
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package org.dromara.sms4j.core.config;
|
|||||||
|
|
||||||
import org.dromara.sms4j.comm.enumerate.SupplierType;
|
import org.dromara.sms4j.comm.enumerate.SupplierType;
|
||||||
import org.dromara.sms4j.core.factory.SmsFactory;
|
import org.dromara.sms4j.core.factory.SmsFactory;
|
||||||
|
import org.dromara.sms4j.ctyun.config.CtyunConfig;
|
||||||
import org.dromara.sms4j.emay.config.EmayConfig;
|
import org.dromara.sms4j.emay.config.EmayConfig;
|
||||||
import org.dromara.sms4j.aliyun.config.AlibabaConfig;
|
import org.dromara.sms4j.aliyun.config.AlibabaConfig;
|
||||||
import org.dromara.sms4j.cloopen.config.CloopenConfig;
|
import org.dromara.sms4j.cloopen.config.CloopenConfig;
|
||||||
@ -47,6 +48,11 @@ public class SupplierFactory {
|
|||||||
*/
|
*/
|
||||||
private static EmayConfig emayConfig;
|
private static EmayConfig emayConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 天翼云短信差异配置
|
||||||
|
*/
|
||||||
|
private static CtyunConfig ctyunConfig;
|
||||||
|
|
||||||
/** 阿里云配置获取*/
|
/** 阿里云配置获取*/
|
||||||
public static AlibabaConfig getAlibabaConfig() {
|
public static AlibabaConfig getAlibabaConfig() {
|
||||||
if (alibabaConfig == null){
|
if (alibabaConfig == null){
|
||||||
@ -113,6 +119,16 @@ public class SupplierFactory {
|
|||||||
return emayConfig;
|
return emayConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 天翼云配置获取
|
||||||
|
*/
|
||||||
|
public static CtyunConfig getCtyunConfig() {
|
||||||
|
if (ctyunConfig == null) {
|
||||||
|
ctyunConfig = CtyunConfig.builder().build();
|
||||||
|
}
|
||||||
|
return ctyunConfig;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置 alibabaConfig
|
* 设置 alibabaConfig
|
||||||
*/
|
*/
|
||||||
@ -176,4 +192,12 @@ public class SupplierFactory {
|
|||||||
SupplierFactory.emayConfig = emayConfig;
|
SupplierFactory.emayConfig = emayConfig;
|
||||||
SmsFactory.refresh(SupplierType.EMAY);
|
SmsFactory.refresh(SupplierType.EMAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置 emayConfig
|
||||||
|
*/
|
||||||
|
public static void setCtyunConfig(CtyunConfig ctyunConfig) {
|
||||||
|
SupplierFactory.ctyunConfig = ctyunConfig;
|
||||||
|
SmsFactory.refresh(SupplierType.EMAY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import org.dromara.sms4j.comm.enumerate.SupplierType;
|
|||||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||||
import org.dromara.sms4j.core.SupplierSqlConfig;
|
import org.dromara.sms4j.core.SupplierSqlConfig;
|
||||||
import org.dromara.sms4j.core.config.SupplierFactory;
|
import org.dromara.sms4j.core.config.SupplierFactory;
|
||||||
|
import org.dromara.sms4j.ctyun.config.CtyunSmsConfig;
|
||||||
import org.dromara.sms4j.emay.config.EmaySmsConfig;
|
import org.dromara.sms4j.emay.config.EmaySmsConfig;
|
||||||
import org.dromara.sms4j.huawei.config.HuaweiSmsConfig;
|
import org.dromara.sms4j.huawei.config.HuaweiSmsConfig;
|
||||||
import org.dromara.sms4j.jdcloud.config.JdCloudSmsConfig;
|
import org.dromara.sms4j.jdcloud.config.JdCloudSmsConfig;
|
||||||
@ -49,6 +50,8 @@ public abstract class SmsFactory {
|
|||||||
return CloopenSmsConfig.createCloopenSms(SupplierFactory.getCloopenConfig());
|
return CloopenSmsConfig.createCloopenSms(SupplierFactory.getCloopenConfig());
|
||||||
case EMAY:
|
case EMAY:
|
||||||
return EmaySmsConfig.createEmaySms(SupplierFactory.getEmayConfig());
|
return EmaySmsConfig.createEmaySms(SupplierFactory.getEmayConfig());
|
||||||
|
case CTYUN:
|
||||||
|
return CtyunSmsConfig.createCtyunSms(SupplierFactory.getCtyunConfig());
|
||||||
}
|
}
|
||||||
throw new SmsBlendException("An attempt to construct a SmsBlend object failed. Please check that the enumeration is valid");
|
throw new SmsBlendException("An attempt to construct a SmsBlend object failed. Please check that the enumeration is valid");
|
||||||
}
|
}
|
||||||
@ -68,6 +71,7 @@ public abstract class SmsFactory {
|
|||||||
JdCloudSmsConfig.refresh(SupplierFactory.getJdCloudConfig());
|
JdCloudSmsConfig.refresh(SupplierFactory.getJdCloudConfig());
|
||||||
CloopenSmsConfig.refresh(SupplierFactory.getCloopenConfig());
|
CloopenSmsConfig.refresh(SupplierFactory.getCloopenConfig());
|
||||||
EmaySmsConfig.refresh(SupplierFactory.getEmayConfig());
|
EmaySmsConfig.refresh(SupplierFactory.getEmayConfig());
|
||||||
|
CtyunSmsConfig.refresh(SupplierFactory.getCtyunConfig());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,6 +104,9 @@ public abstract class SmsFactory {
|
|||||||
case EMAY:
|
case EMAY:
|
||||||
EmaySmsConfig.refresh(SupplierFactory.getEmayConfig());
|
EmaySmsConfig.refresh(SupplierFactory.getEmayConfig());
|
||||||
break;
|
break;
|
||||||
|
case CTYUN:
|
||||||
|
CtyunSmsConfig.refresh(SupplierFactory.getCtyunConfig());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new SmsBlendException("An attempt to construct a SmsBlend object failed. Please check that the enumeration is valid");
|
throw new SmsBlendException("An attempt to construct a SmsBlend object failed. Please check that the enumeration is valid");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,39 @@
|
|||||||
|
package org.dromara.sms4j.ctyun.config;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.ToString;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
import org.dromara.sms4j.comm.config.BaseConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>类名: CtyunConfig
|
||||||
|
* <p>说明: 天翼云短信差异配置
|
||||||
|
*
|
||||||
|
* @author :bleachhtred
|
||||||
|
* 2023/5/12 15:06
|
||||||
|
**/
|
||||||
|
@Data
|
||||||
|
@SuperBuilder
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class CtyunConfig extends BaseConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板变量名称
|
||||||
|
*/
|
||||||
|
private String templateName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求地址
|
||||||
|
*/
|
||||||
|
@Builder.Default
|
||||||
|
private String requestUrl = "https://sms-global.ctapi.ctyun.cn/sms/api/v1";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口名称
|
||||||
|
*/
|
||||||
|
@Builder.Default
|
||||||
|
private String action = "SendSms";
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
package org.dromara.sms4j.ctyun.config;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.sms4j.comm.factory.BeanFactory;
|
||||||
|
import org.dromara.sms4j.ctyun.service.CtyunSmsImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>类名: CtyunSmsConfig
|
||||||
|
* <p>说明: 天翼云 云通信短信配置器
|
||||||
|
*
|
||||||
|
* @author :bleachhtred
|
||||||
|
* 2023/5/12 15:06
|
||||||
|
**/
|
||||||
|
@Slf4j
|
||||||
|
public class CtyunSmsConfig {
|
||||||
|
|
||||||
|
private static CtyunSmsImpl ctyunSms;
|
||||||
|
|
||||||
|
private static CtyunSmsConfig ctyunSmsConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getCtyunSms
|
||||||
|
* <p> 建造一个短信实现对像
|
||||||
|
*
|
||||||
|
* @author :bleachhtred
|
||||||
|
*/
|
||||||
|
public static CtyunSmsImpl createCtyunSms(CtyunConfig alibabaConfig) {
|
||||||
|
if (ctyunSmsConfig == null) {
|
||||||
|
ctyunSmsConfig = new CtyunSmsConfig();
|
||||||
|
}
|
||||||
|
if (ctyunSms == null) {
|
||||||
|
ctyunSms = new CtyunSmsImpl(
|
||||||
|
alibabaConfig,
|
||||||
|
BeanFactory.getExecutor(),
|
||||||
|
BeanFactory.getDelayedTime());
|
||||||
|
}
|
||||||
|
return ctyunSms;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* refresh
|
||||||
|
* <p> 刷新对象
|
||||||
|
*
|
||||||
|
* @author :bleachhtred
|
||||||
|
*/
|
||||||
|
public static CtyunSmsImpl refresh(CtyunConfig alibabaConfig) {
|
||||||
|
// 如果配置对象为空则创建一个
|
||||||
|
if (ctyunSmsConfig == null) {
|
||||||
|
ctyunSmsConfig = new CtyunSmsConfig();
|
||||||
|
}
|
||||||
|
//重新构造一个实现对象
|
||||||
|
ctyunSms = new CtyunSmsImpl(
|
||||||
|
alibabaConfig,
|
||||||
|
BeanFactory.getExecutor(),
|
||||||
|
BeanFactory.getDelayedTime());
|
||||||
|
return ctyunSms;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CtyunSmsConfig() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,197 @@
|
|||||||
|
package org.dromara.sms4j.ctyun.service;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.dtflys.forest.config.ForestConfiguration;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.sms4j.api.SmsBlend;
|
||||||
|
import org.dromara.sms4j.api.callback.CallBack;
|
||||||
|
import org.dromara.sms4j.api.entity.SmsResponse;
|
||||||
|
import org.dromara.sms4j.comm.annotation.Restricted;
|
||||||
|
import org.dromara.sms4j.comm.delayedTime.DelayedTime;
|
||||||
|
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||||
|
import org.dromara.sms4j.comm.factory.BeanFactory;
|
||||||
|
import org.dromara.sms4j.ctyun.config.CtyunConfig;
|
||||||
|
import org.dromara.sms4j.ctyun.utils.CtyunUtils;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>类名: CtyunSmsImpl
|
||||||
|
* <p>说明: 天翼云短信实现
|
||||||
|
*
|
||||||
|
* @author :bleachhtred
|
||||||
|
* 2023/5/12 15:06
|
||||||
|
**/
|
||||||
|
@Slf4j
|
||||||
|
public class CtyunSmsImpl implements SmsBlend {
|
||||||
|
|
||||||
|
private final CtyunConfig ctyunConfig;
|
||||||
|
|
||||||
|
private final Executor pool;
|
||||||
|
|
||||||
|
private final DelayedTime delayed;
|
||||||
|
|
||||||
|
private final ForestConfiguration http = BeanFactory.getForestConfiguration();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AlibabaSmsImpl
|
||||||
|
* <p>构造器,用于构造短信实现模块
|
||||||
|
*
|
||||||
|
* @author :Wind
|
||||||
|
*/
|
||||||
|
|
||||||
|
public CtyunSmsImpl(CtyunConfig ctyunConfig, Executor pool, DelayedTime delayedTime) {
|
||||||
|
this.ctyunConfig = ctyunConfig;
|
||||||
|
this.pool = pool;
|
||||||
|
this.delayed = delayedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Restricted
|
||||||
|
public SmsResponse sendMessage(String phone, String message) {
|
||||||
|
LinkedHashMap<String, String> map = new LinkedHashMap<>();
|
||||||
|
map.put(ctyunConfig.getTemplateName(), message);
|
||||||
|
return sendMessage(phone, ctyunConfig.getTemplateId(), map);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Restricted
|
||||||
|
public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap<String, String> messages) {
|
||||||
|
String messageStr = JSON.toJSONString(messages);
|
||||||
|
return getSmsResponse(phone, messageStr, templateId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Restricted
|
||||||
|
public SmsResponse massTexting(List<String> phones, String message) {
|
||||||
|
LinkedHashMap<String, String> map = new LinkedHashMap<>();
|
||||||
|
map.put(ctyunConfig.getTemplateName(), message);
|
||||||
|
return massTexting(phones, ctyunConfig.getTemplateId(), map);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Restricted
|
||||||
|
public SmsResponse massTexting(List<String> phones, String templateId, LinkedHashMap<String, String> messages) {
|
||||||
|
String messageStr = JSON.toJSONString(messages);
|
||||||
|
return getSmsResponse(arrayToString(phones), messageStr, templateId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SmsResponse getSmsResponse(String phone, String message, String templateId) {
|
||||||
|
AtomicReference<SmsResponse> smsResponse = new AtomicReference<>();
|
||||||
|
String requestUrl;
|
||||||
|
String paramStr;
|
||||||
|
try {
|
||||||
|
requestUrl = ctyunConfig.getRequestUrl();
|
||||||
|
paramStr = CtyunUtils.generateParamJsonStr(ctyunConfig, phone, message, templateId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("ctyun send message error", e);
|
||||||
|
throw new SmsBlendException(e.getMessage());
|
||||||
|
}
|
||||||
|
log.debug("requestUrl {}", requestUrl);
|
||||||
|
http.post(requestUrl)
|
||||||
|
.addHeader(CtyunUtils.signHeader(paramStr, ctyunConfig.getAccessKeyId(), ctyunConfig.getAccessKeySecret()))
|
||||||
|
.addBody(paramStr)
|
||||||
|
.onSuccess(((data, req, res) -> {
|
||||||
|
Map map = res.get(Map.class);
|
||||||
|
smsResponse.set(getResponse(map));
|
||||||
|
}))
|
||||||
|
.onError((ex, req, res) -> {
|
||||||
|
Map map = res.get(Map.class);
|
||||||
|
smsResponse.set(getResponse(map));
|
||||||
|
})
|
||||||
|
.execute();
|
||||||
|
return smsResponse.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SmsResponse getResponse(Map map) {
|
||||||
|
SmsResponse smsResponse = new SmsResponse();
|
||||||
|
smsResponse.setCode((String) map.get("code"));
|
||||||
|
smsResponse.setMessage((String) map.get("message"));
|
||||||
|
smsResponse.setBizId((String) map.get("requestId"));
|
||||||
|
return smsResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Restricted
|
||||||
|
public void sendMessageAsync(String phone, String message, CallBack callBack) {
|
||||||
|
CompletableFuture<SmsResponse> smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone, message), pool);
|
||||||
|
smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Restricted
|
||||||
|
public void sendMessageAsync(String phone, String message) {
|
||||||
|
pool.execute(() -> sendMessage(phone, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Restricted
|
||||||
|
public void sendMessageAsync(String phone, String templateId, LinkedHashMap<String, String> messages, CallBack callBack) {
|
||||||
|
CompletableFuture<SmsResponse> smsResponseCompletableFuture = CompletableFuture.supplyAsync(() -> sendMessage(phone,templateId, messages), pool);
|
||||||
|
smsResponseCompletableFuture.thenAcceptAsync(callBack::callBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Restricted
|
||||||
|
public void sendMessageAsync(String phone, String templateId, LinkedHashMap<String, String> messages) {
|
||||||
|
pool.execute(() -> sendMessage(phone, templateId, messages));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Restricted
|
||||||
|
public void delayedMessage(String phone, String message, Long delayedTime) {
|
||||||
|
this.delayed.schedule(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
sendMessage(phone, message);
|
||||||
|
}
|
||||||
|
}, delayedTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Restricted
|
||||||
|
public void delayedMessage(String phone, String templateId, LinkedHashMap<String, String> messages, Long delayedTime) {
|
||||||
|
this.delayed.schedule(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
sendMessage(phone, templateId, messages);
|
||||||
|
}
|
||||||
|
}, delayedTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Restricted
|
||||||
|
public void delayMassTexting(List<String> phones, String message, Long delayedTime) {
|
||||||
|
this.delayed.schedule(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
massTexting(phones, message);
|
||||||
|
}
|
||||||
|
}, delayedTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Restricted
|
||||||
|
public void delayMassTexting(List<String> phones, String templateId, LinkedHashMap<String, String> messages, Long delayedTime) {
|
||||||
|
this.delayed.schedule(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
massTexting(phones, templateId, messages);
|
||||||
|
}
|
||||||
|
}, delayedTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String arrayToString(List<String> list) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (String s : list) {
|
||||||
|
sb.append(",").append("+86").append(s);
|
||||||
|
}
|
||||||
|
return sb.substring(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,114 @@
|
|||||||
|
package org.dromara.sms4j.ctyun.utils;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||||
|
import org.dromara.sms4j.ctyun.config.CtyunConfig;
|
||||||
|
|
||||||
|
import javax.crypto.Mac;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public class CtyunUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取签名时间戳
|
||||||
|
*/
|
||||||
|
private static String signatureTime(){
|
||||||
|
SimpleDateFormat timeFormat = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
|
||||||
|
return timeFormat.format(new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取签名请求头
|
||||||
|
*/
|
||||||
|
public static Map<String, String> signHeader(String body, String key, String secret){
|
||||||
|
Map<String, String> map = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
// 构造时间戳
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
|
||||||
|
Date now = new Date();
|
||||||
|
String signatureDate = dateFormat.format(now);
|
||||||
|
String signatureTime = signatureTime();
|
||||||
|
// 构造请求流水号
|
||||||
|
String uuid = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
String calculateContentHash = getSHA256(body);
|
||||||
|
|
||||||
|
byte[] kTime = hmacSHA256(signatureTime.getBytes(), secret.getBytes());
|
||||||
|
byte[] kAk = hmacSHA256(key.getBytes(), kTime);
|
||||||
|
byte[] kDate = hmacSHA256(signatureDate.getBytes(), kAk);
|
||||||
|
|
||||||
|
// 构造待签名字符串
|
||||||
|
|
||||||
|
// 报文原封不动进行sha256摘要
|
||||||
|
String signatureStr = String.format("ctyun-eop-request-id:%s\neop-date:%s\n", uuid, signatureTime) + "\n\n" + calculateContentHash;
|
||||||
|
// 构造签名
|
||||||
|
String signature = Base64.getEncoder().encodeToString(hmacSHA256(signatureStr.getBytes(StandardCharsets.UTF_8), kDate));
|
||||||
|
String signHeader = String.format("%s Headers=ctyun-eop-request-id;eop-date Signature=%s", key, signature);
|
||||||
|
map.put("Content-Type", "application/json;charset=UTF-8");
|
||||||
|
map.put("ctyun-eop-request-id", uuid);
|
||||||
|
map.put("Eop-date", signatureTime);
|
||||||
|
map.put("Eop-Authorization", signHeader);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成请求body参数
|
||||||
|
*
|
||||||
|
* @param ctyunConfig 配置数据
|
||||||
|
* @param phone 手机号
|
||||||
|
* @param message 短信内容
|
||||||
|
* @param templateId 模板id
|
||||||
|
*/
|
||||||
|
public static String generateParamJsonStr(CtyunConfig ctyunConfig, String phone, String message, String templateId) {
|
||||||
|
Map<String, String> paramMap = new HashMap<>();
|
||||||
|
paramMap.put("action", ctyunConfig.getAction());
|
||||||
|
paramMap.put("phoneNumber", phone);
|
||||||
|
paramMap.put("signName", ctyunConfig.getSignature());
|
||||||
|
paramMap.put("templateParam", message);
|
||||||
|
paramMap.put("templateCode", templateId);
|
||||||
|
return JSONObject.toJSONString(paramMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String toHex(byte[] data) {
|
||||||
|
StringBuilder sb = new StringBuilder(data.length * 2);
|
||||||
|
for (byte b : data) {
|
||||||
|
String hex = Integer.toHexString(b);
|
||||||
|
if (hex.length() == 1) {
|
||||||
|
sb.append("0");
|
||||||
|
} else if (hex.length() == 8) {
|
||||||
|
hex = hex.substring(6);
|
||||||
|
}
|
||||||
|
sb.append(hex);
|
||||||
|
}
|
||||||
|
return sb.toString().toLowerCase(Locale.getDefault());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getSHA256(String text) {
|
||||||
|
try {
|
||||||
|
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||||
|
md.update(text.getBytes(StandardCharsets.UTF_8));
|
||||||
|
return toHex(md.digest());
|
||||||
|
} catch (NoSuchAlgorithmException var3) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] hmacSHA256(byte[] data, byte[] key){
|
||||||
|
try {
|
||||||
|
Mac mac = Mac.getInstance("HmacSHA256");
|
||||||
|
mac.init(new SecretKeySpec(key, "HmacSHA256"));
|
||||||
|
return mac.doFinal(data);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new SmsBlendException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user