Commit 60911c9f56058ced79a55af6a8cbfa29a7fdf0bf

Authored by YunaiV
1 parent 52b51254

阿里云短信的调试

src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsResult.java
@@ -60,8 +60,12 @@ public class SmsResult implements Serializable { @@ -60,8 +60,12 @@ public class SmsResult implements Serializable {
60 60
61 public static SmsResult success(SmsSendFailureTypeEnum sendFailureType, 61 public static SmsResult success(SmsSendFailureTypeEnum sendFailureType,
62 String apiSendCode, String apiSendMsg, String apiRequestId, String apiSerialNo) { 62 String apiSendCode, String apiSendMsg, String apiRequestId, String apiSerialNo) {
63 - return new SmsResult().setSuccess(true).setSendFailureType(sendFailureType.getType()).setSendFailureMsg(sendFailureType.getMsg())  
64 - .setApiSendCode(apiSendCode).setApiSendMsg(apiSendMsg).setApiRequestId(apiRequestId).setApiSerialNo(apiSerialNo); 63 + SmsResult result = new SmsResult().setSuccess(true).setApiSendCode(apiSendCode).setApiSendMsg(apiSendMsg)
  64 + .setApiRequestId(apiRequestId).setApiSerialNo(apiSerialNo);
  65 + if (sendFailureType != null) {
  66 + result.setSendFailureType(sendFailureType.getType()).setSendFailureMsg(sendFailureType.getMsg());
  67 + }
  68 + return result;
65 } 69 }
66 70
67 public static SmsResult error(Throwable ex) { 71 public static SmsResult error(Throwable ex) {
src/main/java/cn/iocoder/dashboard/framework/sms/core/client/impl/aliyun/AliyunSmsClient.java
@@ -2,14 +2,20 @@ package cn.iocoder.dashboard.framework.sms.core.client.impl.aliyun; @@ -2,14 +2,20 @@ package cn.iocoder.dashboard.framework.sms.core.client.impl.aliyun;
2 2
3 import cn.hutool.core.collection.CollectionUtil; 3 import cn.hutool.core.collection.CollectionUtil;
4 import cn.hutool.core.date.DateUtil; 4 import cn.hutool.core.date.DateUtil;
  5 +import cn.hutool.core.util.StrUtil;
5 import cn.iocoder.dashboard.framework.sms.core.SmsResult; 6 import cn.iocoder.dashboard.framework.sms.core.SmsResult;
6 import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail; 7 import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail;
7 import cn.iocoder.dashboard.framework.sms.core.client.impl.AbstractSmsClient; 8 import cn.iocoder.dashboard.framework.sms.core.client.impl.AbstractSmsClient;
  9 +import cn.iocoder.dashboard.framework.sms.core.enums.SmsSendFailureTypeEnum;
8 import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties; 10 import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
9 import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum; 11 import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
10 import cn.iocoder.dashboard.util.json.JsonUtils; 12 import cn.iocoder.dashboard.util.json.JsonUtils;
11 import com.aliyuncs.DefaultAcsClient; 13 import com.aliyuncs.DefaultAcsClient;
12 import com.aliyuncs.IAcsClient; 14 import com.aliyuncs.IAcsClient;
  15 +import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
  16 +import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
  17 +import com.aliyuncs.exceptions.ClientException;
  18 +import com.aliyuncs.http.MethodType;
13 import com.aliyuncs.profile.DefaultProfile; 19 import com.aliyuncs.profile.DefaultProfile;
14 import com.aliyuncs.profile.IClientProfile; 20 import com.aliyuncs.profile.IClientProfile;
15 import com.fasterxml.jackson.core.type.TypeReference; 21 import com.fasterxml.jackson.core.type.TypeReference;
@@ -36,8 +42,6 @@ public class AliyunSmsClient extends AbstractSmsClient { @@ -36,8 +42,6 @@ public class AliyunSmsClient extends AbstractSmsClient {
36 private static final String DOMAIN = "dysmsapi.aliyuncs.com"; 42 private static final String DOMAIN = "dysmsapi.aliyuncs.com";
37 private static final String ENDPOINT = "cn-hangzhou"; 43 private static final String ENDPOINT = "cn-hangzhou";
38 44
39 - private static final String OK = "OK";  
40 -  
41 /** 45 /**
42 * 阿里云客户端 46 * 阿里云客户端
43 */ 47 */
@@ -56,29 +60,44 @@ public class AliyunSmsClient extends AbstractSmsClient { @@ -56,29 +60,44 @@ public class AliyunSmsClient extends AbstractSmsClient {
56 60
57 @Override 61 @Override
58 protected SmsResult doSend(Long sendLogId, String mobile, String apiTemplateId, Map<String, Object> templateParams) throws Exception { 62 protected SmsResult doSend(Long sendLogId, String mobile, String apiTemplateId, Map<String, Object> templateParams) throws Exception {
59 - return null; 63 + // 构建参数
  64 + SendSmsRequest request = new SendSmsRequest();
  65 + request.setSysMethod(MethodType.POST);
  66 + request.setPhoneNumbers(mobile);
  67 + request.setSignName(properties.getSignature());
  68 + request.setTemplateCode(apiTemplateId);
  69 + request.setTemplateParam(JsonUtils.toJsonString(templateParams));
  70 + request.setOutId(String.valueOf(sendLogId));
  71 +
  72 + try {
  73 + // 执行发送
  74 + SendSmsResponse sendResult = acsClient.getAcsResponse(request);
  75 + // 解析结果
  76 + return SmsResult.success(parseSendFailureType(sendResult.getCode()), // 将 API 短信平台,解析成统一的错误码
  77 + sendResult.getCode(), sendResult.getMessage(), sendResult.getRequestId(), sendResult.getBizId());
  78 + } catch (ClientException ex) {
  79 + return SmsResult.success(parseSendFailureType(ex.getErrCode()), // 将 API 短信平台,解析成统一的错误码
  80 + ex.getErrCode(), formatResultMsg(ex), ex.getRequestId(), null);
  81 + }
  82 + }
  83 +
  84 + private static SmsSendFailureTypeEnum parseSendFailureType(String code) {
  85 + switch (code) {
  86 + case "OK": return null;
  87 + case "MissingAccessKeyId": return SmsSendFailureTypeEnum.SMS_CHANNEL_API_KEY_MISSING;
  88 + case "isp.RAM_PERMISSION_DENY": return SmsSendFailureTypeEnum.SMS_CHANNEL_PERMISSION_DENY;
  89 + case "isv.INVALID_PARAMETERS": return SmsSendFailureTypeEnum.SMS_API_PARAM_ERROR;
  90 + case "isv.BUSINESS_LIMIT_CONTROL": return SmsSendFailureTypeEnum.SMS_SEND_LIMIT_CONTROL;
  91 + }
  92 + return SmsSendFailureTypeEnum.SMS_UNKNOWN;
60 } 93 }
61 94
62 -// @Override  
63 -// public SmsResult doSend(String templateApiId, SmsBody smsBody, String targetPhone) throws Exception {  
64 -// SendSmsRequest request = new SendSmsRequest();  
65 -// request.setSysMethod(MethodType.POST);  
66 -// request.setPhoneNumbers(targetPhone);  
67 -// request.setSignName(properties.getSignature());  
68 -// request.setTemplateCode(templateApiId);  
69 -// request.setTemplateParam(smsBody.getParamsStr());  
70 -// SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);  
71 -//  
72 -// boolean success = OK.equals(sendSmsResponse.getCode());  
73 -// if (!success) {  
74 -// log.debug("send fail[code={}, message={}]", sendSmsResponse.getCode(), sendSmsResponse.getMessage());  
75 -// }  
76 -// return new SmsResult()  
77 -// .setSuccess(success)  
78 -// .setMessage(sendSmsResponse.getMessage())  
79 -// .setCode(sendSmsResponse.getCode())  
80 -// .setApiId(sendSmsResponse.getBizId());  
81 -// } 95 + private static String formatResultMsg(ClientException ex) {
  96 + if (StrUtil.isEmpty(ex.getErrorDescription())) {
  97 + return ex.getMessage();
  98 + }
  99 + return ex.getErrMsg() + " => " + ex.getErrorDescription();
  100 + }
82 101
83 /** 102 /**
84 * [{ 103 * [{
src/main/java/cn/iocoder/dashboard/framework/sms/core/client/impl/yunpian/YunpianSmsClient.java
@@ -106,10 +106,11 @@ public class YunpianSmsClient extends AbstractSmsClient { @@ -106,10 +106,11 @@ public class YunpianSmsClient extends AbstractSmsClient {
106 private static SmsSendFailureTypeEnum parseSendFailureType(Result<SmsSingleSend> sendResult) { 106 private static SmsSendFailureTypeEnum parseSendFailureType(Result<SmsSingleSend> sendResult) {
107 Integer code = sendResult.getCode(); 107 Integer code = sendResult.getCode();
108 switch (code) { 108 switch (code) {
  109 + case OK: return null;
109 case ARGUMENT_MISSING: return SmsSendFailureTypeEnum.SMS_API_PARAM_ERROR; 110 case ARGUMENT_MISSING: return SmsSendFailureTypeEnum.SMS_API_PARAM_ERROR;
110 case BAD_ARGUMENT_FORMAT: return SmsSendFailureTypeEnum.SMS_TEMPLATE_PARAM_ERROR; 111 case BAD_ARGUMENT_FORMAT: return SmsSendFailureTypeEnum.SMS_TEMPLATE_PARAM_ERROR;
111 case TPL_NOT_FOUND: return SmsSendFailureTypeEnum.SMS_TEMPLATE_NOT_EXISTS; 112 case TPL_NOT_FOUND: return SmsSendFailureTypeEnum.SMS_TEMPLATE_NOT_EXISTS;
112 - case TPL_NOT_VALID: return SmsSendFailureTypeEnum.SMS_TMPLATE_INVALID; 113 + case TPL_NOT_VALID: return SmsSendFailureTypeEnum.SMS_TEMPLATE_INVALID;
113 } 114 }
114 return SmsSendFailureTypeEnum.SMS_UNKNOWN; 115 return SmsSendFailureTypeEnum.SMS_UNKNOWN;
115 } 116 }
src/main/java/cn/iocoder/dashboard/framework/sms/core/enums/SmsSendFailureTypeEnum.java
@@ -14,16 +14,19 @@ public enum SmsSendFailureTypeEnum { @@ -14,16 +14,19 @@ public enum SmsSendFailureTypeEnum {
14 14
15 // ========== 渠道相关(100 开头) ========== 15 // ========== 渠道相关(100 开头) ==========
16 SMS_CHANNEL_CLIENT_NOT_EXISTS(100, "短信渠道的客户端不存在"), 16 SMS_CHANNEL_CLIENT_NOT_EXISTS(100, "短信渠道的客户端不存在"),
  17 + SMS_CHANNEL_API_KEY_MISSING(101, "API Key 不存在"),
  18 + SMS_CHANNEL_PERMISSION_DENY(102, "没有发送短信的权限"),
17 19
18 // ========== 模板相关(200 开头) ========== 20 // ========== 模板相关(200 开头) ==========
19 SMS_TEMPLATE_NOT_EXISTS(200, "短信模板不存在"), 21 SMS_TEMPLATE_NOT_EXISTS(200, "短信模板不存在"),
20 SMS_TEMPLATE_DISABLE(201, "短信模板被禁用"), // 例如说,我们在管理后台禁用了 22 SMS_TEMPLATE_DISABLE(201, "短信模板被禁用"), // 例如说,我们在管理后台禁用了
21 - SMS_TMPLATE_INVALID(202, "短信模板不可用"), // 例如说,短信模板正在审核中 23 + SMS_TEMPLATE_INVALID(202, "短信模板不可用"), // 例如说,短信模板正在审核中
22 SMS_TEMPLATE_PARAM_ERROR(203, "模板参数不正确"), 24 SMS_TEMPLATE_PARAM_ERROR(203, "模板参数不正确"),
23 25
24 // ========== 其它相关(900 开头) ========== 26 // ========== 其它相关(900 开头) ==========
25 SMS_API_PARAM_ERROR(900, "请求参数缺失"), 27 SMS_API_PARAM_ERROR(900, "请求参数缺失"),
26 28
  29 + SMS_SEND_LIMIT_CONTROL(997, "业务限流"), // 将短信发送频率限制在正常的业务限流范围内。默认短信验证码:使用同一签名,对同一个手机号验证码,支持 1 条 / 分钟,5 条 / 小时,累计 10 条 / 天。
27 SMS_SEND_EXCEPTION(998, "发送异常"), 30 SMS_SEND_EXCEPTION(998, "发送异常"),
28 SMS_UNKNOWN(999, "未知错误,需要解析") 31 SMS_UNKNOWN(999, "未知错误,需要解析")
29 ; 32 ;
src/test-integration/java/cn/iocoder/dashboard/framework/sms/core/client/impl/aliyun/AliyunSmsClientTest.java 0 → 100644
  1 +package cn.iocoder.dashboard.framework.sms.core.client.impl.aliyun;
  2 +
  3 +import cn.iocoder.dashboard.framework.sms.core.SmsResult;
  4 +import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum;
  5 +import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
  6 +import org.junit.jupiter.api.Test;
  7 +
  8 +import java.util.HashMap;
  9 +import java.util.Map;
  10 +
  11 +/**
  12 + * {@link AliyunSmsClient} 的集成测试
  13 + */
  14 +public class AliyunSmsClientTest {
  15 +
  16 + @Test
  17 + public void testSend() {
  18 + // 创建配置类
  19 + SmsChannelProperties properties = new SmsChannelProperties();
  20 + properties.setId(1L);
  21 + properties.setSignature("Ballcat");
  22 + properties.setCode(SmsChannelEnum.ALIYUN.getCode());
  23 + properties.setApiKey(System.getenv("ALIYUN_ACCESS_KEY"));
  24 + properties.setApiSecret(System.getenv("ALIYUN_SECRET_KEY"));
  25 + // 创建客户端
  26 + AliyunSmsClient smsClient = new AliyunSmsClient(properties);
  27 + smsClient.init();
  28 + // 发送短信
  29 + Map<String, Object> templateParams = new HashMap<>();
  30 + templateParams.put("code", "1024");
  31 +// templateParams.put("operation", "嘿嘿");
  32 +// SmsResult result = smsClient.send(1L, "15601691399", "4372216", templateParams);
  33 + SmsResult result = smsClient.send(1L, "15601691399", "SMS_207945135", templateParams);
  34 + System.out.println(result);
  35 + }
  36 +
  37 +}