Инженерия · 21 сентября 2026 г.
Пошаговый план миграции транзакционной почты
Смена провайдера транзакционной почты без потери наблюдаемости требует поэтапного подхода: параллельная отправка, сопоставление событий и постепенное переключение DNS.
Главная сложность миграции
Чтобы перенести транзакционную почту без потери наблюдаемости, нужно отделить триггер отправки от реализации провайдера. Стратегия — ввести слой абстракции провайдера, который позволяет вести параллельную (теневую) отправку и сопоставлять события. Направляя небольшую долю трафика новому провайдеру и продолжая отслеживать события доставки через вебхуки, вы убеждаетесь, что новый провайдер принимает почту, а конвейер наблюдаемости фиксирует результаты, — и только потом переключаете основной поток.
Почему меняют провайдера
Большинство миграций вызваны стоимостью, удобством для разработчиков или требованиями соответствия. Например, разница в стоимости между провайдерами значительна. Согласно ценам Amazon SES, отправка a la carte стоит 0.10 USD за 1 000 писем. Для сравнения, цены Postmark начинаются от 15 USD в месяц за 10 000 писем, превышение — от 1.80 до 1.20 USD за 1 000. Отправка 50 000 писем стоит около 5 USD на SES a la carte и примерно 66 USD на тарифах Postmark.
Среди других причин — переход на телеметрию только в ЕС с минимальным сбором данных или потребность в лучшей готовности к работе с агентами (например, поддержке MCP-сервера). Какой бы ни была причина, риск один и тот же: слепая зона в конвейере доставки на время перехода.
Этап 1: слой абстракции
Если бизнес-логика приложения напрямую вызывает SDK провайдера, вы к нему привязаны. Нужна обёртка, которая стандартизирует запрос и ответ.
Единая полезная нагрузка
Определите внутреннюю схему, не зависящую от провайдера. Тогда приложению не придётся учитывать, ожидает ли нижележащий API поле to в виде массива или одной строки.
{
"message_id": "msg_12345",
"recipient": "user@example.com",
"template_id": "welcome_email",
"variables": {
"name": "Alex"
},
"idempotency_key": "unique_request_id_789"
}
При работе с ИИ-агентами или автоматизированными процессами критически важно относиться к письму как к внешнему побочному эффекту. Используйте ключ идемпотентности, чтобы повторный проход цикла агента не отправил одному пользователю одно и то же транзакционное письмо пять раз.
Этап 2: настройка DNS и адресов отправителя
Прежде чем отправить хотя бы одно письмо, нужно подтвердить, кто вы. Именно здесь большинство миграций проваливаются из-за задержек распространения DNS или ошибок настройки.
- Подтвердите домены: добавьте записи DKIM и SPF нового провайдера. Проверьте, что записи опубликованы и правильно оформлены, с помощью инструмента вроде Email DNS Checker от SendHQ.
- Разберитесь в записях: убедитесь, что понимаете разницу между SPF (авторизует сервер) и DKIM (подписывает письмо). Если во время миграции вы используете нескольких провайдеров, SPF-запись должна включать обоих.
- Выравнивание DMARC: на начальном этапе миграции установите политику DMARC
p=none, чтобы избежать жёстких отказов при небольших расхождениях в выравнивании. Подробные шаги настройки — в руководстве SendHQ по DKIM, SPF и DMARC.
Этап 3: теневая (параллельная) отправка
Не переключайтесь одним движением. Вместо этого реализуйте маршрутизацию, при которой письмо уходит основному провайдеру, а дубликат (или выборочная доля) асинхронно отправляется новому.
Логика реализации
async function sendEmail(payload) {
// Primary send (Current Provider)
const primaryResult = await primaryProvider.send(payload);
// Shadow send (New Provider) - do not await or block the main thread
if (Math.random() < 0.1) { // 10% sample
newProvider.send(payload).catch(err =>
console.error("Shadow send failed", err)
);
}
return primaryResult;
}
На этом этапе вы проверяете приём провайдером — момент, когда провайдер говорит: «Да, я беру это письмо». Это не то же самое, что доставка (письмо дошло до принимающего сервера) и попадание во «Входящие» (письмо не ушло в «Спам»).
Этап 4: наблюдаемость и соответствие событий
Наблюдаемость — это возможность проследить письмо от sent до delivered или bounced. У каждого провайдера своя схема вебхуков.
Сопоставление событий
Создайте таблицу сопоставления, чтобы привести события к единому виду во внутренней базе данных:
Внутреннее событие | Amazon SES | Resend | Postmark | SendHQ
sent (отправлено) | Send | sent | Sent | sent
delivered (доставлено) | Delivery | delivered | Delivered | delivered
bounced (отказ) | Bounce | bounced | Bounced | bounced
complaint (жалоба) | Complaint | complained | Complaint | complaint
Обработка полезной нагрузки вебхуков
Обработчик вебхуков должен быть универсальным. Полезная нагрузка от нового провайдера должна проходить через преобразователь, прежде чем попасть в систему аналитики.
function transformWebhook(provider, payload) {
switch(provider) {
case 'resend':
return { event: payload.data.delivered ? 'delivered' : 'failed', id: payload.data.id };
case 'sendhq':
return { event: payload.event, id: payload.message_id };
default:
throw new Error("Unknown provider");
}
}
Этап 5: постепенное переключение
Убедившись, что новый провайдер принимает почту, а вебхуки правильно сопоставляют события, переходите к взвешенному распределению.
- 1% трафика: направьте новому провайдеру 1% всей транзакционной почты. Следите за долей отказов.
- 10% трафика: увеличьте нагрузку. Проверьте лимиты запросов. Например, бесплатный тариф Resend ограничен 100 письмами в день, что может стать узким местом при тестировании.
- 50% трафика: это проверка стабильности. Убедитесь, что задержка остаётся приемлемой.
- 100% трафика: окончательное переключение.
Типичные сбои при миграции и их устранение
«Тихое отбрасывание»
Некоторые провайдеры принимают письмо (202 Accepted), но отбрасывают его внутри из-за контент-фильтров или неподтверждённых адресов отправителя. Поэтому этап теневой отправки обязателен. Если событий sent много, а delivered мало, у вас проблема с доставкой, а не с API.
Всплески лимитов запросов
У разных провайдеров разные лимиты на пиковую нагрузку. Тарифы Mailgun и SendGrid (у которого бесплатный тариф теперь — 60-дневный пробный период) часто предусматривают разные квоты пропускной способности. При переходе с аккаунта с высокими лимитами на новый аккаунт вас могут начать притормаживать. Используйте очередь (например, RabbitMQ или SQS), чтобы сглаживать всплески.
Сбои идемпотентности
При смене провайдера можно случайно запустить повторную отправку пакета. Если письма отправляют ИИ-агенты, убедитесь, что агент передаёт уникальный ID запроса. Если агент работает с вашим email API через MCP-сервер, API должен отклонять повторяющиеся значения idempotency_key в пределах 24-часового окна.
Чек-лист миграции
- Уровень абстракции реализован (полезная нагрузка (payload), независимая от провайдера).
- Для нового провайдера добавлены DNS-записи (SPF, DKIM).
- DNS проверен через sendhq.cc/tools/email-dns-checker.
- Обработчик вебхуков обновлён для новых схем провайдера.
- Таблица сопоставления событий заполнена (Sent, Delivered, Bounced, Complaint).
- Теневая (параллельная) отправка активна на уровне от 1% до 10%.
- Ключи идемпотентности проверены для отправок, инициированных агентом.
- Постепенное наращивание (1%, 10%, 50%, 100%).
- API-ключи старого провайдера отозваны после 7 дней 100% стабильности.
Напоследок о выборе провайдера
Выбор провайдера — компромисс между стоимостью и скоростью разработки. Если нужна минимальная стоимость, Amazon SES с его 0.10 USD за 1 000 писем при оплате a la carte трудно превзойти, хотя новые тарифы (Essentials за 0.16 USD, Pro за 0.22 USD) с 21 июля 2026 года вводят другую структуру затрат. Если нужен современный API со встроенной готовностью к агентам и телеметрией только в ЕС с минимальным сбором данных, SendHQ — более простая альтернатива.
Независимо от провайдера цель в том, чтобы ваша инженерная команда не была привязана к SDK конкретного поставщика. Относясь к письму как к стандартизированному побочному эффекту, вы превращаете рискованную миграцию в рутинное изменение конфигурации.
Подробнее о построении надёжных процессов работы с почтой — на https://sendhq.cc.