Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Транзакционные письма: надёжная доставка

Транзакционные письма: отправка без потерь и дублей

Транзакционные письма: отличие от маркетинговых, отдельный домен отправки, обработка отказов, повторы и учёт состояния доставки.

Прямой ответ

Транзакционное письмо отправляется по последствию действия пользователя — подтверждение заказа, сброс пароля, уведомление об оплате. Отличие от маркетингового письма определяется требованием к своевременности и репутацией отправителя.

Признак Транзакционное Маркетинговое
Повод Действие пользователя Инициатива сервиса
Ожидание доставки Минуты Часы либо дни
Влияние репутации Критично Высокое
Отказ от получения Не применяется Обязателен
Объём Низкий, привязан к событиям Массовый

Смешение двух типов в одном потоке отправки приводит к тому, что массовая рассылка снижает репутацию отправителя, и транзакционные письма попадают в спам. Разделение выполняется отдельным доменом либо поддоменом отправки.

Отправка через SMTP с фиксацией состояния:

import smtplib
from email.message import EmailMessage

msg = EmailMessage()
msg["From"] = "Нутмаркет <noreply@mail.noutmarket.example>"
msg["To"] = user_email
msg["Subject"] = "Заказ 1001 подтверждён"
msg["Message-ID"] = f"<order-1001-{notification_id}@mail.noutmarket.example>"
msg.set_content(text_body)
msg.add_alternative(html_body, subtype="html")

with smtplib.SMTP(SMTP_HOST, 587, timeout=15) as s:
    s.starttls()
    s.login(SMTP_USER, SMTP_PASSWORD)
    s.send_message(msg)

Идентификатор сообщения уникален, поэтому повторная отправка распознаётся принимающей стороной как дубль. О настройке локальной отправки — в статье про SMTP в разработке.

Состояние доставки фиксируется отдельно от факта передачи провайдеру, поскольку принятие письма не означает доставку в ящик.

Что определяет доставку транзакционного письма

Передача письма провайдеру — первый шаг, а не результат. Четыре фактора влияют на фактическое получение.

Репутация отправляющего домена. Домен, с которого отправляется массовая рассылка с жалобами, снижает доставляемость всех писем, включая транзакционные. Разделение доменов устраняет влияние.

Аутентификация отправителя. Записи SPF, DKIM и DMARC подтверждают право отправлять письма от имени домена; о настройке — в статье про доставляемость писем.

Содержание письма. Ссылки на домены, отличные от домена отправителя, и вложения повышают вероятность фильтрации. Транзакционное письмо содержит минимум ссылок.

Адрес получателя. Несуществующий адрес приводит к постоянному отказу, а повторные отправки на него снижают репутацию.

Практическое следствие: отказ доставки обрабатывается по типу. Временный отказ означает повтор через интервал, постоянный — прекращение попыток и фиксацию адреса как недействительного.

UPDATE notifications
SET status = CASE WHEN $2 = 'permanent' THEN 'failed' ELSE 'queued' END,
    attempts = attempts + 1
WHERE id = $1 AND status = 'sending';

Отдельный вопрос — повторная отправка. Пользователь запрашивает повторное письмо, поэтому запрос выполняется с проверкой предыдущей отправки: повтор в пределах короткого интервала возвращает существующее письмо, а не создаёт новое.

Уведомление о недоставке приходит асинхронно и обрабатывается отдельно; о разделении записи и отправки — в статье про архитектуру уведомлений.

Отсрочка отправки и группировка уведомлений

Не каждое транзакционное письмо требует немедленной отправки. Три сценария допускают отсрочку без потери ценности.

Серия событий за короткий интервал. Пользователь выполняет несколько действий подряд, и каждое порождает письмо. Группировка в одно сообщение снижает число писем и воспринимается лучше, чем поток отдельных уведомлений.

Отложенное подтверждение. Письмо отправляется после завершения асинхронной операции, поэтому немедленная отправка привела бы к сообщению о незавершённом действии.

Учёт времени получателя. Сообщение, не требующее немедленной реакции, отправляется в приемлемое время по местному часовому поясу получателя.

Практическое следствие: отсрочка задаётся временем отправки в записи уведомления, а обработчик выбирает записи, у которых время наступило. Немедленная отправка остаётся поведением по умолчанию для событий, где своевременность критична.

Отдельный вопрос — группировка. Объединение нескольких событий в одно письмо требует накопления записей в течение интервала и отмены отправки при наступлении завершающего события. Сложность группировки оправдана при высоком числе событий на пользователя, а при редких событиях приводит к лишней задержке.

Проверка своевременности выполняется по возрасту записи: превышение заданного интервала между созданием и отправкой указывает на сбой обработчика либо на накопление очереди.

Практика: организация транзакционной отправки

1. Используйте отдельный домен для транзакционных писем. Массовая рассылка не влияет на репутацию домена, с которого отправляются подтверждения заказов.

2. Настройте аутентификацию отправителя. Записи SPF, DKIM и DMARC обязательны, поскольку письмо без аутентификации фильтруется.

3. Фиксируйте уникальный идентификатор сообщения. Повторная отправка распознаётся как дубль, а разбор обращения выполняется по идентификатору.

4. Различайте временный и постоянный отказ. Повтор выполняется только при временном отказе, постоянный прекращает попытки.

5. Храните состояние доставки. Принятие письма провайдером не означает доставку, поэтому состояние уточняется по уведомлению о недоставке.

6. Ограничивайте частоту повторов по запросу пользователя. Несколько запросов подряд не должны создавать несколько писем.

7. Проверяйте адрес перед отправкой. Отправка на заведомо недействительный адрес снижает репутацию отправителя.

Рекомендации:

  1. Не отправляйте вложения в транзакционных письмах. Вложение повышает вероятность фильтрации, поэтому документ передаётся ссылкой.
  2. Разделяйте текст и HTML-версию. Письмо только в HTML фильтруется чаще, а текстовая версия обеспечивает читаемость.
  3. Учитывайте часовые пояса при оценке своевременности. Время отправки хранится с отметкой времени, иначе оценка задержки некорректна.
  4. Мониторьте долю недоставленных писем. Рост доли указывает на проблему с репутацией либо с настройкой аутентификации.
  5. Документируйте состав транзакционных писем. Перечень событий, требующих письма, фиксируется, поскольку пропуск события обнаруживается пользователем.

Практический сценарий: письма о сбросе пароля попадают в спам

Контекст: пользователи сообщали, что письма для восстановления доступа не приходят либо оказываются в папке спама.

  1. Диагностика. Письма отправлялись с того же домена, что и еженедельная маркетинговая рассылка. Доля жалоб на рассылку выросла, и письма с домена начали фильтроваться, включая транзакционные.
  2. Причина. Reputation домена определяется всей исходящей почтой, поэтому массовая рассылка с жалобами снизила доставляемость транзакционных писем. Разделение доменов отсутствовало.
  3. Действия. (а) Выделили отдельный поддомен для транзакционных писем и настроили для него записи SPF, DKIM и DMARC; (б) перенесли отправку подтверждений и сброса пароля на новый поддомен; (в) добавили текстовую версию письма и сократили число ссылок до одной; (г) внедрили обработку отказов с разделением временных и постоянных; (д) добавили метрику доли недоставленных писем по каждому поддомену.
  4. Результат. Транзакционные письма доставляются независимо от репутации маркетингового домена, а доля недоставленных отслеживается отдельно.

Вывод: репутация отправляющего домена общая для всей исходящей почты, поэтому смешение транзакционных и маркетинговых писем снижает доставляемость первых. Разделение доменов с собственной аутентификацией устраняет влияние массовой рассылки.

FAQ

Нужно ли разделять домены для транзакционных и маркетинговых писем? Да. Репутация домена общая, поэтому жалобы на рассылку снижают доставляемость транзакционных писем.

Что означает принятие письма провайдером? Письмо передано и поставлено в очередь отправки. Доставка в ящик получателя выполняется позже и может завершиться отказом.

Как обрабатывать постоянный отказ доставки? Прекратить попытки и зафиксировать адрес как недействительный. Повторные отправки на недействительный адрес снижают репутацию.

Можно ли отправлять транзакционное письмо без аутентификации домена? Технически да, но письмо фильтруется чаще, поэтому записи SPF, DKIM и DMARC обязательны.

Источники: RFC 5321 (SMTP), Python smtplib, PostgreSQL explicit locking — ссылки в шапке.