全部產品
Search
文件中心

Direct Mail:請求樣本(Python3.6及以上)

更新時間:Jan 01, 2026

# -*- coding: utf-8 -*-
import hmac
import uuid
import base64
import datetime
import requests
import os
from hashlib import sha1
from urllib.parse import urlencode
from urllib.parse import quote


def getSignature(param, method):
    utf8 = getUtf8Encoder(param)
    toSign = method + "&" + quote('/', 'utf-8') + "&" + utf8
    message = toSign.encode(encoding='UTF-8', errors='strict')
    print("message:", message)
    key = (AccessKeySecret + "&").encode(encoding='UTF-8', errors='strict')
    bytes = hmac.new(key, message, sha1)
    Signature = str(base64.b64encode(bytes.digest()), encoding="utf-8")  # base64編碼並把byte類型轉為字串
    print('Signature base64編碼後:' + Signature)
    return Signature


def getUtf8Encoder(param):
    # utf-8編碼
    # 把編碼後的字串中加號 + 替換成 %20、星號 * 替換成 %2A、%7E 替換回波浪號 ~,
    return quote(param.replace('+', '%20').replace('*', '%2A'), encoding="utf-8")


if __name__ == '__main__':
    # https://dm.aliyuncs.com/?Action=SingleSendMail
    # & AccountName = test @ example.com
    # & AddressType = 1
    # & ReceiversName = test2
    # & TemplateName = test1
    # & 可繼續增加參數
    # & < 公用請求參數 >

    protocol = "https"
    method = "POST"
    host = "dm.aliyuncs.com"
    AccessKeySecret = os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET']  # 阿里雲頒發給使用者的訪問服務所用的金鑰識別碼。需要替換為對應的內容。建議配置到環境變數中擷取,請參考文檔:在環境變數中配置身分識別驗證AccessKey。

    time1 = datetime.datetime.now()
    time2 = time1 + datetime.timedelta(hours=-8)

    print('當前系統時間: ', time1.strftime("%Y-%m-%d %H:%M:%S"), ' -8小時,轉換為國際標準時間:', time2.strftime("%Y-%m-%dT%H:%M:%SZ"))

    params_dict = {}
    # 參數賦值
    params_dict["AccessKeyId"] = os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID']  # 阿里雲頒發給使用者的訪問服務所用的金鑰識別碼。需要替換為對應的內容。                #公用請求參數
    params_dict["AccountName"] = 'test***@example.net'  # 管理主控台中配置的發信地址。
    params_dict["Action"] = 'SingleSendMail'  # 系統規定參數SingleSendMail/BatchSendMail等介面
    params_dict["AddressType"] = 1  # 0:為隨機帳號 1:為發信地址
    params_dict["Format"] = 'JSON'  # 傳回值的類型,支援 JSON 與 XML。預設為 XML。  #公用請求參數
    params_dict["HtmlBody"] = '中文body'  # html郵件內容
    params_dict["RegionId"] = 'cn-hangzhou'  # 機房資訊。其他地區請參考API服務地址文檔擷取。
    params_dict["ReplyToAddress"] = 'true'  # true 為使用控制台設定的回信地址,
    params_dict["SignatureMethod"] = 'HMAC-SHA1'  # 簽名方式,目前支援 HMAC-SHA1。                #公用請求參數
    params_dict["SignatureNonce"] = str(uuid.uuid4())  # 公用請求參數,唯一隨機數,用於防止網路重放攻擊。不同的請求要使用不同的隨機數值。您可以使用UUID(隨機串),也可以自訂。
    params_dict["SignatureVersion"] = 1.0  # 公用請求參數,簽名演算法版本,目前版本是1.0。
    params_dict["Subject"] = '自訂佈景主題'  # 郵件主題
    params_dict["TagName"] = '自訂標籤'  # 郵件標籤    
    params_dict['Template'] = '{"TemplateData":{"username":"222"},"TemplateId":"411558"}'
    params_dict["Timestamp"] = time2.strftime(
        "%Y-%m-%dT%H:%M:%SZ")  # 公用請求參數,請求的時間戳記。日期格式按照 ISO8601 標準表示,並需要使用 UTC 時間。格式為YYYY-MM-DDThh:mm:ssZ。 例如,2015-11-23T04:00:00Z(為北京時間 2015年11月23日12點0分0秒)。
    params_dict["ToAddress"] = 'test1***@example.net'  # 收件地址
    params_dict["Version"] = '2015-11-23'  # 公用請求參數
    # Version:
    # API 版本號碼,為日期形式:YYYY-MM-DD。推薦版本為2015-11-23。

    print('初始參數:', params_dict)
    # htmlbody的值為例進行編碼:
    # 初始參數:params_dict["HtmlBody"] = '中文body'
    # getSignature函數內的message:%25E4%25B8%25AD%25E6%2596%2587body ,二次URL編碼
    # 最終產生的URL中:%E4%B8%AD%E6%96%87body
    # 對初始參數字典進行URL 編碼 dict-->str

    #伺服器參數順序不可變更
    #字典排序處理代碼,增加傳參時的順序自由度
    params_dict_sorted = {}
    for i in sorted(params_dict):
        params_dict_sorted[i] = params_dict[i]
    print(params_dict_sorted)
    url_dict_to_str = urlencode(params_dict_sorted)

    print('第一次URL編碼後:' + url_dict_to_str)# 例:%E4%B8%AD%E6%96%87body
    print('產生Signature開始。。。')
    params_dict["Signature"] = getSignature(url_dict_to_str, method)
    print('產生Signature結束。。。')
    param = urlencode(params_dict)
    print('請求參數添加Signature後,再次URL編碼後:' + param)#例:%E4%B8%AD%E6%96%87body
    # 產生URL
    final_url = protocol + "://" + host
    print('最終產生的URL參考:', protocol + "://" + host + "/?" + param)
    # post請求URL
    response = requests.post(final_url, data=params_dict)
    # 返回資訊 RequestId 阿里雲為該請求產生的唯一識別碼。例:{"RequestId":"D0291CF2-BFDA-46F1-9DFD-6B32B5675B38","EnvId":"120414808748"}
    print('返回參數:' + response.text)
    # 列印url參數
    # listurl = final_url.split("&")
    # for i in listurl:
    #     print(i)
說明

如何將AccessKeySecret和AccessKeyId配置到環境變數中,請參考:在環境變數中配置身分識別驗證AccessKey

如何擷取其他地區的RegionId,請參考:API服務地址

杭州服務地區最後發出的URL請求樣本如下

https://dm.aliyuncs.com/?AccessKeyId=xxxxxxxx&AccountName=test%40t1.example.com&Action=SingleSendMail&AddressType=1&Format=JSON&HtmlBody=%E4%B8%AD%E6%96%87body&RegionId=cn-hangzhou&ReplyToAddress=true&SignatureMethod=HMAC-SHA1&SignatureNonce=a883f1bf-e415-4a4d-91ba-085ad3bc7741&SignatureVersion=1.0&Subject=%E8%87%AA%E5%AE%9A%E4%B9%89%E4%B8%BB%E9%A2%98&TagName=%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A0%87%E7%AD%BE&Template=%7B%22TemplateData%22%3A%7B%22username%22%3A%22222%22%7D%2C%22TemplateId%22%3A%22411558%22%7D&Timestamp=2025-12-31T06%3A01%3A51Z&ToAddress=test%40example.com&Version=2015-11-23&Signature=%2Fapm1xqY3Ob9k9IgFbgZcrbeYrg%3D