Отправка через SMTP
Что нужно для подключения
Отправляйте письма из приложения через SMTP с логином и паролем ящика. API-ключ и токен аккаунта для SMTP не подходят.
Создайте активный ящик на подключённом домене и завершите проверку его DNS-записей. Логин — полный адрес, например [email protected]. Пароль — пароль этого ящика, а не почтового аккаунта. В примерах замените адреса своими; пароль вводится скрыто при запуске.
Сервер, порты и шифрование
Используйте mail.adapt-mail.com для любого подключённого домена. На порту 465 TLS включается сразу; на порту 587 сначала выполняется STARTTLS, затем авторизация. Выберите один вариант. Проверку сертификата отключать не нужно.
Адрес From и SMTP-отправитель в примерах совпадают с логином ящика. Имя отправителя можно изменить. Порт 25 предназначен для обмена между почтовыми серверами, для приложения используйте 465 или 587.
SMTP_HOST = "mail.adapt-mail.com"SMTP_PORT = 465SMTP_USER = "[email protected]"SMTP_PASSWORD = "<mailbox-password>"SMTP_FROM = "[email protected]"SMTP_FROM_NAME = "Example"
465: implicit TLS587: STARTTLSPython: отправка через порт 465
Пример использует только стандартную библиотеку Python 3. Сохраните его в send_mail.py и запустите python3 send_mail.py. Для автоматической отправки получайте пароль из защищённой конфигурации вашего приложения; не сохраняйте его в Git или логах.
import smtplibimport sslfrom getpass import getpassfrom email.message import EmailMessagefrom email.utils import formataddr, make_msgid, formatdate
username = "[email protected]"password = getpass("SMTP password: ")recipient = "[email protected]"
message = EmailMessage()message["From"] = formataddr(("Example", username))message["To"] = recipientmessage["Subject"] = "SMTP test"message["Date"] = formatdate(localtime=False, usegmt=True)message["Message-ID"] = make_msgid(domain=username.split("@")[1])message.set_content("Hello! This message was sent through Adapt Mail SMTP.")
with smtplib.SMTP_SSL( "mail.adapt-mail.com", 465, timeout=30, context=ssl.create_default_context(),) as smtp: smtp.login(username, password) refused = smtp.send_message( message, from_addr=username, to_addrs=[recipient], ) print("Rejected recipients:", refused)Python: подключение через порт 587
Для STARTTLS используйте подготовку письма из предыдущего примера и замените блок with smtplib.SMTP_SSL на следующий. В smtplib.SMTP пароль передаётся только после успешного STARTTLS.
with smtplib.SMTP("mail.adapt-mail.com", 587, timeout=30) as smtp: smtp.ehlo() smtp.starttls(context=ssl.create_default_context()) smtp.ehlo() smtp.login(username, password) refused = smtp.send_message( message, from_addr=username, to_addrs=[recipient], ) print("Rejected recipients:", refused)HTML и вложения
Добавьте HTML-версию после set_content, а вложение — перед отправкой. Текстовую версию оставьте для клиентов без HTML. Передавайте только доверенный HTML или экранируйте подставляемые данные.
message.add_alternative( "<p>Hello! This message was sent through <strong>Adapt Mail</strong>.</p>", subtype="html",)with open("document.pdf", "rb") as attachment: message.add_attachment( attachment.read(), maintype="application", subtype="pdf", filename="document.pdf", )Результат, лимиты и отправленные
Успешный send_message означает, что SMTP-сервер принял письмо, а не что оно попало во входящие получателя. Словарь refused содержит отклонённых получателей; при отказе всем получателям Python выбросит SMTPRecipientsRefused.
SMTP и API используют общие лимиты одного ящика: до 30 писем за скользящие 60 секунд, до 50 получателей в одном письме и до 1000 получателей за скользящие 24 часа; при включённом повышенном лимите — 5000. Считаются все адресаты To, Cc и Bcc.
Прямая отправка через SMTP сама по себе не сохраняет копию в папке «Отправленные». Это делает почтовый клиент через IMAP; отправка через API Adapt Mail сохраняет копию отдельно.
Ошибки SMTP
535- Авторизация не прошла: проверьте полный адрес, пароль ящика и доступность ящика.
451- Временный отказ, в том числе при превышении лимита отправки. Повторите позже с задержкой.
550 / 5xx- Постоянный отказ: проверьте адреса, права отправителя и текст ответа. Более 50 получателей отклоняются после DATA. Исправьте причину перед повтором.
TLS / timeout- Проверьте имя mail.adapt-mail.com, порт, режим TLS и исходящий доступ с сервера приложения. На 465 используйте SMTP_SSL, на 587 — SMTP с STARTTLS.
Читайте полный ответ SMTP-сервера. Временный отказ повторяйте с задержкой. Если соединение оборвалось после передачи письма и итог неизвестен, не отправляйте его повторно вслепую: в SMTP нет Idempotency-Key, повтор может создать дубликат.