Spring Boot - 实用功能26 - SMS相关使用
文章目录
一:概述和前置准备
SSM是阿里云为用户提供的一种通信服务的能力。
支持向国内和国际快速发送验证码、短信通知和推广短信,服务范围覆盖全球200多个国家和地区。
国内短信支持三网合一专属通道,与工信部携号转网平台实时互联。
电信级运维保障,实时监控自动切换,到达率高达99%。完美支撑双11期间20亿短信发送,6亿用户触达
1:收费标准
短信服务是按量计费模式,同时支持国内短信套餐包,根据短信模板的不同,进行梯度计费。
- 国内短信:支持按量付费和国内短信套餐包。更多信息,请参见国内短信定价。
- 国际/港澳台短信:支持按量付费和国际/港澳台短信套餐包。更多信息,请参见国际/港澳台短信定价。
若短信发送5分钟后还未返回状态,将先扣费,实际返回状态后根据失败条数进行短信量返补。
- 国内短信接口调用失败及运营商返回失败状态,都不会扣费;
- 国际短信按导入号码成功计费,即运营商反馈失败也要计费。
国内短信月消费金额=月累计短信成功发送量所在的档位×月累计短信发送成功量。
例如:110万单价是0.045元/条,1030万单价是0.04元/条,若您当月累计用了15万,则消费金额为15万×0.04元/条。
短信服务产品属于后付费产品,即发送短信成功才会开始计费。
不同短信模板的单价不同,产生费用后,进行累计计费,每5分钟出账一次,每个月月底进行扣费。
短信服务采用的是T+2的模式,即当月出具账单后,在下下个月可以申请发票。
例如,10月31日出具10月完整账单,12月申请10月的发票。
阿里云账户余额为0,或阿里云账户处于欠费状态时,即使国内短信套餐包仍有余量也无法发送短信。
2:字数计算
国内的短信
短信长度(字数)=短信模版内容字数+签名字数。
-
汉字、字母、数字、符号(不区分全角和半角),都按照一个字计算。
-
短信长度不超过70个字,按照一条短信计费;超过70个字,即为长短信,按照67字/条拆分成多条计费。
例如:短信长度为160个字,将会被分隔成67字、67字、26字三条进行计费。
国外的短信
短信长度(字数)=短信模版内容字数+签名字数。
纯英文的 -> 短信长度不超过140字时,按照1条短信计费。超过140字时为长短信,按134字/条分隔成多条计费
非纯英文的 -> 短信长度不超过70个字,按照一条短信计费;超过70个字,即为长短信,按照67字/条拆分成多条计费。
3:欠费扣费和服务限制
账单出账时间通常在当前计费周期结束后4小时内。系统会自动从您账户余额中扣除账单金额,账户余额不足时,转为欠费状态。当账号余额不足时,系统会给账号的注册手机发送短信通知。
当账户余额不足以支付账单金额,短信服务处于欠费状态时,阿里云将暂停为您提供服务,不允许发送短信和使用资源包。建议您在欠费后及时补足欠费,以免服务停止,对您的业务造成损失。当您充值并补足欠费后,服务会自动开启,可以继续使用。
欠费停服后,请于7天内及时充值补足欠费,服务会自动恢复。欠费超过7天,将视为您主动放弃服务,数据会被清理且不可恢复。
| 限制项目 | 限制说明 |
|---|---|
| 短信验证码 | 使用同一个签名,默认情况下对同一个手机号码发送短信验证码 1条/分钟,5条/小时,10条/天 可以在控制台系统设置>国内消息设置中修改发送频率 一个手机号码通过阿里云短信服务平台只能收到40条/天 |
| 短信通知 | 使用同一个签名和同一个短信模版ID,对同一个手机号码发送短信通知,最多支持50条/日。 |
| 推广短信 | 使用同一个签名和同一个短信模版ID,对同一个手机号码发送推广短信,最多支持50条/日。 |
4:获取AccessKey
4.1:账号注册、实名和充值
我们需要使用阿里云提供的SMS(短信服务),因此首先我们需要注册一个账号
如果不想注册,也可以使用淘宝、支付宝账号登录。
-
注册地址:https://account.aliyun.com/register/register.htm
-
登录地址:https://account.aliyun.com/login/login.htm
在使用阿里云提供的各项服务之前,我们需要实名认证。
第一步:进入控制台
第二步:在右上角找到用户头像,把鼠标放上去,会弹出一个下拉菜单,里边就有实名认证选项

我们为了学习发送短信,不至于要去买很贵的短信包,没有必要,我们采用按量付费,也就是发送一条花一条短信的钱,这样,我们的学习成本就大大降低了,为了保证短信能够发送成功,请往自己的账户充值一些金额,多少都可以,建议1元就行了。
第一步:进入控制台
第二步:在搜索框旁边找到费用,把鼠标放上去,会弹出一个下拉菜单,里边就有充值选项

4.2:获取AccessKey
访问密钥AccessKey(AK)相当于登录密码,只是使用场景不同。
AccessKey用于程序方式调用云服务API,而登录密码用于登录控制台。
如果您不需要调用API,那么就不需要创建AccessKey。
-
使用云账号登录RAM控制台。
-
在左侧导航栏的人员管理菜单下,单击用户。
-
在用户登录名称/显示名称列表下,创建一个测试用户。
-
第一次登录肯定没有用户,请自行创建一个用户。创建时请勾选上“编程访问”。

⚠️ AccessKey Secret只在创建时显示,不提供查询,请妥善保管。
⚠️ 如果AccessKey泄露或丢失,则需要创建新的AccessKey,最多可以创建2个AccessKey
用户是创建好了,可以创建多个用户,这样方便给不同的人使用,但是现在创建的账户没有任何权限,我们需要给这个账户赋予使用”短信服务“的权限。




二:SMS发送
1:创建短信签名
注意现在自定义签名和自定义模板都要求比较严格,要各种审批,如果你是个人学习大概率是不会通过的
所以需要和阿里云的人工客服进行沟通

短信签名就类似于那个短信的标题,可以自己创建,打开短信控制台,在左侧导航栏找到国内消息。
进入到签名管理中:


如果成功申请了,就完事了,如果没有成功的话,需要手动填写提交工单并联系客服
1️⃣ 打开阿里云控制台,在搜索框的右侧找到“工单”,把鼠标放上去,会弹出一个小框,点击第一个“提交工单”

2️⃣ 在输入框输入“人工”,发送两次,才会弹出“联系人工”这个按钮

3️⃣ 在弹出的对话框中输入“短信服务”进行搜索,然后点击审核问题”,然后确定


4️⃣ 最后就是按照如下话术填写工单,处理时间长短听天由命
- 重要的优先级
- 不使用急速工单
- 问题描述:这边是个人业务,没有任何公司营业执照,需要测试使用,短信签名审核一直不通过
- 重要原因:着急

5️⃣ 可以联系人工打电话沟通

2:创建短信模板
短信模板就短信的正文内容
自定义创建打开短信控制台,在左侧导航栏找到国内消息。找到“模板管理”,然后点击创建即可。


申请流程一样,详见上面的短信签名
3:编码发送短信
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.3</version>
</dependency>
package com.example.mylogin;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.messaging.MessagingException;
import javax.annotation.Resource;
import javax.mail.internet.MimeMessage;
import java.io.File;
@SpringBootTest
class MyloginApplicationTests {
/**
* 短信发送
*/
@Test
public void sendSms() {
/*
* 初始化阿里云短信服务客户端
* regionId:cn-hangzhou
* accessKeyId:之前申请过
* accessSecret:之前申请过
*/
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "<accessKeyId>", "<accessSecret>");
IAcsClient client = new DefaultAcsClient(profile);
// 定义短信接收者的电话号码
String phoneNumbers = "15633029014";
// 定义短信签名名称
String signName = "果然新鲜";
// 定义短信模板代码
String templateCode = "SMS_174989915";
// 定义短信模板参数
String templateParam = "{'code':123456}";
// 创建并发送短信请求
CommonRequest request = getCommonRequest(phoneNumbers, signName, templateCode, templateParam);
try {
// 获取短信发送响应
CommonResponse response = client.getCommonResponse(request);
// 打印响应数据
System.out.println(response.getData());
} catch (ClientException e) {
// 打印异常信息
e.printStackTrace();
}
}
/**
* 获取阿里云短信发送的参数
* @param phoneNumbers 接收短信的电话号码
* @param signName 短信签名
* @param templateCode 短信模板
* @param templateParam 短信模板参数
* @return CommonRequest
*/
private static CommonRequest getCommonRequest(String phoneNumbers, String signName, String templateCode, String templateParam) {
CommonRequest request = new CommonRequest();
request.setSysMethod(MethodType.POST);//请求方式,无需改变
request.setSysDomain("dysmsapi.aliyuncs.com");//请求地址,无需改变
request.setSysVersion("2017-05-25");//请求版本,无需改变
request.setSysAction("SendSms");//请求动作,可以改变
request.putQueryParameter("PhoneNumbers", phoneNumbers);//接收短信的电话号码
request.putQueryParameter("SignName", signName);//发送短信的短信签名
request.putQueryParameter("TemplateCode", templateCode);//发送短信的短信模板
request.putQueryParameter("TemplateParam", templateParam);//发送短信的模板参数(也就是验证码)
return request;
}
}
分页查询和指定查询
@Test
public void QuerySendDetails() {
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "<accessKeyId>", "<accessSecret>");
IAcsClient client = new DefaultAcsClient(profile);
CommonRequest request = new CommonRequest();
request.setSysMethod(MethodType.POST);//请求方式,无需改变
request.setSysDomain("dysmsapi.aliyuncs.com");//请求地址,无需改变
request.setSysVersion("2017-05-25");//请求版本,无需改变
request.setSysAction("QuerySendDetails");//请求动作,可以改变
request.putQueryParameter("PhoneNumber", "15633029014");//要查询的电话号码
request.putQueryParameter("SendDate", "20210114");//要查询的发送日期
request.putQueryParameter("PageSize", "20");//要查询的记录条数
request.putQueryParameter("CurrentPage", "1");//要查询的当前页数
try {
CommonResponse response = client.getCommonResponse(request);
System.out.println(response.getData());
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace();
}
}
@Test
public void QuerySendDetailsByBizId() {
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "<accessKeyId>", "<accessSecret>");
IAcsClient client = new DefaultAcsClient(profile);
CommonRequest request = new CommonRequest();
request.setSysMethod(MethodType.POST);//请求方式,无需改变
request.setSysDomain("dysmsapi.aliyuncs.com");//请求地址,无需改变
request.setSysVersion("2017-05-25");//请求版本,无需改变
request.setSysAction("QuerySendDetails");//请求动作,可以改变
request.putQueryParameter("PhoneNumber", "15633029014");//要查询的电话号码
request.putQueryParameter("SendDate", "20210114");//要查询的发送日期
request.putQueryParameter("PageSize", "20");//要查询的记录条数
request.putQueryParameter("CurrentPage", "1");//要查询的当前页数
request.putQueryParameter("BizId", "502813610623272119");//要查询的BizId
try {
CommonResponse response = client.getCommonResponse(request);
System.out.println(response.getData());
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace();
}
}

被折叠的 条评论
为什么被折叠?



