All Products
Search
Document Center

Direct Mail:Request example (Python 3.6 or later)

Last Updated: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-encode the signature and convert the byte type to a string.
    print('Signature after Base64 encoding:' + Signature)
    return Signature


def getUtf8Encoder(param):
    # UTF-8 encoding.
    # Replace + with %20, * with %2A, and %7E with ~ in the encoded string.
    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
    # & Add more parameters as needed.
    # & < Common request parameters >

    protocol = "https"
    method = "POST"
    host = "dm.aliyuncs.com"
    AccessKeySecret = os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET']  # The AccessKey secret issued by Alibaba Cloud. Replace this with your own AccessKey secret. We recommend that you retrieve it from an environment variable. For more information, see Configure AccessKey pairs in environment variables.

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

    print('Current system time: ', time1.strftime("%Y-%m-%d %H:%M:%S"), ' -8 hours, converted to UTC: ', time2.strftime("%Y-%m-%dT%H:%M:%SZ"))

    params_dict = {}
    # Assign values to parameters.
    params_dict["AccessKeyId"] = os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID']  # The AccessKey ID issued by Alibaba Cloud. Replace this with your own AccessKey ID. # Required parameter
    params_dict["AccountName"] = 'test***@example.net'  # The sender address configured in the console.
    params_dict["Action"] = 'SingleSendMail'  # A required parameter, such as SingleSendMail or BatchSendMail.
    params_dict["AddressType"] = 1  # 0: random account. 1: sender address.
    params_dict["Format"] = 'JSON'  # The format of the return value. Valid values: JSON and XML. Default value: XML. # Required parameter
    params_dict["HtmlBody"] = 'Chinese body'  # The HTML body of the email.
    params_dict["RegionId"] = 'cn-hangzhou'  # The data center information. For other regions, see the API endpoints document.
    params_dict["ReplyToAddress"] = 'true'  # true: Use the reply-to address set in the console.
    params_dict["SignatureMethod"] = 'HMAC-SHA1'  # The signature algorithm. Only HMAC-SHA1 is supported. # Required parameter
    params_dict["SignatureNonce"] = str(uuid.uuid4())  # A required parameter. A unique random number to prevent replay attacks. Use a different random number for each request. You can use a UUID or a custom string.
    params_dict["SignatureVersion"] = 1.0  # A required parameter. The version of the signature algorithm. The current version is 1.0.
    params_dict["Subject"] = 'Custom subject'  # The email subject.
    params_dict["TagName"] = 'Custom tag'  # The email tag.    
    params_dict['Template'] = '{"TemplateData":{"username":"222"},"TemplateId":"411558"}'
    params_dict["Timestamp"] = time2.strftime(
        "%Y-%m-%dT%H:%M:%SZ")  # A required parameter. The request timestamp. The time must be in UTC and follow the ISO 8601 standard. Format: YYYY-MM-DDThh:mm:ssZ. For example, 2015-11-23T04:00:00Z is 12:00:00 on November 23, 2015 (UTC+8).
    params_dict["ToAddress"] = 'test1***@example.net'  # The recipient address.
    params_dict["Version"] = '2015-11-23'  # Required parameter
    # Version:
    # The API version number in the YYYY-MM-DD format. The recommended version is 2015-11-23.

    print('Initial parameters:', params_dict)
    # Example of encoding the HtmlBody value:
    # Initial parameter: params_dict["HtmlBody"] = 'Chinese body'
    # message in the getSignature function: %25E4%25B8%25AD%25E6%2596%2587body, double URL encoded
    # In the final generated URL: %E4%B8%AD%E6%96%87body
    # URL-encode the initial parameter dictionary: dict-->str

    # The order of parameters for signing cannot be changed.
    # The code sorts the dictionary to ensure the correct parameter order for signing.
    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('After the first URL encoding:' + url_dict_to_str)# Example: %E4%B8%AD%E6%96%87body
    print('Generating signature...')
    params_dict["Signature"] = getSignature(url_dict_to_str, method)
    print('Signature generated.')
    param = urlencode(params_dict)
    print('After adding Signature to the request parameters and URL-encoding again:' + param)# Example: %E4%B8%AD%E6%96%87body
    # Generate the URL.
    final_url = protocol + "://" + host
    print('Example of the final generated URL:', protocol + "://" + host + "/?" + param)
    # POST request URL
    response = requests.post(final_url, data=params_dict)
    # Return information. RequestId is the unique identifier generated by Alibaba Cloud for the request. Example: {"RequestId":"D0291CF2-BFDA-46F1-9DFD-6B32B5675B38","EnvId":"120414808748"}
    print('Returned parameters:' + response.text)
    # Print URL parameters.
    # listurl = final_url.split("&")
    # for i in listurl:
    #     print(i)
Note

For more information about how to configure an AccessKey pair in an environment variable, see Configure AccessKey pairs in environment variables.

For a list of endpoints in other regions, see API endpoints.

Example of the final request URL for the China (Hangzhou) region

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