Todos os produtos
Search
Central de documentação

Direct Mail:Exemplo de chamada SMTP para Python 3.6 ou posterior

Última atualização: Jun 27, 2026

Envie e-mails a partir do Python 3.6 ou versões posteriores utilizando o endpoint SMTP do Direct Mail.

Pré-requisitos

Antes de começar, verifique se você possui:

  • Um endereço de remetente criado no console do Direct Mail

  • Uma senha SMTP gerada para esse endereço de remetente

  • Python 3.6 ou versão posterior instalado

Aviso: Não codifique sua senha SMTP diretamente no source code. Armazene as credenciais em variáveis de ambiente ou em um gerenciador de segredos e faça a leitura delas durante a execução.

Como funciona

Este exemplo utiliza as bibliotecas nativas smtplib e email do Python para:

  1. Construir uma mensagem MIMEMultipart com os cabeçalhos To, Cc, Bcc, Reply-To e Return-Path.

  2. Anexar um corpo HTML (opções de texto simples e anexos de arquivo estão disponíveis como código comentado).

  3. Conectar-se a smtpdm.aliyun.com na porta 80 (ou porta 465 para SSL) e autenticar-se com o endereço de remetente e a senha SMTP.

  4. Enviar para todos os destinatários em uma única chamada e tratar erros SMTP por tipo.

Código de exemplo

# -*- coding:utf-8 -*-
import smtplib
import email
# import json
# import base64
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# from email.mime.image import MIMEImage
# from email.mime.base import MIMEBase
# from email.mime.application import MIMEApplication
from email.header import Header
from email.utils import formataddr
# import urllib.request
# import ssl

# The sender address created in the Direct Mail console.
username = 'XXXXXXXX'
# The SMTP password for the sender address.
password = 'XXXXXXXX'
# The reply-to address. When a recipient replies, the email goes to this address
# instead of the sender address, which does not receive replies.
replyto = 'XXXXXXXX'
# The To recipient addresses (displayed in the email header).
rcptto = ['address1@example.net', 'address2@example.net']
# The Cc recipient addresses (displayed in the email header).
rcptcc = ['address3@example.net', 'address4@example.net']
# The Bcc recipient addresses (hidden from recipients but receive the email).
rcptbcc = ['address5@example.net', 'address6@example.net']
# All recipients. A single send cannot exceed 60 addresses.
receivers = rcptto + rcptcc + rcptbcc

# Build the message.
msg = MIMEMultipart('alternative')
msg['Subject'] = Header('Custom email subject')
msg['From'] = formataddr(["Custom sender nickname", username])  # Nickname + sender address (or proxy sender)
msg['To'] = ",".join(rcptto)
msg['Cc'] = ",".join(rcptcc)
msg['Reply-to'] = replyto  # Address that receives replies. The recipient must support standard protocols.
msg['Return-Path'] = 'test@example.net'  # Address that receives bounces. The recipient must support standard protocols.
msg['Message-id'] = email.utils.make_msgid()  # Unique identifier per RFC 5322, e.g. <uniquestring@example.com>.
msg['Date'] = email.utils.formatdate()

# To enable email tracking, uncomment the following section.
# A tag is required and must be created in the console at least 10 minutes before use.
# tagName = 'xxxxxxx'
#
# trace = {
#     "OpenTrace": '1',  # Enable open tracking.
#     "LinkTrace": '1',  # Enable link-click tracking.
#     "TagName": tagName
# }
# jsonTrace = json.dumps(trace)
# base64Trace = str(base64.b64encode(jsonTrace.encode('utf-8')), 'utf-8')
# msg.add_header("X-AliDM-Trace", base64Trace)

# To add a plain-text fallback for mail clients that do not render HTML, uncomment the following.
# textplain = MIMEText('Custom plain text part', _subtype='plain', _charset='UTF-8')
# msg.attach(textplain)

# HTML body.
texthtml = MIMEText('Custom HTML hypertext part', _subtype='html', _charset='UTF-8')
msg.attach(texthtml)

# To attach a local file, uncomment the following.
# files = [r'C:\Users\Downloads\test1.jpg', r'C:\Users\Downloads\test2.jpg']
# for t in files:
#     filename = t.rsplit('/', 1)[1]
#     part_attach1 = MIMEApplication(open(t, 'rb').read())
#     part_attach1.add_header('Content-Disposition', 'attachment', filename=filename)
#     msg.attach(part_attach1)

# To attach a file from a URL (e.g., an OSS object), uncomment the following.
# files = [r'https://example.oss-cn-shanghai.aliyuncs.com/xxxxxxxxxxx.png']
# for t in files:
#     filename = t.rsplit('/', 1)[1]
#     response = urllib.request.urlopen(t)
#     part_attach1 = MIMEApplication(response.read())
#     part_attach1.add_header('Content-Disposition', 'attachment', filename=filename)
#     msg.attach(part_attach1)

# Send the email.
try:
    # To use SSL, replace the line below with:
    # client = smtplib.SMTP_SSL('smtpdm.aliyun.com', 465)
    #
    # If the SSL handshake fails on Python 3.10 or 3.11, use a custom context:
    # ctxt = ssl.create_default_context()
    # ctxt.set_ciphers('DEFAULT')
    # client = smtplib.SMTP_SSL('smtpdm.aliyun.com', 465, context=ctxt)

    # Standard SMTP on port 80 (port 25 is also supported).
    client = smtplib.SMTP('smtpdm.aliyun.com', 80)
    client.set_debuglevel(0)  # Set to 1 to enable debug output.
    # The sender address and authentication address must match.
    client.login(username, password)
    client.sendmail(username, receivers, msg.as_string())
    client.quit()
    print('Email sent successfully!')
except smtplib.SMTPConnectError as e:
    print('Failed to send email. Connection failed:', e.smtp_code, e.smtp_error)
except smtplib.SMTPAuthenticationError as e:
    print('Failed to send email. Authentication error:', e.smtp_code, e.smtp_error)
except smtplib.SMTPSenderRefused as e:
    print('Failed to send email. Sender refused:', e.smtp_code, e.smtp_error)
except smtplib.SMTPRecipientsRefused as e:
    print('Failed to send email. Recipients refused:', e.smtp_code, e.smtp_error)
except smtplib.SMTPDataError as e:
    print('Failed to send email. Data reception refused:', e.smtp_code, e.smtp_error)
except smtplib.SMTPException as e:
    print('Failed to send email:', str(e))
except Exception as e:
    print('Exception while sending email:', str(e))

Parâmetros principais

Parâmetro

Descrição

username

Endereço de remetente criado no console do Direct Mail. Utilizado como login SMTP e argumento FROM do sendmail — os três valores devem ser idênticos.

password

Senha SMTP associada ao endereço de remetente. Diferente da senha da sua conta Alibaba Cloud.

replyto

Endereço destinado a receber respostas. Independente do endereço de remetente, pois este último não recebe respostas.

rcptto / rcptcc / rcptbcc

Listas de destinatários To, Cc e Bcc. O total combinado nas três listas não pode ultrapassar 60 endereços por envio.

smtpdm.aliyun.com

Endpoint SMTP do Direct Mail. Utilize a porta 80 ou 25 para SMTP simples, ou a porta 465 para SSL.

Recursos opcionais

O exemplo inclui código comentado para os recursos abaixo. Remova os comentários das seções correspondentes para ativá-los.

  • Corpo em texto simples: Adicione uma parte alternativa text/plain junto ao corpo HTML. Clientes de e-mail que não renderizam HTML exibirão automaticamente a versão em texto simples.

  • Anexo de arquivo local: Leia um arquivo do disco e anexe-o à mensagem usando MIMEApplication.

  • Anexo via URL: Obtenha um arquivo diretamente de uma URL (como um objeto do OSS) e anexe-o sem precisar salvá-lo no disco previamente.

  • Conexão SSL: Substitua smtplib.SMTP por smtplib.SMTP_SSL na porta 465. Caso o handshake SSL falhe no Python 3.10 ou 3.11, crie um contexto SSL personalizado com ctxt.set_ciphers('DEFAULT').

  • Rastreamento de e-mail: Configure o cabeçalho X-AliDM-Trace com um payload JSON codificado em Base64 para habilitar o rastreamento de abertura e cliques em links. Requer uma tag criada no console do Direct Mail (disponível 10 minutos após a criação).