package com.tourguide.integration.sms;
|
|
import com.aliyun.dysmsapi20170525.Client;
|
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
|
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
|
import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody;
|
import com.aliyun.teaopenapi.models.Config;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.tourguide.common.exception.BusinessException;
|
import com.tourguide.config.properties.AliyunSmsProperties;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.stereotype.Component;
|
import org.springframework.util.StringUtils;
|
|
import java.util.Collections;
|
|
@Component
|
public class AliyunSmsCodeSender implements SmsCodeSender {
|
private static final Logger LOGGER = LoggerFactory.getLogger(AliyunSmsCodeSender.class);
|
private static final String SUCCESS_CODE = "OK";
|
|
private final AliyunSmsProperties properties;
|
private final ObjectMapper objectMapper;
|
|
public AliyunSmsCodeSender(AliyunSmsProperties properties, ObjectMapper objectMapper) {
|
this.properties = properties;
|
this.objectMapper = objectMapper;
|
}
|
|
@Override
|
public void sendLoginCode(String phone, String code) {
|
ensureConfigured();
|
try {
|
SendSmsResponse response = createClient().sendSms(new SendSmsRequest()
|
.setPhoneNumbers(phone)
|
.setSignName(properties.getSignName())
|
.setTemplateCode(properties.getLoginTemplateCode())
|
.setTemplateParam(templateParam(code)));
|
ensureSuccess(phone, response == null ? null : response.getBody());
|
} catch (BusinessException exception) {
|
throw exception;
|
} catch (Exception exception) {
|
LOGGER.error("调用阿里云短信服务失败,手机号:{}", maskPhone(phone), exception);
|
throw new BusinessException(502, "短信服务暂不可用,请稍后再试");
|
}
|
}
|
|
private Client createClient() throws Exception {
|
Config config = new Config()
|
.setAccessKeyId(properties.getAccessKeyId())
|
.setAccessKeySecret(properties.getAccessKeySecret());
|
config.endpoint = properties.getEndpoint();
|
return new Client(config);
|
}
|
|
private String templateParam(String code) throws JsonProcessingException {
|
return objectMapper.writeValueAsString(Collections.singletonMap("code", code));
|
}
|
|
private void ensureSuccess(String phone, SendSmsResponseBody body) {
|
if (body != null && SUCCESS_CODE.equals(body.getCode())) {
|
return;
|
}
|
String aliyunCode = body == null ? null : body.getCode();
|
String aliyunMessage = body == null ? null : body.getMessage();
|
LOGGER.warn("阿里云短信发送失败,手机号:{},错误码:{},错误信息:{}",
|
maskPhone(phone), aliyunCode, aliyunMessage);
|
throw new BusinessException(502, "验证码发送失败,请稍后再试");
|
}
|
|
private void ensureConfigured() {
|
if (!StringUtils.hasText(properties.getAccessKeyId())
|
|| !StringUtils.hasText(properties.getAccessKeySecret())
|
|| !StringUtils.hasText(properties.getEndpoint())
|
|| !StringUtils.hasText(properties.getSignName())
|
|| !StringUtils.hasText(properties.getLoginTemplateCode())) {
|
throw new BusinessException(503, "阿里云短信配置未完成");
|
}
|
}
|
|
private String maskPhone(String phone) {
|
if (phone == null || phone.length() < 7) {
|
return "****";
|
}
|
return phone.substring(0, 3) + "****" + phone.substring(phone.length() - 4);
|
}
|
}
|