文档首页 > > 开发指南> 代码样例> Python

Python

分享
更新时间:2020/06/02 GMT+08:00

样例

发送短信(示例1)发送分批短信(示例1)

发送短信(示例2)发送分批短信(示例2)

接收状态报告接收上行短信

环境要求

基于Python 3.7.0版本,要求Python 3.7及以上版本。

引用库

requests 2.18.1(仅示例1引用)

  1. 请自行下载安装Python 3.7,并完成环境配置。
  2. 打开命令行窗口,执行pip install requests命令。
  3. 执行pip list查看安装结果。
  • 本文档所述Demo在提供服务的过程中,可能会涉及个人数据的使用,建议您遵从国家的相关法律采取足够的措施,以确保用户的个人数据受到充分的保护。
  • 本文档所述Demo仅用于功能演示,不允许客户直接进行商业使用。
  • 本文档信息仅供参考,不构成任何要约或承诺。

发送短信(示例1)

 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
# -*- coding: utf-8 -*-
import time
import uuid
import hashlib
import base64
import requests #需要先使用pip install requests命令安装依赖

# 必填,请参考"开发准备"获取如下数据,替换为实际值
url = 'https://rtcsms.cn-north-1.myhuaweicloud.com:10743/sms/batchSendSms/v1' #APP接入地址+接口访问URI
APP_KEY = "c8RWg3ggEcyd4D3p94bf3Y7x1Ile" #APP_Key
APP_SECRET = "q4Ii87BhST9vcs8wvrzN80SfD7Al" #APP_Secret
sender = "csms12345678" #国内短信签名通道号或国际/港澳台短信通道号
TEMPLATE_ID = "8ff55eac1d0b478ab3c06c3c6a492300" #模板ID

#条件必填,国内短信关注,当templateId指定的模板类型为通用模板时生效且必填,必须是已审核通过的,与模板类型一致的签名名称
#国际/港澳台短信不用关注该参数
signature = "华为云短信测试" #签名名称

# 必填,全局号码格式(包含国家码),示例:+8615123456789,多个号码之间用英文逗号分隔
receiver = "+8615123456789,+8615234567890" #短信接收人号码

# 选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告
statusCallBack = ""

'''
选填,使用无变量模板时请赋空值 TEMPLATE_PARAM = '';
单变量模板示例:模板内容为"您的验证码是${1}"时,TEMPLATE_PARAM可填写为'["369751"]'
双变量模板示例:模板内容为"您有${1}件快递请到${2}领取"时,TEMPLATE_PARAM可填写为'["3","人民公园正门"]'
模板中的每个变量都必须赋值,且取值不能为空
查看更多模板和变量规范:产品介绍>模板和变量规范
'''
TEMPLATE_PARAM = '["369751"]' #模板变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。

'''
构造X-WSSE参数值
@param appKey: string
@param appSecret: string
@return: string
'''
def buildWSSEHeader(appKey, appSecret):
    now = time.strftime('%Y-%m-%dT%H:%M:%SZ') #Created
    nonce = str(uuid.uuid4()).replace('-', '') #Nonce
    digest = hashlib.sha256((nonce + now + appSecret).encode()).hexdigest()

    digestBase64 = base64.b64encode(digest.encode()).decode() #PasswordDigest
    return 'UsernameToken Username="{}",PasswordDigest="{}",Nonce="{}",Created="{}"'.format(appKey, digestBase64, nonce, now);

def main():
    # 请求Headers
    header = {'Authorization': 'WSSE realm="SDP",profile="UsernameToken",type="Appkey"',
              'X-WSSE': buildWSSEHeader(APP_KEY, APP_SECRET)}
    # 请求Body
    formData = {'from': sender,
                'to': receiver,
                'templateId': TEMPLATE_ID,
                'templateParas': TEMPLATE_PARAM,
                'statusCallback': statusCallBack,
#                'signature': signature #使用国内短信通用模板时,必须填写签名名称
                }
    print(header)
    
    # 为防止因HTTPS证书认证失败造成API调用失败,需要先忽略证书信任问题
    r = requests.post(url, data=formData, headers=header, verify=False)
    print(r.text) #打印响应信息

if __name__ == '__main__':
    main() 

发送短信(示例2)

 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
# -*- coding: utf-8 -*-
import time
import uuid
import hashlib
import base64
import ssl
import urllib.parse
import urllib.request

# 必填,请参考"开发准备"获取如下数据,替换为实际值
url = 'https://rtcsms.cn-north-1.myhuaweicloud.com:10743/sms/batchSendSms/v1' #APP接入地址+接口访问URI
APP_KEY = "c8RWg3ggEcyd4D3p94bf3Y7x1Ile" #APP_Key
APP_SECRET = "q4Ii87BhST9vcs8wvrzN80SfD7Al" #APP_Secret
sender = "csms12345678" #国内短信签名通道号或国际/港澳台短信通道号
TEMPLATE_ID = "8ff55eac1d0b478ab3c06c3c6a492300" #模板ID

#条件必填,国内短信关注,当templateId指定的模板类型为通用模板时生效且必填,必须是已审核通过的,与模板类型一致的签名名称
#国际/港澳台短信不用关注该参数
signature = "华为云短信测试" #签名名称

# 必填,全局号码格式(包含国家码),示例:+8615123456789,多个号码之间用英文逗号分隔
receiver = "+8615123456789,+8615234567890" #短信接收人号码

# 选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告
statusCallBack = ""

'''
选填,使用无变量模板时请赋空值 TEMPLATE_PARAM = '';
单变量模板示例:模板内容为"您的验证码是${1}"时,TEMPLATE_PARAM可填写为'["369751"]'
双变量模板示例:模板内容为"您有${1}件快递请到${2}领取"时,TEMPLATE_PARAM可填写为'["3","人民公园正门"]'
模板中的每个变量都必须赋值,且取值不能为空
查看更多模板和变量规范:产品介绍>模板和变量规范
'''
TEMPLATE_PARAM = '["369751"]' #模板变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。

'''
构造X-WSSE参数值
@param appKey: string
@param appSecret: string
@return: string
'''
def buildWSSEHeader(appKey, appSecret):
    now = time.strftime('%Y-%m-%dT%H:%M:%SZ') #Created
    nonce = str(uuid.uuid4()).replace('-', '') #Nonce
    digest = hashlib.sha256((nonce + now + appSecret).encode()).hexdigest()

    digestBase64 = base64.b64encode(digest.encode()).decode() #PasswordDigest
    return 'UsernameToken Username="{}",PasswordDigest="{}",Nonce="{}",Created="{}"'.format(appKey, digestBase64, nonce, now);

def main():
    # 请求Body
    formData = urllib.parse.urlencode({
                    'from': sender,
                    'to': receiver,
                    'templateId': TEMPLATE_ID,
                    'templateParas': TEMPLATE_PARAM,
                    'statusCallback': statusCallBack,
#                    'signature': signature #使用国内短信通用模板时,必须填写签名名称
                    }).encode('ascii')

    req = urllib.request.Request(url=url, data=formData, method='POST') #请求方法为POST
    # 请求Headers参数
    req.add_header('Authorization', 'WSSE realm="SDP",profile="UsernameToken",type="Appkey"')
    req.add_header('X-WSSE', buildWSSEHeader(APP_KEY, APP_SECRET))
    req.add_header('Content-Type', 'application/x-www-form-urlencoded')

    # 为防止因HTTPS证书认证失败造成API调用失败,需要先忽略证书信任问题
    ssl._create_default_https_context = ssl._create_unverified_context

    try:
        r = urllib.request.urlopen(req) #发送请求
        print(r.read().decode('utf-8')) #打印响应信息
    except urllib.error.HTTPError as e:
        print(e.code)
        print(e.read().decode('utf-8'))
    except urllib.error.URLError as e:
        print(e.reason)

if __name__ == '__main__':
    main() 

发送分批短信(示例1)

 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
# -*- coding: utf-8 -*-
import time
import uuid
import hashlib
import base64
import requests #需要先使用pip install requests命令安装依赖

# 必填,请参考"开发准备"获取如下数据,替换为实际值
url = 'https://rtcsms.cn-north-1.myhuaweicloud.com:10743/sms/batchSendDiffSms/v1' #APP接入地址+接口访问URI
APP_KEY = "c8RWg3ggEcyd4D3p94bf3Y7x1Ile" #APP_Key
APP_SECRET = "q4Ii87BhST9vcs8wvrzN80SfD7Al" #APP_Secret
sender = "csms12345678" #国内短信签名通道号或国际/港澳台短信通道号
TEMPLATE_ID_1 = "8ff55eac1d0b478ab3c06c3c6a492300" #模板ID1
TEMPLATE_ID_2 = "8ff55eac1d0b478ab3c06c3c6a492300" #模板ID2

#条件必填,国内短信关注,当templateId指定的模板类型为通用模板时生效且必填,必须是已审核通过的,与模板类型一致的签名名称
#国际/港澳台短信不用关注该参数
signature_1 = "华为云短信测试" #签名名称1
signature_2 = "华为云短信测试" #签名名称2

# 必填,全局号码格式(包含国家码),示例:+8615123456789,多个号码之间用英文逗号分隔
receiver_1 = ["+8615123456789", "+8615234567890"] #模板1的接收号码
receiver_2 = ["+8615123456789", "+8615234567890"] #模板2的接收号码

# 选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告
statusCallBack = ""

'''
选填,使用无变量模板时请赋空值 TEMPLATE_PARAM = [];
单变量模板示例:模板内容为"您的验证码是${1}"时,TEMPLATE_PARAM可填写为["369751"]
双变量模板示例:模板内容为"您有${1}件快递请到${2}领取"时,TEMPLATE_PARAM可填写为["3","人民公园正门"]
模板中的每个变量都必须赋值,且取值不能为空
查看更多模板和变量规范:产品介绍>模板和变量规范
'''
TEMPLATE_PARAM_1 = ["123456"] #模板1变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。
TEMPLATE_PARAM_2 = ["234567"] #模板2变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。

'''
构造X-WSSE参数值
@param appKey: string
@param appSecret: string
@return: string
'''
def buildWSSEHeader(appKey, appSecret):
    now = time.strftime('%Y-%m-%dT%H:%M:%SZ') #Created
    nonce = str(uuid.uuid4()).replace('-', '') #Nonce
    digest = hashlib.sha256((nonce + now + appSecret).encode()).hexdigest()

    digestBase64 = base64.b64encode(digest.encode()).decode() #PasswordDigest
    return 'UsernameToken Username="{}",PasswordDigest="{}",Nonce="{}",Created="{}"'.format(appKey, digestBase64, nonce, now);

def main():
    # 请求Headers
    header = {'Authorization':'WSSE realm="SDP",profile="UsernameToken",type="Appkey"',
              'X-WSSE': buildWSSEHeader(APP_KEY, APP_SECRET)}
    # 请求Body
    jsonData = {'from': sender,
                'statusCallback': statusCallBack,
                'smsContent':[
                    {'to':receiver_1,
                     'templateId':TEMPLATE_ID_1,
                     'templateParas':TEMPLATE_PARAM_1,
#                     'signature':signature_1 #使用国内短信通用模板时,必须填写签名名称
                     },
                    {'to':receiver_2,
                     'templateId':TEMPLATE_ID_2,
                     'templateParas':TEMPLATE_PARAM_2,
#                     'signature':signature_2 #使用国内短信通用模板时,必须填写签名名称
                     }]
                }
    print(header)
    
    # 为防止因HTTPS证书认证失败造成API调用失败,需要先忽略证书信任问题
    r = requests.post(url, json=jsonData, headers=header, verify=False)
    print(r.text) #打印响应信息

if __name__ == '__main__':
    main() 

发送分批短信(示例2)

 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
# -*- coding: utf-8 -*-
import time
import uuid
import hashlib
import base64
import json
import ssl
import urllib.request

# 必填,请参考"开发准备"获取如下数据,替换为实际值
url = 'https://rtcsms.cn-north-1.myhuaweicloud.com:10743/sms/batchSendDiffSms/v1' #APP接入地址+接口访问URI
APP_KEY = "c8RWg3ggEcyd4D3p94bf3Y7x1Ile" #APP_Key
APP_SECRET = "q4Ii87BhST9vcs8wvrzN80SfD7Al" #APP_Secret
sender = "csms12345678" #国内短信签名通道号或国际/港澳台短信通道号
TEMPLATE_ID_1 = "8ff55eac1d0b478ab3c06c3c6a492300" #模板ID1
TEMPLATE_ID_2 = "8ff55eac1d0b478ab3c06c3c6a492300" #模板ID2

#条件必填,国内短信关注,当templateId指定的模板类型为通用模板时生效且必填,必须是已审核通过的,与模板类型一致的签名名称
#国际/港澳台短信不用关注该参数
signature_1 = "华为云短信测试" #签名名称1
signature_2 = "华为云短信测试" #签名名称2

# 必填,全局号码格式(包含国家码),示例:+8615123456789,多个号码之间用英文逗号分隔
receiver_1 = ["+8615123456789", "+8615234567890"] #模板1的接收号码
receiver_2 = ["+8615123456789", "+8615234567890"] #模板2的接收号码

# 选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告
statusCallBack = ""

'''
选填,使用无变量模板时请赋空值 TEMPLATE_PARAM = [];
单变量模板示例:模板内容为"您的验证码是${1}"时,TEMPLATE_PARAM可填写为["369751"]
双变量模板示例:模板内容为"您有${1}件快递请到${2}领取"时,TEMPLATE_PARAM可填写为["3","人民公园正门"]
模板中的每个变量都必须赋值,且取值不能为空
查看更多模板和变量规范:产品介绍>模板和变量规范
'''
TEMPLATE_PARAM_1 = ["123456"] #模板1变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。
TEMPLATE_PARAM_2 = ["234567"] #模板2变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。

'''
构造X-WSSE参数值
@param appKey: string
@param appSecret: string
@return: string
'''
def buildWSSEHeader(appKey, appSecret):
    now = time.strftime('%Y-%m-%dT%H:%M:%SZ') #Created
    nonce = str(uuid.uuid4()).replace('-', '') #Nonce
    digest = hashlib.sha256((nonce + now + appSecret).encode()).hexdigest()

    digestBase64 = base64.b64encode(digest.encode()).decode() #PasswordDigest
    return 'UsernameToken Username="{}",PasswordDigest="{}",Nonce="{}",Created="{}"'.format(appKey, digestBase64, nonce, now);

def main():
    # 请求Body
    jsonData = json.dumps({'from': sender,
                           'statusCallback': statusCallBack,
                           'smsContent':[
                                {'to':receiver_1,
                                 'templateId':TEMPLATE_ID_1,
                                 'templateParas':TEMPLATE_PARAM_1,
#                                 'signature':signature_1 #使用国内短信通用模板时,必须填写签名名称
                                 },
                                {'to':receiver_2, 
                                 'templateId':TEMPLATE_ID_2, 
                                 'templateParas':TEMPLATE_PARAM_2,
#                                 'signature':signature_2 #使用国内短信通用模板时,必须填写签名名称
                                 }]
                           }).encode('ascii')

    req = urllib.request.Request(url=url, data=jsonData, method='POST') #请求方法为POST
    # 请求Headers参数
    req.add_header('Authorization', 'WSSE realm="SDP",profile="UsernameToken",type="Appkey"')
    req.add_header('X-WSSE', buildWSSEHeader(APP_KEY, APP_SECRET))
    req.add_header('Content-Type', 'application/json')

    # 为防止因HTTPS证书认证失败造成API调用失败,需要先忽略证书信任问题
    ssl._create_default_https_context = ssl._create_unverified_context

    try:
        r = urllib.request.urlopen(req) #发送请求
        print(r.read().decode('utf-8')) #打印响应信息
    except urllib.error.HTTPError as e:
        print(e.code)
        print(e.read().decode('utf-8'))
    except urllib.error.URLError as e:
        print(e.reason)

if __name__ == '__main__':
    main() 

接收状态报告

 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
# -*- coding: utf-8 -*-
import urllib.parse

# 短信平台上报状态报告数据样例(urlencode)
#success_body = "sequence=1&total=1&updateTime=2018-10-31T08%3A43%3A41Z&source=2&smsMsgId=2ea20735-f856-4376-afbf-570bd70a46ee_11840135&status=DELIVRD";
failed_body = "sequence=1&total=1&updateTime=2018-10-31T08%3A43%3A41Z&source=2&smsMsgId=2ea20735-f856-4376-afbf-570bd70a46ee_11840135&status=E200027";

'''
解析状态报告数据
@param data: 短信平台上报的状态报告数据
@return: 
'''
def onSmsStatusReport(data):
    keyValues = urllib.parse.parse_qs(data); #解析状态报告数据

    '''
    Example: 此处已解析status为例,请按需解析所需参数并自行实现相关处理

    'smsMsgId': 短信唯一标识
    'total': 长短信拆分条数
    'sequence': 拆分后短信序号
    'source': 状态报告来源
    'updateTime': 资源更新时间
    'status': 状态码
    '''
    status = keyValues.get('status'); #状态报告枚举值
    # 通过status判断短信是否发送成功
    if 'DELIVRD' == str.upper(status[0]):
        print('Send sms success. smsMsgId: ', keyValues.get('smsMsgId')[0]);
    else:
        # 发送失败,打印status和orgCode
        print('Send sms failed. smsMsgId: ', keyValues.get('smsMsgId')[0]);
        print('Failed status: ', status[0]);

if __name__ == '__main__':
#     onSmsStatusReport(success_body)
    onSmsStatusReport(failed_body)

接收上行短信

 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
# -*- coding: utf-8 -*-
import urllib.parse

# 上行短信通知样例(urlencode)
updata = "from=%2B8615123456789&to=10691002019&body=********&smsMsgId=9692b5be-c427-4525-8e73-cf4a6ac5b3f7";

'''
解析上行短信通知数据
@param data: 短信平台推送的上行短信通知数据
@return: 
'''
def onSmsUpData(data):
    keyValues = urllib.parse.parse_qs(data); #解析上行短信通知数据

    '''
    Example: 此处已解析body为例,请按需解析所需参数并自行实现相关处理

    'smsMsgId': 上行短信唯一标识
    'from': 上行短信发送方的号码
    'to': 上行短信接收方的号码
    'body': 上行短信发送的内容
    '''
    body = keyValues.get('body'); #上行短信发送的内容
    print('Sms up data. Body: ', body[0]);

if __name__ == '__main__':
    onSmsUpData(updata)
分享:

    相关文档

    相关产品

文档是否有解决您的问题?

提交成功!非常感谢您的反馈,我们会继续努力做到更好!
反馈提交失败,请稍后再试!

*必选

请至少选择或填写一项反馈信息

字符长度不能超过200

提交反馈 取消

如您有其它疑问,您也可以通过华为云社区问答频道来与我们联系探讨

智能客服提问云社区提问