
# Python
|    样例    | [发送短信示例]、[发送分批短信示例]、[接收状态报告示例]、 |
|---|---|
| **环境要求** | 基于Python 3.7.0版本，要求Python 3.7及以上版本。                                                                                                                                                          |
   
![](https://support.huaweicloud.com/devg-msgsms/public_sys-resources/notice_3.0-zh-cn.png)
- 发送短信为单模板群发短信示例，发送分批短信为多模板群发短信示例。

- 本文档所述Demo在提供服务的过程中，可能会涉及个人数据的使用，建议您遵从国家的相关法律采取足够的措施，以确保用户的个人数据受到充分的保护。
- 本文档所述Demo仅用于功能演示，不允许客户直接进行商业使用。
- 本文档信息仅供参考，不构成任何要约或承诺。
 
参考[API签名SDK与demo](https://support.huaweicloud.com/devg-apisign/api-sign-sdk-python.html)，单击下载其中的SDK与Demo。将下列代码样例替换main.py文件内容即可。
 #### 发送短信示例
```
# coding=utf-8
import urllib.parse
import urllib.request
import requests
from apig_sdk import signer
if __name__ == '__main__':
    # 必填,请参考"开发准备"获取如下数据,替换为实际值
    url = 'https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendSms/v1' #APP接入地址(在控制台"应用管理"页面获取)+接口访问URI
    # 认证用的appKey和appSecret硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；
    APP_KEY = "c8RWg3ggEcyd4D3p94bf3Y7x1Ile" #APP_Key
    APP_SECRET = "q4Ii87Bh************80SfD7Al" #APP_Secret
    sender = "csms12345678" #国内短信签名通道号
    TEMPLATE_ID = "8ff55eac1d0b478ab3c06c3c6a492300" #模板ID
    #条件必填,国内短信关注,当templateId指定的模板类型为通用模板时生效且必填,必须是已审核通过的,与模板类型一致的签名名称
   
    signature = "华为云短信测试" #签名名称
    # 必填,全局号码格式(包含国家码),示例:+86151****6789,多个号码之间用英文逗号分隔
    receiver = "+86151****6789,+86152****7890" #短信接收人号码
    # 选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告
    statusCallBack = ""
    '''
    选填,使用无变量模板时请赋空值 TEMPLATE_PARAM = '';
    单变量模板示例:模板内容为"您的验证码是${1}"时,TEMPLATE_PARAM可填写为'["369751"]'
    双变量模板示例:模板内容为"您有${1}件快递请到${2}领取"时,TEMPLATE_PARAM可填写为'["3","人民公园正门"]'
    模板中的每个变量都必须赋值，且取值不能为空
    查看更多模板规范和变量规范:产品介绍>短信模板须知和短信变量须知
    '''
    TEMPLATE_PARAM = '["369751"]' #模板变量，此处以单变量验证码短信为例，请客户自行生成6位验证码，并定义为字符串类型，以杜绝首位0丢失的问题（例如：002569变成了2569）。
    formData = urllib.parse.urlencode({
        'from': sender,
        'to': receiver,
        'templateId': TEMPLATE_ID,
        'templateParas': TEMPLATE_PARAM,
        'statusCallback': statusCallBack,
        # 'signature': signature #使用中国大陆短信通用模板时,必须填写签名名称
    }).encode('ascii')
    print(formData)
    sig = signer.Signer()
    sig.Key = APP_KEY
    sig.Secret = APP_SECRET
    r = signer.HttpRequest("POST", url)
    r.headers = {"content-type": "application/x-www-form-urlencoded"}
    r.body = formData
    sig.Sign(r)
    print(r.headers["X-Sdk-Date"])
    print(r.headers["Authorization"])
    resp = requests.request(r.method, r.scheme + "://" + r.host + r.uri, headers=r.headers, data=r.body, verify=False)
    print(resp.status_code, resp.reason)
    print(resp.content)
```
 #### 发送分批短信示例
```
# coding=utf-8
import json
import requests
from apig_sdk import signer
if __name__ == '__main__':
    # 必填,请参考"开发准备"获取如下数据,替换为实际值
    url = 'https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendDiffSms/v1'  # APP接入地址(在控制台"应用管理"页面获取)+接口访问URI
    # 认证用的appKey和appSecret硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；
    APP_KEY = "c8RWg3ggEcyd4D3p94bf3Y7x1Ile"  # APP_Key
    APP_SECRET = "q4Ii87Bh************80SfD7Al"  # APP_Secret
    sender = "csms12345678"  # 国内短信签名通道号
    TEMPLATE_ID_1 = "8ff55eac1d0b478ab3c06c3c6a492300"  # 模板ID1
    TEMPLATE_ID_2 = "8ff55eac1d0b478ab3c06c3c6a492300"  # 模板ID2
    # 条件必填,国内短信关注,当templateId指定的模板类型为通用模板时生效且必填,必须是已审核通过的,与模板类型一致的签名名称
    
    signature_1 = "华为云短信测试"  # 签名名称1
    signature_2 = "华为云短信测试"  # 签名名称2
    # 必填,全局号码格式(包含国家码),示例:+86151****6789,多个号码之间用英文逗号分隔
    receiver_1 = ["+86151****6789", "+86152****7890"]  # 模板1的接收号码
    receiver_2 = ["+86151****6789", "+86152****7890"]  # 模板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）。
    '''
    选填,使用无变量模板时请赋空值 TEMPLATE_PARAM = '';
    单变量模板示例:模板内容为"您的验证码是${1}"时,TEMPLATE_PARAM可填写为'["369751"]'
    双变量模板示例:模板内容为"您有${1}件快递请到${2}领取"时,TEMPLATE_PARAM可填写为'["3","人民公园正门"]'
    模板中的每个变量都必须赋值，且取值不能为空
    查看更多模板规范和变量规范:产品介绍>短信模板须知和短信变量须知
    '''
    TEMPLATE_PARAM = '["369751"]'  # 模板变量，此处以单变量验证码短信为例，请客户自行生成6位验证码，并定义为字符串类型，以杜绝首位0丢失的问题（例如：002569变成了2569）。
    # 请求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')
    sig = signer.Signer()
    sig.Key = APP_KEY
    sig.Secret = APP_SECRET
    r = signer.HttpRequest("POST", url)
    r.headers = {"content-type": "application/json"}
    r.body = jsonData
    sig.Sign(r)
    print(r.headers["X-Sdk-Date"])
    print(r.headers["Authorization"])
    resp = requests.request(r.method, r.scheme + "://" + r.host + r.uri, headers=r.headers, data=r.body, verify=False)
    print(resp.status_code, resp.reason)
    print(resp.content)
```
 #### 接收状态报告
```
# -*- 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)
```
#### 接收上行短信
```
# -*- coding: utf-8 -*-
import urllib.parse
# 上行短信通知样例(urlencode)
updata = "from=%2B86151****6789&to=1069****019&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)
```
#### 相关推荐
| 相关文档                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | 相关产品                                                                                                                                                                  |
|:---|:---|
| - 代码样例：[Java](https://support.huaweicloud.com/devg-msgsms/sms_04_0018.html)/[PHP](https://support.huaweicloud.com/devg-msgsms/sms_04_0013.html)/[Python](https://support.huaweicloud.com/devg-msgsms/sms_04_0014.html)/[3.1.5-Node.js](https://support.huaweicloud.com/devg-msgsms/sms_04_0016.html)/[3.1.6-Go](https://support.huaweicloud.com/devg-msgsms/sms_04_0017.html)  - [发送短信API](https://support.huaweicloud.com/api-msgsms/sms_05_0001.html)  - [发送分批短信API](https://support.huaweicloud.com/api-msgsms/sms_05_0002.html)  - [接收状态报告API](https://support.huaweicloud.com/api-msgsms/sms_05_0003.html)  - [接收上行短信API](https://support.huaweicloud.com/api-msgsms/sms_05_0004.html)  - [调测问题处理](https://support.huaweicloud.com/api-msgsms/sms_05_0050.html)   | [语音通话](https://www.huaweicloud.com/product/voice.html) [隐私保护通话](https://www.huaweicloud.com/product/privatenumber.html) |
   
