阿里云短信服务调用详解

最近项目需求使用了阿里云的短信服务给用户发送验证,写此文章记录学习。

接口申请:

步骤 1 创建阿里云账号

为了访问短信服务,您需要有一个阿里云账号。如果没有,可首先按照如下步骤创建阿里云账号:

  1. 访问阿里云 官方网站,单击页面上的 免费注册 按钮。
  2. 按照屏幕提示完成注册流程并进行实名认证,短信服务只支持实名认证用户使用。为了更好地使用阿里云服务,建议尽快完成实名认证,否则部分阿里云服务将无法使用。具体实名认证流程,请参考 这里
步骤 2 获取阿里云访问密钥

为了使用短信发送API-JAVA SDK,您必须申请阿里云的访问密钥。

阿里云访问秘钥是阿里云为用户使用 API(非控制台)来访问其云资源设计的“安全口令”。您可以用它来签名 API 请求内容以通过服务端的安全验证。

该访问秘钥成对(AccessKeyId 与 AccessKeySecret)生成和使用。每个阿里云用户可以创建多对访问秘钥,且可随时启用(Active)、禁用(Inactive)或者删除已经生成的访问秘钥对。

您可以通过阿里云控制台的 秘钥管理页面 创建、管理所有的访问秘钥对,且保证它处于“启用”状态。由于访问秘钥是阿里云对 API 请求进行安全验证的关键因子,请妥善保管你的访问秘钥。如果某些秘钥对出现泄漏风险,建议及时删除该秘钥对并生成新的替代秘钥对。

步骤 3 在控制台完成模板与签名的申请,获得调用接口必备的参数

短信签名

根据用户属性来创建符合自身属性的签名信息。企业用户需要上传相关企业资质证明,个人用户需要上传证明个人身份的证明。

注意:短信签名需要审核通过后才可以使用。

短信模板

短信模板,即具体发送的短信内容。

短信模板可以支持验证码、短信通知、推广短信三种模式。验证码和短信通知,通过变量替换实现个性短信定制。推广短信不支持在模板中添加变量。

短信模板需要审核通过后才可以使用。

为了成功发送短信通知,您至少需要完成以下步骤

一、在控制台完成短信签名与短信模板的申请,获得调用接口必备的参数

在“短信签名”页面完成签名的申请,获得短信签名的字符串 签名申请手册

在“短信模板”页面完成模板的申请,获得模板ID。模板申请手册

 

 

开通阿里云短信服务链接:https://www.aliyun.com/product/sms?spm=5176.doc55324.765261.224.SSoWpM

使用阿里云的短信服务,需要注册登录自己的阿里云控制台,然后进入AccessKeys的处理界面

短信验证获取 AccessKey ID和AccessKey

短信服务文档

 https://help.aliyun.com/product/44282.html?spm=a2c4g.11186623.3.1.60861a81MfZAoZ

 

技术对接步骤
1:下载SDK工具包:SDK工具包中一共包含了2个类库,一个aliyun-java-sdk-core包,另外一个是alicom-dysms-api包
<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-core</artifactId>
    <version>4.0.6</version> <!-- 注:如提示报错,先升级基础包版,无法解决可联系技术支持 -->
</dependency>
<dependency>
  <groupId>com.aliyun</groupId>
  <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
  <version>1.1.0</version>
</dependency>

 

2: 编写样例程序

发送短信接口(SendSms)

//设置超时时间-可自行调整
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//初始化ascClient需要的几个参数
final String product = "Dysmsapi";//短信API产品名称(短信产品名固定,无需修改)
final String domain = "dysmsapi.aliyuncs.com";//短信API产品域名(接口地址固定,无需修改)
//替换成你的AK
final String accessKeyId = "yourAccessKeyId";//你的accessKeyId,参考本文档步骤2
final String accessKeySecret = "yourAccessKeySecret";//你的accessKeySecret,参考本文档步骤2
//初始化ascClient,暂时不支持多region(请勿修改)
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId,accessKeySecret);
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
IAcsClient acsClient = new DefaultAcsClient(profile);
 //组装请求对象
 SendSmsRequest request = new SendSmsRequest();
 //使用post提交
 request.setMethod(MethodType.POST);
 //必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式;发送国际/港澳台消息时,接收号码格式为国际区号+号码,如“85200000000”
 request.setPhoneNumbers("1500000000");
 //必填:短信签名-可在短信控制台中找到
 request.setSignName("云通信");
 //必填:短信模板-可在短信控制台中找到,发送国际/港澳台消息时,请使用国际/港澳台短信模版
 request.setTemplateCode("SMS_1000000");
 //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
 //友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
 request.setTemplateParam("{\"name\":\"Tom\", \"code\":\"123\"}");
 //可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
 //request.setSmsUpExtendCode("90997");
 //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
 request.setOutId("yourOutId");
//请求失败这里会抛ClientException异常
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
if(sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
//请求成功
}
参数
入参列表
参数名称参数类型必填与否样例取值参数说明
PhoneNumbersString必须15000000000短信接收号码,支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式;发送国际/港澳台消息时,接收号码格式为:国际区号+号码,如“85200000000”
SignNameString必须云通信短信签名
TemplateCodeString必须SMS_0000短信模板ID,发送国际/港澳台消息时,请使用国际/港澳台短信模版
TemplateParamString可选{“code”:”1234”,”product”:”ytx”}短信模板变量替换JSON串,友情提示:如果JSON中需要带换行符,请参照标准的JSON协议。
SmsUpExtendCodeString可选90999上行短信扩展码,无特殊需要此字段的用户请忽略此字段
OutIdString可选abcdefgh外部流水扩展字段
出参列表
出参名称出参类型样例取值参数说明
RequestIdString8906582E-6722请求ID
CodeStringOK状态码-返回OK代表请求成功,其他错误码详见错误码列表
MessageString请求成功状态码的描述
BizIdString134523^4351232发送回执ID,可根据该ID查询具体的发送状态

 

短信接口调用错误码:https://help.aliyun.com/knowledge_detail/57717.html?spm=a2c4g.11186623.2.20.37103144DVn56z

短信发送记录查询接口(QuerySendDetails)

用于查询短信发送的状态,是否成功到达终端用户手机

 //设置超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");
        //云通信产品-短信API服务产品名称(短信产品名固定,无需修改)
        final String product = "Dysmsapi";
        //云通信产品-短信API服务产品域名(接口地址固定,无需修改)
        final String domain = "dysmsapi.aliyuncs.com";
        //此处需要替换成开发者自己的AK信息
        final String accessKeyId = "yourAccessKeyId";
        final String accessKeySecret = "yourAccessKeySecret";
        //初始化ascClient
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
        IAcsClient acsClient = new DefaultAcsClient(profile);
        //组装请求对象
        QuerySendDetailsRequest request = new QuerySendDetailsRequest();
        //必填-号码
        request.setPhoneNumber("150000000");
        //可选-调用发送短信接口时返回的BizId
        request.setBizId("1234567^8901234");
        //必填-短信发送的日期 支持30天内记录查询(可查其中一天的发送数据),格式yyyyMMdd
        request.setSendDate("20170513");
        //必填-页大小
        request.setPageSize(10L);
        //必填-当前页码从1开始计数
        request.setCurrentPage(1L);
        //hint 此处可能会抛出异常,注意catch
        QuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request);
        //获取返回结果
       if(querySendDetailsResponse.getCode() != null && querySendDetailsResponse.getCode().equals("OK")){
        //代表请求成功
      }

 

 

入参列表
参数名称参数类型必填与否样例取值参数说明
PhoneNumberString必须15000000000短信接收号码,如果需要查询国际短信,号码前需要带上对应国家的区号,区号的获取详见国际短信支持国家信息查询API接口
BizIdString可选1234^1234发送流水号,从调用发送接口返回值中获取
SendDateString必须20170525短信发送日期格式yyyyMMdd,支持最近30天记录查询
PageSizeNumber必须10页大小Max=50
CurrentPageNumber必须1当前页码
出参列表
出参名称出参类型样例取值参数说明
RequestIdString8906582E-6722请求ID
CodeStringOK状态码-返回OK代表请求成功,其他错误码详见错误码列表
MessageString请求成功状态码的描述
TotalCountNumber100发送总条数
smsSendDetailDTOsObject-发送明细结构体,详见Demo样例
Demo样例
出参名称出参类型样例取值参数说明
phoneNumString13000000000手机号码
sendStatusNumber1发送状态 1:等待回执,2:发送失败,3:发送成功
errCodeStringDELIVERED运营商短信错误码
templateCodeStringSMS_000模板ID
contentString【阿里云】你好!短信内容
sendDateObject2017-05-25 00:00:00发送时间
receiveDateString2017-05-25 00:00:00接收时间
outIdString123外部流水扩展字段

 

发送批量短信接口(SendBatchSms)

//设置超时时间-可自行调整
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//初始化ascClient需要的几个参数
final String product = "Dysmsapi";//短信API产品名称(短信产品名固定,无需修改)
final String domain = "dysmsapi.aliyuncs.com";//短信API产品域名(接口地址固定,无需修改)
//替换成你的AK
final String accessKeyId = "yourAccessKeyId";//你的accessKeyId,参考本文档步骤2
final String accessKeySecret = "yourAccessKeySecret";//你的accessKeySecret,参考本文档步骤2
//初始化ascClient,暂时不支持多region(请勿修改)
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId,
accessKeySecret);
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
IAcsClient acsClient = new DefaultAcsClient(profile);
 //组装请求对象
 SendBatchSmsRequest request = new SendBatchSmsRequest();
 //使用post提交
 request.setMethod(MethodType.POST);
 //必填:待发送手机号。支持JSON格式的批量调用,批量上限为100个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
 request.setPhoneNumberJson("[\"1500000000\",\"1500000001\"]");
 //必填:短信签名-支持不同的号码发送不同的短信签名
 request.setSignNameJson("[\"云通信\",\"云通信\"]");
 //必填:短信模板-可在短信控制台中找到
 request.setTemplateCode("SMS_1000000");
 //必填:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
 //友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
 request.setTemplateParamJson("[{\"name\":\"Tom\", \"code\":\"123\"},{\"name\":\"Jack\", \"code\":\"456\"}]");
 //可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
 //request.setSmsUpExtendCodeJson("[\"90997\",\"90998\"]");
//请求失败这里会抛ClientException异常
SendBatchSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
if(sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
//请求成功
}

 

 

参数
入参列表
参数名称参数类型必填与否样例取值参数说明
PhoneNumberJsonString必须[“15000000000”,”15000000001”]短信接收号码,JSON格式,批量上限为100个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
SignNameJsonString必须[“云通信”,”云通信”]短信签名,JSON格式
TemplateCodeString必须SMS_0000短信模板ID
TemplateParamJsonString必须[{“code”:”1234”,”product”:”ytx1”},{“code”:”5678”,”product”:”ytx2”}]短信模板变量替换JSON串,友情提示:如果JSON中需要带换行符,请参照标准的JSON协议。
SmsUpExtendCodeJsonString可选[“90999”,”90998”]上行短信扩展码,JSON格式,无特殊需要此字段的用户请忽略此字段
出参列表
出参名称出参类型样例取值参数说明
RequestIdString8906582E-6722请求ID
CodeStringOK状态码-返回OK代表请求成功,其他错误码详见错误码列表
MessageString请求成功状态码的描述
BizIdString134523^4351232发送回执ID,可根据该ID查询具体的发送状态

短信消息API

当您使用短信的API接口发送短信后,可以通过使用MNS的Queue模型来接收短信的回执消息,假如服务出现异常情况时(如网络问题),导致消息回执未成功获取,还可以通过短信发送记录查询API接口进行一定的补偿(目前支持30天内发送记录的查询,可查询一天的发送数据)。

消息的订阅

  • 云通信的所有业务消息都通过MNS消息服务向外发送。用户每订阅一个类别的消息(比如上行短信消息SmsUp),系统都会为用户分配一个独立的消息队列。
  • 用户可以通过阿里云账号拿到一个临时的token用于获取队列中的消息。用户可以下载demo,编写简单的消息处理类即可完成消息处理的任务。
  • 在页面上订阅消息,订阅完消息后,能拿到消息队列名称(queueName)。比如:Alicom-Queue-xxxxxx-SmsReport 。队列名字每个用户都不同。

路径:短信产品进入控制台→应用开发→接口调用→云通信消息接收→短信状态报告接收→向右滑动(MNS消息队列消费模式。接收消息队列信息,请下载消息服务SDK进行程序编写,详见API文档)

消息类型

短信提供2种消息类型SmsReport(短信回执报告消息) 和 SmsUp(上行短信消息)

  • 通过订阅SmsReport短信状态报告,可以获知每条短信的发送情况,了解短信是否达到终端用户的状态与相关信息
  • 通过订阅SmsUp上行短信消息,可以获知终端用户回复短信的内容
  • 短信回执消息SmsReport消息体格式
    名称类型描述示例
    phone_numberString短信接收号码13000000000
    successBoolean发送是否成功true
    biz_idString发送回执ID1234^345
    out_idString调用发送短信接口时传的outId123456
    send_timeString转发给运营商的时间2017-06-01 10:00:00
    report_timeString收到运营商回执的时间2017-06-01 10:00:05
    err_codeString错误码UNKNOW
    err_msgString错误信息未知异常
    sms_sizeString140字节算一条短信,短信长度超过140字节时会拆分成多条短信发送1,2,3
    上行短信消息SmsUp
    名称类型描述示例
    phone_numberString短信接收号码13000000000
    contentString短信内容true
    sign_nameString短信签名【阿里云】
    send_timeString时间2017-06-01 10:00:00
    dest_codeString扩展码123456
    sequence_idDouble消息序列ID123456
/**
 * 只能用于接收云通信的消息,不能用于接收其他业务的消息
 */
public class ReceiveAlicomMsgDemo {
    private static Log logger=LogFactory.getLog(ReceiveAlicomMsgDemo.class);
    //以短信回执消息处理为例
    static class MyMessageListener implements MessageListener{
        private Gson gson=new Gson();
        @Override
        public boolean dealMessage(Message message) {
            System.out.println("message handle: " + message.getReceiptHandle());
            System.out.println("message body: " + message.getMessageBodyAsString());
            System.out.println("message id: " + message.getMessageId());
            System.out.println("message dequeue count:" + message.getDequeueCount());
            //以短信回执消息处理为例
            try{
                Map<String,Object> contentMap=gson.fromJson(message.getMessageBodyAsString(), HashMap.class);
                String phoneNumber=(String)contentMap.get("phone_number");
                Boolean success=(Boolean)contentMap.get("success");
                String bizId=(String)contentMap.get("biz_id");
                String outId=(String)contentMap.get("out_id");
                String sendTime=(String)contentMap.get("send_time");
                String reportTime=(String)contentMap.get("report_time");
                String errCode=(String)contentMap.get("err_code");
                String errMsg=(String)contentMap.get("err_msg");
                //TODO 这里开始写业务代码
            }catch(com.google.gson.JsonSyntaxException e){
               logger.error("error_json_format:"+message.getMessageBodyAsString(),e);
            }
            Boolean dealResult=true;
            return dealResult;//返回true,则工具类自动删除已拉取的消息。
        }
    }
    public static void main(String[] args) throws com.aliyuncs.exceptions.ClientException, ParseException {
        DefaultAlicomMessagePuller puller=new DefaultAlicomMessagePuller();
        String accessKeyId="yourAccessKeyId";
        String accessKeySecret="yourAccessKeySecret";
        String messageType="SmsReport";//短信回执:SmsReport,短信上行:SmsUp
        String queueName="yourQueueName";//在云通信页面开通相应业务消息后,就能在页面上获得对应的queueName
        puller.startReceiveMsg(accessKeyId,accessKeySecret ,messageType,queueName , new MyMessageListener());
    }
}

 

转载于:https://www.cnblogs.com/qq99514925/p/10688710.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值