阿里短信服务API接入指南及示例

本文涉及的产品
短信服务,200条 3个月
短信服务,100条 3个月
数字短信套餐包(仅限零售电商行业),100条 12个月
简介: 阿里短信服务,用淘宝账号打通三大运营商通信能力,以开放API方式向开发者提供短信服务。阿里短信服务具备3秒可达、99%到达率和超低资费的优势,并完美支撑了双11“2亿用户,6亿短信,8万并发”的挑战。本文将介绍阿里短信服务API如何接入,并提供了多种编程语言的调用示例。

阿里短信服务,用淘宝账号打通三大运营商通信能力,以开放API方式向开发者提供短信服务。阿里短信服务具备3秒可达、99%到达率和超低资费的优势,并完美支撑了双11“2亿用户,6亿短信,8万并发”的挑战。本文将介绍阿里短信服务API的接入方法,并提供了多种编程语言的调用示例。

订购阿里短信服务

进入阿里云数据市场订购[阿里短信服务](
https://market.aliyun.com/products/57002003/cmapi011900.html?spm=5176.78296.419700.1.KshhBT)。阿里短信服务是后付费商品,0元即可订购,成功发送短信后再付费。资费详见商品详情页面。

阿里短信服务接入指南

订购阿里短信服务后,就可以设置短信签名和短信模板,然后可基于API Gateway SDK实现API调用。
注意:短信签名和模板是必须的,而且要通过审核后方可使用,不允许随意发送短信。

1. 设置短信签名和模板

进入云市场控制台,在短信服务中点击“设置”,进入短信签名和模板的设置页面。

设置短信签名

短信签名为验证码短信或者通知短信内容中【】内的名称,一般为公司或者产品名,如【阿里云】。
点击“签名”标签,点击“新建短信签名”,根据下方文字说明,新建签名。
screenshot

企业用户首先要确保阿里云账户通过企业实名认证,如果当前是个人账户,请先升级为企业实名认证

新建签名时,要上传 企业营业执照,组织机构代码证、税务登记证 三个证件的图片,如果是三证合一,则上传三张同样的图片即可。如果是要使用他人公司的名称,则要上传授权委托书、授权单位的组织机构代码证的图片。

签名提交后,要等待审核,一般在1个工作日内完成。审核通过的签名方能使用。签名审核通过后,请留意“签名名称”,在API调用的时候将会使用到这个参数。
个人用户最多可以创建1个自定义短信签名;企业用户最多可以创建5个自定义短信签名。

设置短信模板

短信模板就是短信正文的模板。
点击“模板”标签,点击“新建模板”,根据正文文字说明,新建模板。
screenshot
填写内容确定之后,点击“提交审核”。审核将在1个工作日内完成。同样,只有审核通过的模板才能使用。模板审核通过后,请留意“模板CODE”,在API调用的时候将会使用到这个参数。
模板最多可添加20个。

2. 调用短信服务API

API签名机制

为了保证安全,API请求需要有带上签名。API Gateway的签名机制比较复杂,一般用户可直接使用SDK和参考下一章节的调用示例直接调用短信服务API。如果你使用的编程语言,我们还没有提供SDK和示例,则需要你参考以下文档,自行实现签名。
API Gateway 请求签名机制说明

API调用所需参数

API调用的SDK及调用示例将在下一章节介绍。

1)API基础参数
API基础参数有Host、Path、请求方式、返回类型、请求参数、返回示例、错误码等等,可通过商品详情页查看。

2)AppCode或者AppKey&AppSecret
云市场控制台 获取AppCode或者AppKey&AppSecret。
screenshot

3)签名名称及模板CODE

进入云市场控制台 ,选择短信服务,点击“设置”进入短信服务控制台,可获取签名名称和模板CODE。
签名名称:
screenshot
模板CODE:
screenshot

4)模板变量

模板变量为新建模板的时你自定义的变量。这些变量的值可在调用API时进行设置。API参数中ParamString 即为模板变量,形式为JSON字符串。其中,数字必须转换为字符串。个人用户ParamString变量长度必须小于15个字符。

举例:
若短信模板为:“你好,你的验证码为:${no},不要告诉别人哦”,此时你如果将参数ParamString=‘{“no”:”123456”}’,用户收到的短信内容将为:【短信签名】你好,你的验证码为:123456,不要告诉别人哦。

提示:如果你的模板中没有变量,则ParamString={}

5)目标手机号
支持批量发送给多个手机号。参数名为RecNum ,多个手机号之间以英文逗号分割。

3. 查看账单及账户充值

短信服务API调用成功后,则会产出账单,进入云市场控制台 ,选择短信服务,点击“账单明细”可查看账单。
账单5分钟产出一次,账单产出后,会自己从你的云账户中扣费。若扣费失败,则会中止服务,请及时充值

阿里短信服务API SDK及调用示例

数据市场现已支持两种API调用方式,一种为APPCODE简单身份认证模式,另一种为AppKey&AppSecret签名认证模式。推荐使用APPCODE模式,简单易用。如果你对安全有更高要求,则可以继续采用AppKey&AppSecret签名认证模式。

APPCODE简单身份认证模式

APPCODE简单身份认证模式,用起来很简单,只需要在请求的Header中加入APPCODE即可,具体可直接参考详情页中给出的调用示例代码需要注意的事,URL中若有中文字符,需要进行URLEncode。示例代码举例如下:

SHELL(CURL)版本

curl -i --get --include 'http://sms.market.alicloudapi.com/singleSendSms?ParamString=%7B%22no%22%3A%22123456%22%7D&RecNum=RecNum&SignName=SignName&TemplateCode=TemplateCode'  -H 'Authorization:APPCODE 你自己的AppCode'

Python版本

import urllib, urllib2, sys


host = 'http://sms.market.alicloudapi.com'
path = '/singleSendSms'
method = 'GET'
appcode = '你自己的AppCode'
querys = 'ParamString=%7B%22no%22%3A%22123456%22%7D&RecNum=RecNum&SignName=SignName&TemplateCode=TemplateCode'
bodys = {}
url = host + path + '?' + querys

request = urllib2.Request(url)
request.add_header('Authorization', 'APPCODE ' + appcode)
response = urllib2.urlopen(request)
content = response.read()
if (content):
    print(content)

Java版本

Java版本依赖于Java SDK,请注意代码其中的注释说明,下载Java SDK后使用以下代码。

public static void main(String[] args) {
        String host = "http://sms.market.alicloudapi.com";
        String path = "/singleSendSms";
        String method = "GET";
        Map<String, String> headers = new HashMap<String, String>();
        headers.put("Authorization", "APPCODE 你自己的AppCode");
        Map<String, String> querys = new HashMap<String, String>();
        querys.put("ParamString", "%7B%22no%22%3A%22123456%22%7D");
        querys.put("RecNum", "RecNum");
        querys.put("SignName", "SignName");
        querys.put("TemplateCode", "TemplateCode");

        try {
            /**
            * 重要提示如下:
            * HttpUtils请从
            * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java
            * 下载
            *
            * 相应的依赖请参照
            * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
            */
            HttpResponse response = HttpUtils.doGet(host, path, method, headers, querys);
            System.out.println(response.toString());
            //获取response的body
            //System.out.println(EntityUtils.toString(response.getEntity()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

其他语言,如PHP、C#、Objective-C,请直接参考商品详情页中的描述。

AppKey&AppSecret签名认证模式

Java版本

1)下载API Gateway Java SDK
2)在 src/main/java/com/aliyun/api/gateway/demo 目录下新建代码文件SingleSendSms.java,复制如下代码(自行修改相关参数):

package com.aliyun.api.gateway.demo;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.api.gateway.demo.constant.Constants;
import com.aliyun.api.gateway.demo.constant.HttpSchema;
import com.aliyun.api.gateway.demo.enums.Method;
public class SingleSendSms {
    private final static String APP_KEY = "AppKey"; //AppKey从控制台获取
    private final static String APP_SECRET = "AppSecret"; //AppSecret从控制台获取
    private final static String SIGN_NAME = "签名名称"; // 签名名称从控制台获取,必须是审核通过的
    private final static String TEMPLATE_CODE = "模板CODE"; //模板CODE从控制台获取,必须是审核通过的
    private final static String HOST = "sms.market.alicloudapi.com"; //API域名从控制台获取
    
    private final static String ERRORKEY = "errorMessage";  //返回错误的key
    
    // @phoneNum: 目标手机号,多个手机号可以逗号分隔;
    // @params: 短信模板中的变量,数字必须转换为字符串,如短信模板中变量为${no}",则参数params的值为{"no":"123456"}
    public void sendMsg(String phoneNum, String params){
        String path = "/singleSendSms";
    
        Request request =  new Request(Method.GET, HttpSchema.HTTP + HOST, path, APP_KEY, APP_SECRET, Constants.DEFAULT_TIMEOUT);
        
        //请求的query
        Map<String, String> querys = new HashMap<String, String>();
        querys.put("SignName", SIGN_NAME);
        querys.put("TemplateCode", TEMPLATE_CODE);
        querys.put("RecNum", phoneNum);
        querys.put("ParamString", params);
        request.setQuerys(querys);
        
        try {
            Map<String, String> bodymap = new HashMap<String, String>();
            Response response = Client.execute(request);
            //根据实际业务需要,调整对response的处理
            if (null == response) {
                System.out.println("no response");
            } else if (200 != response.getStatusCode()) {
                System.out.println("StatusCode:" + response.getStatusCode());
                System.out.println("ErrorMessage:"+response.getErrorMessage());
                System.out.println("RequestId:"+response.getRequestId());
            } else {
                bodymap = ReadResponseBodyContent(response.getBody());
                 if (null != bodymap.get(ERRORKEY)) {
                    //当传入的参数不合法时,返回有错误说明
                    System.out.println(bodymap.get(ERRORKEY));
                } else {
                    //成功返回map,对应的key分别为:message、success等
                    System.out.println(JSON.toJSONString(bodymap));
                }
            }
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
    }
    
    private Map<String, String> ReadResponseBodyContent(String body) {
        Map<String, String> map = new HashMap<String, String>();     
        try {
            JSONObject jsonObject = JSON.parseObject(body);
            if (null != jsonObject) {                
                for(Entry<String, Object> entry : jsonObject.entrySet()){
                    map.put(entry.getKey(), entry.getValue().toString());
                }                
            }
            if ("false".equals(map.get("success"))) {
                map.put(ERRORKEY, map.get("message"));
            }
        } catch (Exception e) {
            map.put(ERRORKEY, body);
        }
        return map;
    }
    
    
    public  static void main(String agrs[]){
        SingleSendSms app = new SingleSendSms();
        app.sendMsg("18600000000,13800000000","{'name':'David'}");
    }
}

3)编译后执行SingleSendSms类即可发送短信。

Python版本

1) 下载API Gateway Python SDK
2) 修改 com/aliyun/api/gateway/sdk/ClientDemo.py 的代码为(自行替换相应的参数内容):

#!/usr/bin/env python
#encoding=utf-8

from com.aliyun.api.gateway.sdk import client
from com.aliyun.api.gateway.sdk.http import request
from com.aliyun.api.gateway.sdk.common import constant

host = "http://sms.market.alicloudapi.com"

url = "/singleSendSms" \
    + '?ParamString={"name":"XXXX"}' \
    + "&RecNum=18600000000,13500000000" \
    + "&SignName=签名名称" \
    + "&TemplateCode=模板CODE"

req = request.Request(host=host, url=url, method="GET", time_out=30000)
cli = client.DefaultClient(app_key="APP_KEY", app_secret="APP_SECRET")
print cli.execute(req)

3)执行 com/aliyun/api/gateway/sdk/ClientDemo.py 即可发送短信。

如果不想使用Python SDK,则可以使用如下更为精简的代码自行实现API签名和API调用:

#!/usr/bin/env python
#encoding=utf-8

import time
import base64
import hashlib
import httplib
import uuid
import hmac

class SMSClient:
    def __init__(self, app_key, app_secret):
        self.__app_key, self.__app_secret = app_key, app_secret

    def send(self, receiver, sign, template_code, parameters=''):
        print receiver, sign, template_code, parameters
        self.__host = 'sms.market.alicloudapi.com'
        self.__str_uri = '/singleSendSms?ParamString=%s&RecNum=%s&SignName=%s&TemplateCode=%s' % (parameters, receiver, sign, template_code)
        print self.__str_uri
        self.build_headers()
        self.__connection = httplib.HTTPConnection(self.__host, 80)
        self.__connection.connect()
        self.__connection.request('GET', self.__str_uri, headers=self.__headers)
        response = self.__connection.getresponse()
        print response.status, response.getheaders(), response.read()

    def build_headers(self):
        headers = dict()
        headers['X-Ca-Key'] = self.__app_key
        headers['X-Ca-Nonce'] = str(uuid.uuid4())
        headers['X-Ca-Timestamp'] = str(int(time.time() * 1000))
        headers['X-Ca-Signature-Headers'] = 'X-Ca-Key,X-Ca-Nonce,X-Ca-Timestamp'
        str_header = '\n'.join('%s:%s' % (k, headers[k]) for k in ['X-Ca-Key','X-Ca-Nonce','X-Ca-Timestamp'])
        str_to_sign = '%s\n\n\n\n\n%s\n%s' % ('GET', str_header, self.__str_uri)
        headers['X-Ca-Signature'] = self.__get_sign(str_to_sign, self.__app_secret)
        self.__headers = headers

    def __get_sign(self, source, secret):
        h = hmac.new(secret, source, hashlib.sha256)
        signature = base64.encodestring(h.digest()).strip()
        return signature

cli = SMSClient(app_key="APP_KEY", app_secret="APP_SECRET")
cli.send('18600000000,13500000000', '签名名称', '模板CODE', '{"name":"XXXX"}')

Shell版本

Shell版本的代码比较精简,替换相关参数后就可以直接使用。其他语言也可以通过调用Shell脚本发送短信。

#!/usr/bin/env bash

RECEIVER=136********      #接收方手机号
SIGN="签名名称"            #签名
TEMP_CODE="模板CODE"      #短信模板
PARAMS="{\"time\":\"`date +%Y%m%d%H%M%S`\"}" #模板参数(json格式)

K="2******6" #AppKey,从管理控制台获取,下同
S="0******************************7" #AppSecret

NL="
"
[ "x`uname`" = "xDarwin" ] && {
NONCE="`uuidgen`"
TIMESTAMP="`date +%s`500"
} || {
NONCE="`uuid`"
TIMESTAMP="`date +%s%3N`"
}
STR_HEADER="X-Ca-Key:$K${NL}X-Ca-Nonce:$NONCE${NL}X-Ca-Timestamp:$TIMESTAMP"
STR_URI="/singleSendSms?ParamString=$PARAMS&RecNum=$RECEIVER&SignName=$SIGN&TemplateCode=$TEMP_CODE"
STR_TO_SIGN="GET${NL}${NL}${NL}${NL}${NL}$STR_HEADER${NL}$STR_URI"
SIGN="`/bin/echo -n "$STR_TO_SIGN" | openssl dgst -sha256 -hmac "$S" | sed 's/.* //g' | xxd -r -p | base64`"
STR_URI="`echo "$STR_URI" | sed 's#{#\\\\{#g;s#}#\\\\}#g'`"
curl -v -H 'Accept:' \
    -H "X-Ca-Key: $K" \
    -H "X-Ca-Nonce: $NONCE" \
    -H "X-Ca-Timestamp: $TIMESTAMP" \
    -H "X-Ca-Signature-Headers: X-Ca-Key,X-Ca-Nonce,X-Ca-Timestamp" \
    -H "X-Ca-Signature: $SIGN" \
    "http://sms.market.alicloudapi.com$STR_URI"

C# 版本

1)下载API Gateway .NET SDK
2)新建一个工程,并依赖于.NET SDK,再新建一个SingleSendSms类,代码如下(自行修改相关参数):

using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Net;

namespace example
{
    using aliyun_api_gateway_sdk.Constant;
    using aliyun_api_gateway_sdk.Util;

    class SingleSendSms
    {
        private const String appKey = "************";
        private const String appSecret = "****************************";
        private const String host = "http://sms.market.alicloudapi.com";
        private const String path = "/singleSendSms";
        
        public static void Main(string[] args)
        {
            var headers = new Dictionary<string, string>();
            var querys = new Dictionary<string, string>();            
            var signHeader = new List<String>();

            //设定Content-Type,根据服务器端接受的值来设置
            headers.Add(HttpHeader.HTTP_HEADER_CONTENT_TYPE, ContentType.CONTENT_TYPE_TEXT);
            //设定Accept,根据服务器端接受的值来设置
            headers.Add(HttpHeader.HTTP_HEADER_ACCEPT, ContentType.CONTENT_TYPE_TEXT);

            //注意:业务query部分,如果没有则无此行;请不要、不要、不要做UrlEncode处理
            querys.Add("ParamString", "{'name':'XXXX'}");  // 模板变量
            querys.Add("RecNum", "18600000000,18600000000");  // 接收手机号,多个手机号以英文逗号分隔
            querys.Add("SignName", "签名名称"); // 短信签名名称
            querys.Add("TemplateCode", "模板CODE"); // 短信模板CODE

            using (HttpWebResponse response = HttpUtil.HttpGet(host, path, appKey, appSecret, 30000, headers, querys, signHeader)) {
                Console.WriteLine(response.StatusCode);
                Console.WriteLine(response.Method);
                Console.WriteLine(response.Headers);
                Stream st = response.GetResponseStream();
                var reader = new StreamReader(st, Encoding.GetEncoding("utf-8"));
                Console.WriteLine(reader.ReadToEnd());
                Console.WriteLine(Constants.LF);
            }            
            Console.Read();
        }
    }
}

3)执行SingleSendSms中的Main函数就可以发送短信。

PHP版本

PHP版本的代码比较精简,替换相关参数后就可以直接使用。

<?php
$app_key = "*********";
$app_secret = "*******************************";
$request_paras = array(
        'ParamString' => '{"name":"XXXX"}',
        'RecNum' => '18600000000,13500000000',
        'SignName' =>'签名名称', 
        'TemplateCode' => '模板CODE'
        );

$request_host = "http://sms.market.alicloudapi.com";
$request_uri = "/singleSendSms";
$request_method = "GET";
$info = "";
$content = do_get($app_key, $app_secret, $request_host, $request_uri, $request_method, $request_paras, $info);
print_r($content); // API返回值
# print_r($info);  // 系统请求返回信息

function do_get($app_key, $app_secret, $request_host, $request_uri, $request_method, $request_paras, &$info) {
    ksort($request_paras);
    $request_header_accept = "application/json;charset=utf-8";
    $content_type = "";
    $headers = array(
            'X-Ca-Key' => $app_key,
            'Accept' => $request_header_accept
            );
    ksort($headers);
    $header_str = "";
    $header_ignore_list = array('X-CA-SIGNATURE', 'X-CA-SIGNATURE-HEADERS', 'ACCEPT', 'CONTENT-MD5', 'CONTENT-TYPE', 'DATE');
    $sig_header = array();
    foreach($headers as $k => $v) {
        if(in_array(strtoupper($k), $header_ignore_list)) {
            continue;
        }
        $header_str .= $k . ':' . $v . "\n";
        array_push($sig_header, $k);
    }
    $url_str = $request_uri;
    $para_array = array();
    foreach($request_paras as $k => $v) {
        array_push($para_array, $k .'='. $v);
    }
    if(!empty($para_array)) {
        $url_str .= '?' . join('&', $para_array);
    }
    $content_md5 = "";
    $date = "";
    $sign_str = "";
    $sign_str .= $request_method ."\n";
    $sign_str .= $request_header_accept."\n";
    $sign_str .= $content_md5."\n";
    $sign_str .= "\n";
    $sign_str .= $date."\n";
    $sign_str .= $header_str;
    $sign_str .= $url_str;

    $sign = base64_encode(hash_hmac('sha256', $sign_str, $app_secret, true));
    $headers['X-Ca-Signature'] = $sign;
    $headers['X-Ca-Signature-Headers'] = join(',', $sig_header);
    $request_header = array();
    foreach($headers as $k => $v) {
        array_push($request_header, $k .': ' . $v);
    }

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $request_host . $url_str);
    //curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLINFO_HEADER_OUT, true);
    curl_setopt($ch, CURLOPT_VERBOSE, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $request_header);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $ret = curl_exec($ch);
    $info = curl_getinfo($ch);
    curl_close($ch);
    return $ret;
}

Object-C版本

1)新建一个Signature类,类的实现代码如下(请自行修改appKey和appSecret):

#import "Signature.h"
#import <CommonCrypto/CommonHMAC.h>

static NSString * const host   = @"http://sms.market.alicloudapi.com";  // HOST
static NSString * const appKey = @"********";  // app key,从云市场控制台获取,下同
static NSString * const appSecret = @"***************************************";  // app secret

@implementation Signature

/*! @brief send message
 @param receiver     接收者的手机号, 多个手机号码以英文逗号分隔   e.g: 13000000000
 @param sign         签名名称,       e.g: 数据市场
 @param templateCode 模板CODE       e.g: MSG_0000000
 @param paramters    模板参数,JSON字符串格式     e.g: {"name" : "Hello"}
 */
- (void)sendMsg:(NSString *)receiver :(NSString *)sign :(NSString *)templateCode :(NSString *)paramters {
    NSString *pathPamras   = [NSString stringWithFormat:@"/singleSendSms?ParamString=%@&RecNum=%@&SignName=%@&TemplateCode=%@", paramters, receiver, sign, templateCode];
    
    /*! @warn 因为请求中带有json数据,花括号不被nsurl接受,所以这里计算签名的时候不能转义,拼接到URL上之后才转义 */
    NSString *urlString    = [host stringByAppendingString:[pathPamras stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
    NSLog(@"url: %@", urlString);
    
    NSURL *url             = [NSURL URLWithString:urlString];
    NSString *contentType  = @"";
    NSString *accept       = @"";
    NSString *contentMd5   = @"";
    
    NSMutableURLRequest *request  = [NSMutableURLRequest requestWithURL:url];
    NSDictionary *header   = [self getHeader:pathPamras:@"GET":contentType:accept:contentMd5];
    [request setAllHTTPHeaderFields:header];

    NSURLSession *session  = [NSURLSession sharedSession];
    NSURLSessionDataTask *sessionTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSString *body     = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"result: %@", body);
    }];

    [sessionTask resume];
}

/*! @brief 获取header
    @param pathParams  请求url路径及其query参数
    @param method      请求方法名
    @param contentType header中的ContentType, 服务端会将此字段加入签名,某些http客户端会自动加上默认值,这里强制指定,防止签名报错。
    @param accept      同contentType
    @param contentMd5  当body为非Form表单形式的时候需要计算MD5值
*/
- (NSDictionary *)getHeader :(NSString *)pathParams :(NSString *)method :(NSString *)contentType :(NSString *)accept :(NSString *)contentMd5 {
    NSString *uuid        = [[NSUUID UUID] UUIDString];
    
    UInt64 recordTime     = [[NSDate date] timeIntervalSince1970] * 1000;
    NSNumber *currentTime = [NSNumber numberWithInteger:recordTime];
    NSString *timestamp   = [NSString stringWithFormat:@"%@", currentTime];
    method                = [method uppercaseString];

    NSString *headerString   = [NSString stringWithFormat:@"X-Ca-Key:%@\nX-Ca-Nonce:%@\nX-Ca-Timestamp:%@", appKey, uuid, timestamp];

    NSString *sinatureString = [NSString stringWithFormat:@"%@\n%@\n%@\n%@\n%@\n%@\n%@", method, accept, contentMd5, contentType, @"", headerString, pathParams];
    
    NSDictionary *header     = @{
                             @"X-Ca-Key"       : appKey,
                             @"X-Ca-Nonce"     : uuid,
                             @"X-Ca-Timestamp" : timestamp,
                             @"X-Ca-Signature-Headers" : @"X-Ca-Key,X-Ca-Nonce,X-Ca-Timestamp",
                             @"X-Ca-Signature"         : [self encrypto:sinatureString],
                             /*! @warn IOS默认会把Accept带上"*斜杠* 会导致签名失败,这里需要强制指定accept" */
                             @"Accept"                 : accept,
                             @"Content-type"           : contentType
                             };
    return header;
}

- (NSString *)encrypto:(NSString *)sourceString {
    NSData *saltData       = [appSecret dataUsingEncoding:NSUTF8StringEncoding];
    NSData *paramData      = [sourceString dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableData* hash    = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH ];
    CCHmac(kCCHmacAlgSHA256, saltData.bytes, saltData.length, paramData.bytes, paramData.length, hash.mutableBytes);
    NSData *base64hash     = [hash base64EncodedDataWithOptions:0];
    NSString *base64String = [[NSString alloc] initWithData:base64hash encoding:NSUTF8StringEncoding];
    return base64String;
}

@end

调用方法:

#import "Sinagure.h"

Sinagure *sinagure = [[Sinagure alloc] init];
[sinagure sendMsg:@"13000000000":@"签名名称":@"模板code":@"{\"name\":\"xxx\"}"];

Swift版本

Swift脚本可以通过调用Object-C代码实现短信发送。

如果你使用的编程语言未在上述调用示例之内,你可以根据签名说明文档自行实现。也可以通过调用Shell脚本发送短信。

客户支持

如有其他问题,可以加入我们的客户支持群(群号:1639868142),有专门的小二会提供咨询。

Enjoy it~

目录
相关文章
|
20天前
|
API
阿里云短信服务文档与实际API不符
阿里云短信服务文档与实际API不符
|
4天前
|
JSON API 数据格式
店铺所有商品列表接口json数据格式示例(API接口)
当然,以下是一个示例的JSON数据格式,用于表示一个店铺所有商品列表的API接口响应
|
28天前
|
机器学习/深度学习 PyTorch 算法框架/工具
揭秘深度学习中的微调难题:如何运用弹性权重巩固(EWC)策略巧妙应对灾难性遗忘,附带实战代码详解助你轻松掌握技巧
【10月更文挑战第1天】深度学习中,模型微调虽能提升性能,但常导致“灾难性遗忘”,即模型在新任务上训练后遗忘旧知识。本文介绍弹性权重巩固(EWC)方法,通过在损失函数中加入正则项来惩罚对重要参数的更改,从而缓解此问题。提供了一个基于PyTorch的实现示例,展示如何在训练过程中引入EWC损失,适用于终身学习和在线学习等场景。
42 4
揭秘深度学习中的微调难题:如何运用弹性权重巩固(EWC)策略巧妙应对灾难性遗忘,附带实战代码详解助你轻松掌握技巧
|
17天前
|
JSON API 数据安全/隐私保护
拍立淘按图搜索json数据格式示例(API接口)
拍立淘按图搜索API接口为电商平台和购物应用提供了强大的图像搜索功能,能够显著提升用户的购物体验和搜索效率。开发者可以根据自己的需求调用此接口,并处理返回的JSON格式数据来展示推荐商品
|
20天前
|
API
阿里云短信平台API错误码提示错误天级流控显示小时级错误码
阿里云短信平台API错误码提示错误天级流控显示小时级错误码
|
2月前
|
JSON Go API
使用Go语言和Gin框架构建RESTful API:GET与POST请求示例
使用Go语言和Gin框架构建RESTful API:GET与POST请求示例
|
18天前
|
JSON API 数据格式
商品详情数据JSON格式示例参考(api接口)
JSON数据格式的商品详情数据通常包含商品的多个层级信息,以下是一个综合多个来源信息的JSON数据格式的商品详情数据示例参考:
|
18天前
|
存储 前端开发 API
Restful API 设计示例
Restful API 设计示例
25 0
|
2月前
|
API iOS开发 开发者
Snapchat API 访问:Objective-C 实现示例
Snapchat API 访问:Objective-C 实现示例
|
3月前
|
JSON 安全 API
构建高效后端API:最佳实践与代码示例
【8月更文挑战第2天】 在数字化时代,后端API是连接数据与用户的桥梁。本文深入探讨了如何设计并实现高效的后端API,从理论到实践,提供了实用的技巧和代码示例。通过阅读本篇文章,你将学会如何避免常见的陷阱,优化你的API性能,从而提供更加流畅的用户体验。