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 60  
61 61 public static SmsResult success(SmsSendFailureTypeEnum sendFailureType,
62 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 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 2  
3 3 import cn.hutool.core.collection.CollectionUtil;
4 4 import cn.hutool.core.date.DateUtil;
  5 +import cn.hutool.core.util.StrUtil;
5 6 import cn.iocoder.dashboard.framework.sms.core.SmsResult;
6 7 import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail;
7 8 import cn.iocoder.dashboard.framework.sms.core.client.impl.AbstractSmsClient;
  9 +import cn.iocoder.dashboard.framework.sms.core.enums.SmsSendFailureTypeEnum;
8 10 import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
9 11 import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
10 12 import cn.iocoder.dashboard.util.json.JsonUtils;
11 13 import com.aliyuncs.DefaultAcsClient;
12 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 19 import com.aliyuncs.profile.DefaultProfile;
14 20 import com.aliyuncs.profile.IClientProfile;
15 21 import com.fasterxml.jackson.core.type.TypeReference;
... ... @@ -36,8 +42,6 @@ public class AliyunSmsClient extends AbstractSmsClient {
36 42 private static final String DOMAIN = "dysmsapi.aliyuncs.com";
37 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 60  
57 61 @Override
58 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 106 private static SmsSendFailureTypeEnum parseSendFailureType(Result<SmsSingleSend> sendResult) {
107 107 Integer code = sendResult.getCode();
108 108 switch (code) {
  109 + case OK: return null;
109 110 case ARGUMENT_MISSING: return SmsSendFailureTypeEnum.SMS_API_PARAM_ERROR;
110 111 case BAD_ARGUMENT_FORMAT: return SmsSendFailureTypeEnum.SMS_TEMPLATE_PARAM_ERROR;
111 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 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 14  
15 15 // ========== 渠道相关(100 开头) ==========
16 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 20 // ========== 模板相关(200 开头) ==========
19 21 SMS_TEMPLATE_NOT_EXISTS(200, "短信模板不存在"),
20 22 SMS_TEMPLATE_DISABLE(201, "短信模板被禁用"), // 例如说,我们在管理后台禁用了
21   - SMS_TMPLATE_INVALID(202, "短信模板不可用"), // 例如说,短信模板正在审核中
  23 + SMS_TEMPLATE_INVALID(202, "短信模板不可用"), // 例如说,短信模板正在审核中
22 24 SMS_TEMPLATE_PARAM_ERROR(203, "模板参数不正确"),
23 25  
24 26 // ========== 其它相关(900 开头) ==========
25 27 SMS_API_PARAM_ERROR(900, "请求参数缺失"),
26 28  
  29 + SMS_SEND_LIMIT_CONTROL(997, "业务限流"), // 将短信发送频率限制在正常的业务限流范围内。默认短信验证码:使用同一签名,对同一个手机号验证码,支持 1 条 / 分钟,5 条 / 小时,累计 10 条 / 天。
27 30 SMS_SEND_EXCEPTION(998, "发送异常"),
28 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 +}
... ...