Перейти к содержанию

Интеграция Mailgun и n8n: transactional email с шаблонами, tracking и idempotency

Обновлено: 2026-05-30

AI summary: Problem/Solution-гайд по Mailgun и n8n: как отправлять transactional email через API без дублей, с шаблонами, проверкой получателей, tracking и журналом доставки.
Готовый blueprint для внедрения

Импортируйте JSON в n8n, замените credentials, домены, sender IDs, лимиты, callback URL и production-политики под вашу инфраструктуру.

Проблема: письмо из CRM или формы кажется простым HTTP-запросом, пока retry не отправляет клиенту два одинаковых invoice, шаблон не ломается из-за пустого поля, а delivery status остаётся только в логах Mailgun.

Решение: интеграция Mailgun и n8n должна валидировать получателя, выбрать approved template, собрать idempotency key, отправить письмо через Sending API и записать delivery/audit status обратно в CRM или таблицу. Такой подход закрывает не демонстрационный happy path, а реальную production-боль: повторы, consent, delivery status, API-ошибки, ограничения провайдера и понятный audit trail.

Схема интеграции Mailgun и n8n для отправки transactional email без дублей
Схема показывает путь события через n8n: validation, idempotency, отправка во внешний сервис, callback и audit.

Проблема: почему простая отправка ломает коммуникации

Коммуникационный workflow нельзя оценивать только по ответу API. Важны consent, формат адреса или телефона, повторная отправка, связь с CRM, callback-статусы и способ отката, если провайдер принял запрос, но сообщение не доставлено.

Для этой страницы основной объект — transactional email message. Входной контракт должен явно фиксировать recipient_email, template_name, variables, campaign_id, idempotency_key, message_id. Если эти поля приходят нестабильно, автоматизация начинает угадывать и может отправить сообщение не тому получателю, не тем каналом или повторно.

Поэтому workflow строится вокруг детерминированных проверок: сначала validation, consent и idempotency, затем отправка, затем callback/audit и только потом бизнес-действия вроде смены статуса или уведомления менеджера.

Архитектура workflow для n8n

БлокЗадачаProduction-проверка
Webhook / CRM triggerполучает событие для отправки transactional emailесть order_id/deal_id и email
Validate recipientпроверяет email, шаблон и обязательные variablesнет мусорных адресов и пустого template
Idempotency storageне отправляет одно письмо дваждыunique key до Mailgun API
Mailgun Send APIотправляет template-based emailдомен, API key, tracking и tags
Delivery trackingпринимает события accepted/delivered/failedmessage_id связан с CRM
CRM auditзаписывает статус и ссылку на письмокоманда видит факт доставки

Такой workflow удобно сопровождать: mapping, API-запрос, retry, callback и human-readable audit не смешиваются в одной ноде.

Контракт входных данных

{
  "event": "send_invoice_email",
  "recipient_email": "client@example.com",
  "recipient_name": "Ирина",
  "template_name": "invoice_paid_ru",
  "subject": "Счёт оплачен — доступ открыт",
  "order_id": "ord-10492",
  "crm_deal_id": "deal-5581",
  "variables": {
    "amount": "12900.00",
    "currency": "RUB",
    "login_url": "https://example.ru/login"
  },
  "source": "crm",
  "locale": "ru"
}

Payload можно расширять, но нельзя делать обязательные поля “по настроению”. Если источник не передал внешний ID, получателя, шаблон или consent, workflow должен остановиться с понятной ошибкой до отправки.

Code Node: нормализация, mapping и guard-условия

const src = $json.body ?? $json;
const email = String(src.recipient_email ?? '').trim().toLowerCase();
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
  throw new Error(`Invalid recipient_email for Mailgun: ${email}`);
}
const allowedTemplates = new Set(['invoice_paid_ru', 'lead_welcome_ru', 'support_reply_ru']);
const template = String(src.template_name ?? '').trim();
if (!allowedTemplates.has(template)) {
  throw new Error(`Mailgun template is not allowlisted: ${template}`);
}
const orderId = String(src.order_id ?? '').trim();
const dealId = String(src.crm_deal_id ?? '').trim();
if (!orderId && !dealId) throw new Error('order_id or crm_deal_id is required');
const variables = src.variables ?? {};
const idempotencyKey = `mailgun:${template}:${orderId || dealId}:${email}`;
return [{
  json: {
    action: 'send_mailgun_template_email',
    idempotency_key: idempotencyKey,
    mailgun: {
      to: `${src.recipient_name ?? ''} <${email}>`.trim(),
      subject: String(src.subject ?? '').trim() || 'Уведомление',
      template,
      'h:X-Mailgun-Variables': JSON.stringify({ ...variables, order_id: orderId, deal_id: dealId }),
      'o:tracking': 'yes',
      'o:tag': [template, String(src.source ?? 'n8n')]
    },
    audit: { order_id: orderId, crm_deal_id: dealId, recipient_email: email }
  }
}];

Этот скрипт n8n не заменяет политику провайдера. Его задача — привести данные к стабильному контракту, сформировать idempotency key и не пропустить опасный payload дальше по цепочке.

Готовый workflow JSON: скачать и импортировать

В архиве страницы есть импортируемый workflow JSON и тестовый payload. После импорта замените credentials, домены, sender IDs, callback URL, лимиты и правила доступа. Не запускайте сценарий на production-данных, пока не проверены повторы, пустые значения и ошибки API.

{
  "name": "Nodbot - Mailgun transactional email with idempotency and tracking",
  "nodes": [
    {
      "name": "Webhook / CRM trigger",
      "type": "n8n-node",
      "purpose": "получает событие для отправки transactional email"
    },
    {
      "name": "Validate recipient",
      "type": "n8n-node",
      "purpose": "проверяет email, шаблон и обязательные variables"
    },
    {
      "name": "Idempotency storage",
      "type": "n8n-node",
      "purpose": "не отправляет одно письмо дважды"
    },
    {
      "name": "Mailgun Send API",
      "type": "n8n-node",
      "purpose": "отправляет template-based email"
    },
    {
      "name": "Delivery tracking",
      "type": "n8n-node",
      "purpose": "принимает события accepted/delivered/failed"
    },
    {
      "name": "CRM audit",
      "type": "n8n-node",
      "purpose": "записывает статус и ссылку на письмо"
    }
  ],
  "connections": "Webhook / CRM trigger → Validate recipient → Idempotency storage → Mailgun Send API → Delivery tracking → CRM audit"
}
Скачать и проверить: используйте кнопки в начале статьи, затем прогоните curl и сравните результат с audit-log.

Пошаговая настройка связки

  1. Подтвердите sending domain в Mailgun и не используйте sandbox domain для production-писем клиентам.
  2. Создайте allowlist template names и не разрешайте workflow отправлять произвольный HTML из входного payload.
  3. Сохраните Mailgun API key в credentials или ENV, а не в Code Node и не в test payload.
  4. Добавьте таблицу idempotency: ключ, order_id/deal_id, recipient_email, template, Mailgun message_id и status.
  5. Подключите webhook delivery events и обновляйте CRM после accepted/delivered/failed, а не только после 200 OK.
Что проверить после импорта workflow

Откройте каждую ноду, замените credentials и IDs, включите dry-run там, где доступно, затем выполните сценарий на тестовом объекте. Для платных или внешних отправок добавьте approval, rate limit и отдельный тестовый получатель.

Тесты перед production

Минимальный smoke test:

curl -X POST "https://YOUR-N8N-DOMAIN/webhook/mailgun-transactional-email-n8n" -H "Content-Type: application/json" --data @integration-mailgun-n8n-transactional-email-payload.json
  1. повторный payload с тем же order_id
  2. невалидный email
  3. template не из allowlist
  4. ошибка Mailgun 401/429
  5. delivery failed event после успешной отправки

Отдельно проверьте, что retry n8n не создаёт повторную отправку. Для критичных действий используйте durable storage: Postgres, CRM custom field, audit table или другой слой с уникальным ключом.

Production-риски

  • 200 OK от Mailgun считается доставкой, хотя это только принятие запроса.
  • Retry n8n отправляет одно письмо повторно без durable idempotency.
  • HTML письма приходит из формы и открывает риск фишинга или XSS в шаблоне.
  • Bounce/failed события не возвращаются в CRM, и менеджер не видит проблему.
  • Один API key используется для всех доменов без разделения окружений.
Карточка результата Mailgun email delivery с message_id, template и status
Визуальный блок результата помогает быстро понять, что именно должно появиться после успешного запуска.

Внутренняя перелинковка помогает перейти от общего integration-гайда к готовым workflow, а внешние ссылки ведут на официальную документацию API и n8n-нод.

Критерии готовности

  1. Повторный запуск не отправляет второе письмо.
  2. Шаблоны ограничены allowlist и версионируются.
  3. Mailgun message_id сохраняется в CRM или audit table.
  4. Delivery events обновляют статус письма после отправки.
  5. Ошибки 401/429/5xx уходят в alert или DLQ.
Нужно внедрить без риска? Nodbot может собрать production workflow под вашу инфраструктуру: credentials, mapping, idempotency, callbacks, тесты, monitoring, LLM-разметка и понятный runbook для команды.