0%

使用阿里云短信服务API实现短信验证码以及短信服务通知

前言

初学者刚刚接触API的使用会遇到很多坑,自己就是如此,近期参与一个项目开发,负责的其中一项即为短信服务接口,在其中也碰到了许多问题,于是想就想写这篇文章一共分享所得。

新手上路,错误与不足之处,还望大家海涵。

一 .短信调用简要说明

短信服务(Short Message Service)是阿里云为用户提供的一种通信服务的能力。

支持向国内和国际快速发送验证码、短信通知和推广短信,服务范围覆盖全球200多个国家和地区。国内短信支持三网合一专属通道,与工信部携号转网平台实时互联。电信级运维保障,实时监控自动切换,到达率高达99%。完美支撑双11期间20亿短信发送,6亿用户触达。

使用其短信服务要先申请access key短信签名短信模板,审核时间一般一到两个工作日就可以了。

然后确保账户有余额,一条通知短信0.0045元。

随后就可以调用API接口了,代码demo很容易理解,导入依赖或是下载对应编程语言的短信open-api-SDK到本地导入就完成准备工作。

阿里云需要申请规范
然后就是测试了,导入以上的签名模板等进入demo代码就可以了。

二 .官方不带签名原生态测试demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//阿里云SMS短信服务demo
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;
/*
pom.xml
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.0.3</version>
</dependency>
*/
public class CommonRpc {
public static void main(String[] args) {
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "<accessKeyId>", "<accessSecret>");
IAcsClient client = new DefaultAcsClient(profile);

CommonRequest request = new CommonRequest();
//request.setProtocol(ProtocolType.HTTPS);
request.setMethod(MethodType.POST);
request.setDomain("dysmsapi.aliyuncs.com");
request.setVersion("2017-05-25");
request.setAction("SendSms");
request.putQueryParameter("RegionId", "cn-hangzhou");
request.putQueryParameter("PhoneNumbers", "13027145080");
try {
CommonResponse response = client.getCommonResponse(request);
System.out.println(response.getData());
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace();
}
}
}

调用结果如下

在这里插入图片描述


三 .以上为不带模板和签名的API调用结果 下面加入签名和模板


带有签名和模板的demo

相应区块已进行注释说明,只需要替换签名,模板,以及变量的参数值就可以使用了。变量类型需要自己在申请时自定义,以下展示为个人模板,具体情况请参照模板解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package com.whuseat.notify_server.south.mess_service;

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;

/**
* 阿里云短信API调用类
*
* @author GanAH on 2019/3/30.
* @version 1.0
*/
public class HttpSendSms
{
public void StartSendSms()
{
/**
* 调用短信API请求
*
* access key
* regionId:短信服务区域.
* accessKeyId:阿里云短信服务access keyId.
* secret:access key密钥.
*/
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou",
"LTAIAbjCxxxxxxW", "B4pWsaQfjzvVxxxxxxxxOF9");
IAcsClient client = new DefaultAcsClient(profile);
/**
* 传入参数,调用SDK
*/
CommonRequest request = new CommonRequest();
//request.setProtocol(ProtocolType.HTTPS);
request.setMethod(MethodType.POST);
request.setDomain("dysmsapi.aliyuncs.com");
request.setVersion("2019-03-30");
request.setAction("SendSms");
/**
* 短信通知用户
*/
request.putQueryParameter("PhoneNumbers", "130xxxxx");
/**
* 短信签名
*/
request.putQueryParameter("SignName", "XXXX");
/**
* 短信通知模板
*/
request.putQueryParameter("TemplateCode", "SMS_16xxxxx");
/**
* 模板变量名
*
* 用户姓名name,时段time,数值code
*/
request.putQueryParameter("TemplateParam", "{\"name\":\"GanAH\",\"time\":\"2019\",\"code\":\"20\"}");
try
{
CommonResponse response = client.getCommonResponse(request);
System.out.println(response.getData());
}
catch (ServerException e)
{
e.printStackTrace();
}
catch (ClientException e)
{
e.printStackTrace();
}
}

public static void main(String[] args)
{
try
{

HttpSendSms Test1 = new HttpSendSms();
Test1.StartSendSms();
QuerySendDetails Test2 = new QuerySendDetails();
SendBatchSms Test3 = new SendBatchSms();
Test2.ShowQuerySendDetails();
Test3.StartSendBatchSms();

}catch (Exception e)
{
e.printStackTrace();
}

}
}

调用结果及说明

在这里插入图片描述

  • 以上为我加入签名和模板,调整好变量后的调用结果,其中的短信:”签名场景非法”是由于我所用的示例短信签名和示例短信通知模板不对应所致,demo本身无问题。
  • 使用不匹配的示例是为了说明下面的问题:
    Code一栏为错误返回值,其说明了你的API调用错误类型,具体修改方法官方有指导,为了方便我已列出如下面所示。
  • 特别说明:加入测试的变量编辑方式如下图(最后一栏):
    在这里插入图片描述

    四 .常见的调试结果错误返回值

    调用API接口会产生接口调用错误码,常见接口调用错误码显示及修改建议如下。
    错误码Code —— 错误提示Message —— 原因及建议处理方式
    (一) isp.RAM_PERMISSION_DENY RAM权限DENY 当提示RAM权限不足时,就需要给当前使用的AK对应子账号进行授权:AliyunDysmsFullAccess(权限名称)。具体权限授权详见:https://help.aliyun.com/document_detail/55764.html?spm=5176.product44282.6.548.bKZJL2
    (二) isv.OUT_OF_SERVICE 业务停机 请先查看账户余额,若余额大于零,则请通过创建工单联系工程师处理
    (三) isv.PRODUCT_UN_SUBSCRIPT 未开通云通信产品的阿里云客户 未开通云通信产品的阿里云客户(该AK所属的账号尚未开通云通信的服务,包括短信、语音、流量等服务)注:阿里云短信服务包含:1、消息服务 2、云通信短信服务 3、云市场短信接口,账号和短信接口不可混用。当出现此类提示报错需要检查当前AK是否已经开通阿里云云通信短信服务,如已开通消息服务,则参照消息服务文档调用接口。
    (四) isv.PRODUCT_UNSUBSCRIBE 产品未开通 产品未订购(该AK所属的账号尚未开通当前接口的产品,如仅开通了短信服务的用户调用语音接口。),检查AK对应账号是否已开通调用接口对应的服务。短信服务开通链接:https://www.aliyun.com/product/sms
    (五) isv.ACCOUNT_NOT_EXISTS 账户不存在 请确认使用的账号是否与申请的账号一致
    (六) isv.ACCOUNT_ABNORMAL 账户异常 请确认使用的账号是否与申请的账号一致
    (七) isv.SMS_TEMPLATE_ILLEGAL 短信模版不合法 TemplateCode参数请传入审核通过的模版ID,模版见:见:https://dysms.console.aliyun.com/dysms.htm#/template
    (八) isv.SMS_SIGNATURE_ILLEGAL 短信签名不合法 SignName请传入审核通过的签名内容,签名见:https://dysms.console.aliyun.com/dysms.htm#/sign
    (九) isv.INVALID_PARAMETERS 参数异常 对照文档,检查参数格式。例:短信查询接口SendDate日期格式yyyyMMdd,错误:2017-01-01正确:20170101
    (十) isp.SYSTEM_ERROR isp.SYSTEM_ERROR 请重试接口调用,如仍存在此情况请创建工单反馈工程师查看
    (十一) isv.MOBILE_NUMBER_ILLEGAL 非法手机号 PhoneNumbers参数请传入11位国内号段的手机号码
    (十二) isv.MOBILE_COUNT_OVER_LIMIT 手机号码数量超过限制 短信接收号码,支持以英文逗号分隔的形式进行批量调用,批量上限为1000个手机号码,PhoneNumbers参数单次调用不传入过多接收号码
    (十三) isv.TEMPLATE_MISSING_PARAMETERS 模版缺少变量 TemplateParam中需要以json格式字符串给使用的模版中出现的所有变量进行赋值。例:模版为:您好${name},验证码${code} TemplateParam={“name”:”Tom”,”code”:”123”}
    (十四) isv.BUSINESS_LIMIT_CONTROL 业务限流 将短信发送频率限制在正常的业务流控范围内,默认流控:短信验证码 :使用同一个签名,对同一个手机号码发送短信验证码,支持1条/分钟,5条/小时 ,累计10条/天。
    (十五) isv.INVALID_JSON_PARAM JSON参数不合法,只接受字符串值 TemplateParam入参以Json格式字符串形式传入。例:正确{“code”:”123”}
    (十六) isv.BLACK_KEY_CONTROL_LIMIT 黑名单管控 黑名单管控是指变量内容含有限制发送的内容,变量不支持透传url,同时检查通过变量是否透传了一些敏感信息触发关键字
    (十七) isv.PARAM_LENGTH_LIMIT 参数超出长度限制 单个变量长度限制在20字符内。
    (十八) isv.PARAM_NOT_SUPPORT_URL 不支持URL 变量不支持透传url,同时检查通过变量是否透传了一些敏感信息触发关键字
    (十九) isv.AMOUNT_NOT_ENOUGH 账户余额不足 转入金额不足以发送当前信息,确保余额足够发送当前短信
    (二十) isv.TEMPLATE_PARAMS_ILLEGAL 模版变量里包含非法关键字 变量不支持透传url,同时检查通过变量是否透传了一些敏感信息触发关键字
    (二十一) SignatureDoesNotMatch Specified signature is not matched with our calculation. Signature加密错误,如为SDK调用,则需要注意accessKeyId和accessKeySecret字符串赋值正确无误;如自行加密的Signature,则需要检查加密逻辑,对照文档:https://help.aliyun.com/document_detail/56189.html
    (二十二) InvalidTimeStamp.Expired Specified time stamp or date value is expired. 时间戳错误,发出请求的时间和服务器接收到请求的时间不在15分钟内。经常出现该错误的原因是时区原因造成的,目前网关使用的时间是GMT时间
    (二十三) SignatureNonceUsed Specified signature nonce was used already. 唯一随机数重复,SignatureNonce为唯一随机数,用于防止网络重放攻击。不同请求间要使用不同的随机数值。
    (二十四) InvalidVersion Specified parameter Version is not valid. 版本号错误,需要确认接口的版本号,如云通信短信、语音、流量服务的Version=2017-05-25
    (二十五) InvalidAction.NotFound Specified api is not found, please check your url and method 接口名错误,需要确认接口地址和接口名,如云通信短信服务短信发送:dysmsapi.aliyuncs.com,接口名Action=SendSms

    联系方式

    微信公众号,更多成长分享

    在这里插入图片描述
-------------结束啦 我可是有底线的~ -------------

欢迎关注我的其它发布渠道