Low‑code и zero‑code платформы решают логику и бизнес‑процессы, но не решают email deliverability. Между «платформа отправила письмо» и «получатель его увидел» лежит слой, который ни одна из этих платформ не контролирует:
Большинство платформ по дефолту шлют через свою инфраструктуру с shared IP. Без настройки SPF/DKIM/DMARC на домене отправителя — почти гарантированный спам у Mail.ru и Яндекса.
Authentication‑Results на стороне получателя — единственный реальный индикатор. Платформа не отдаёт его и не показывает.
Inbox placement не наблюдаем штатно ни в одной из low‑code‑платформ. Это решается отдельным observability‑слоем.
В статье — архитектура отправки в Bubble, AppMaster, ELMA365, n8n, Make, Albato, что конкретно ломается на каждом уровне, что записывать в DNS, и как встроить проверку доставки в pipeline через webhook без написания SMTP‑инфраструктуры.
Зачем это разработчику на low‑code
Типичная ситуация: вы построили на n8n или Bubble сервис, который шлёт пользователям подтверждение регистрации, OTP‑код, ссылку для сброса пароля или уведомление о действии в системе. Логи платформы говорят «отправлено», метрики Sentry чистые, в админке зелёные галочки. А поддержка получает: «не приходит письмо». Каждый день. От 5–20% пользователей.
Дебажить это с привычным инструментарием не получается, потому что email — единственный из подключаемых сервисов, где отправитель не имеет API для проверки доставки. SMTP‑протокол по RFC 5321 возвращает только статус «accepted/rejected» серверу‑получателю. Что произошло с письмом после accept — определяет фильтр получателя, и наружу эта информация не выходит.
Это значит, что весь стандартный observability — логи, метрики, трейсы — не отвечает на вопрос «дошло ли». Вы видите, что код отработал, что API вернул 250 OK, что в очереди нет ошибок. Письма при этом могут стабильно уходить в спам.
Архитектура отправки в популярных low‑code‑платформах
Bubble
Bubble использует встроенный workflow action Send email или сторонние плагины (SendGrid Plugin, Postmark Plugin). По дефолту:
Отправка идёт с дефолтного домена Bubble (
@bubble.ioили@bubbleapps.io)Можно настроить custom sender domain, но это требует DNS‑настройки на вашем домене
SPF и DKIM‑записи нужно прописывать руками в DNS
Поток отправки:
Workflow event → Bubble backend → Bubble SMTP gateway → получатель
Где ломается: если вы не настроили DKIM на свой домен, Bubble всё равно отправит. С точки зрения получателя:
From:support@yourapp.comФактический сервер отправки — Bubble
Authentication‑Results покажет
dkim=noneилиdkim=fail
Для Mail.ru это сигнал spoofing — письмо в спам автоматически.
AppMaster.io
Российская no‑code платформа для генерации полноценных backend‑приложений. Email‑отправка реализована через сконфигурированный SMTP‑провайдер в настройках проекта. По дефолту встроенный коннектор не выдаёт нативной интеграции — нужно подключать SendGrid, Mailgun, UniSender Go или свой SMTP.
Это технически более чистый подход, потому что отправка идёт от настроенного вами провайдера с вашими DKIM. Но и проблем больше — конфигурация на разработчике, и типичные ошибки:
DKIM не валидируется (опечатка в DNS‑записи)
SPF не включает домен провайдера
Return‑Path указывает на несуществующий ящик
ELMA365, Creatio (бывший Terrasoft), BPMSoft, Comindware
Low‑code BPM для корпоративного сегмента. Отправка обычно идёт через настроенный SMTP‑сервер организации (корпоративный Exchange, Я.360, Mailion) или внешний транзакционный сервис.
Архитектура:
Уведомление в процессе → BPM-движок → SMTP-коннектор → корпоративный SMTP → почтовый сервер получателя
Где ломается: корпоративный SMTP, который ходит и под маркетинг, и под персональную переписку, и теперь ещё под системные уведомления BPM, накапливает репутационные проблемы. Особенно у организаций, которые делают массовые рассылки с того же домена. ELMA365 при этом сама ничего о репутации не знает — она просто передаёт письмо в SMTP.
Внешние уведомления (клиентам, контрагентам) страдают больше всего: у получателей нет встроенного правила доверия к вашему домену, фильтры действуют по общим правилам.
n8n, Make (Integromat), Albato
Платформы автоматизации с email как одним из узлов workflow. У всех трёх схожая логика:
Узел Send Email подключается к настроенному SMTP, Gmail OAuth, или сервису типа SendGrid/Mailgun
Платформа сама писем не генерирует — она транслирует ваш SMTP‑вызов
Сам узел показывает success/error по факту acceptance SMTP‑сервером
Архитектура n8n:
Trigger → Function nodes → Email node → (SMTP config или OAuth Gmail) → SMTP-сервер провайдера → получатель
Проблема: если вы подключили Gmail через OAuth — лимиты Gmail работают (500 писем в день для бесплатных аккаунтов, 2000 для Workspace). Если SMTP вашего ESP — лимиты ESP, и у каждого свои throttling‑политики. Узел показывает success — фактическая доставка не отслеживается никак.
Zapier, Pipedream
Аналогично n8n и Make. Email как action в zap'е — это вызов внешнего сервиса (Gmail, Mailgun, SendGrid). Zapier сам ничего не отправляет, а Mailchimp/SendGrid action возвращают success по факту API‑acceptance.
Особенность Zapier — простота скрывает архитектуру. Маркетолог настраивает zap «когда триггер → отправить письмо», не понимая, что от настроек DNS его домена зависит, дойдёт ли письмо. И никаких подсказок Zapier не даёт.
Аутентификация: SPF, DKIM, DMARC — что должно быть в DNS
Это уровень, который ломается чаще всего. Поясню детально.
SPF (RFC 7208)
TXT‑запись на корневом домене, разрешающая определённым серверам отправлять от вашего имени. Пример для домена, который шлёт через SendGrid + UniSender Go + собственный сервер:
yourdomain.com. IN TXT "v=spf1 include:sendgrid.net include:unione.io ip4:203.0.113.10 ~all"
Типичные ошибки:
Несколько SPF‑записей на домене (по RFC должна быть одна — иначе считается невалидной)
Превышен лимит в 10 DNS‑lookup'ов (включения через
include:цепляются по цепочке)Использован
+allвместо~allили-all(разрешает отправку откуда угодно — бессмысленно)
Проверка: команда dig TXT yourdomain.com +short или сервис MXToolbox SPF Check.
DKIM (RFC 6376)
Цифровая подпись письма приватным ключом, публичный ключ публикуется в DNS как TXT‑запись. Каждый ESP / SMTP‑провайдер требует своего селектора и своего ключа:
sg._domainkey.yourdomain.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
Селектор sg — пример для SendGrid; UniSender Go использует unione, Mailgun — k1, Postmark — pm.
Типичные ошибки:
DNS‑запись скопирована с переносом строки или лишними пробелами (DKIM‑валидация падает)
DKIM настроен, но платформа подписывает другим селектором (рассинхрон)
Длина ключа 1024 бит вместо 2048 — Gmail и Yahoo с 2024 года требуют 2048
Проверка: отправить тестовое письмо себе на Gmail, открыть «Show original», искать dkim=pass в Authentication‑Results.
DMARC (RFC 7489)
Политика, которая говорит почтовому провайдеру «если SPF или DKIM не прошли — что делать». Минимальная запись:
_dmarc.yourdomain.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com"
Где p=none — режим мониторинга, фильтр пропускает письма, но шлёт вам отчёты. По мере наработки доверия — переключают на p=quarantine или p=reject.
Без DMARC Gmail и Mail.ru с 2024 года всё агрессивнее режут отправителей с массовым outbound (Yahoo, Google требования к sender'ам отправляющим 5000+ писем/день).
Authentication‑Results: что должно быть в полученном письме
В заголовке Authentication-Results принимающего сервера. Открыть в Gmail через «Show original» → искать строку:
Authentication-Results: mx.google.com; dkim=pass header.i=@yourdomain.com header.s=sg; spf=pass (google.com: domain of bounces+12345@em.yourdomain.com designates 167.89.66.123 as permitted sender); dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=yourdomain.com
Все три должны быть pass. Если хотя бы один fail или none — Mail.ru почти гарантированно отправит в спам, Яндекс — с высокой вероятностью, Gmail в Promotions.
Это и есть та информация, которую low‑code‑платформа не отдаёт и не показывает. Чтобы её увидеть, нужно либо открывать каждое письмо руками, либо собирать через сторонний инструмент — об этом ниже.
Inbox placement как наблюдаемый параметр
Поскольку SMTP не возвращает информацию о размещении, для отслеживания доставки нужен out‑of‑band‑канал: набор тестовых ящиков на ключевых провайдерах, через которые видно, куда легло письмо.
Это называется seed network / inbox placement testing. Принцип:
Сервис предоставляет N реальных почтовых адресов на Mail.ru, Яндекс, Gmail, Outlook, корпоративных доменах
Вы шлёте на эти адреса ту же отправку, что и боевую
Сервис проверяет каждый ящик и возвращает структурированный отчёт: куда легло, что показал Authentication‑Results, какие маркеры спама нашёл фильтр
Это единственный способ получить наблюдаемый сигнал о deliverability без помощи самих почтовых провайдеров (которые такой информации наружу не дают).
Встраивание мониторинга в low‑code pipeline
Архитектурно правильное решение — относиться к inbox‑проверке как к стандартному наблюдаемому параметру в pipeline отправки. В коде это выглядит так:
import requests def send_with_monitoring(recipient, subject, body): # 1. Отправляем боевое письмо smtp_send(recipient, subject, body) # 2. Параллельно отправляем на seed network seed_addresses = get_seed_network() # из API сервиса for seed in seed_addresses: smtp_send(seed, subject, body) # 3. Через 30 секунд — запрашиваем отчёт test_id = trigger_placement_check(seed_addresses) # 4. Если spam_rate выше порога — алерт return test_id # дальше асинхронно
Для n8n это конфигурируется как пара нод: Send Email → HTTP Request (вызов API проверки) → IF (порог) → Slack notification (если плохо).
Для Make / Albato — аналогично, через HTTP‑модуль в сценарии.
Для Bubble — через API Connector plugin, добавляется backend workflow.
Для AppMaster — через REST‑модуль с настроенным HTTP‑вызовом.
Для ELMA365 — через скрипт уведомления, который дополнительно дёргает webhook проверки.
То есть API проверки deliverability становится частью наблюдаемости вашего low‑code‑приложения, на одном уровне с метриками выполнения, ошибками, временем отклика.
Пример проверки placement через REST API
Любой inbox placement checker предоставляет REST. На примере LDM check — нашей инфраструктуры, которую мы используем сами и опубликовали как MCP‑сервер в awesome-mcp-servers:
# 1. Получить адреса seed network curl -X GET https://check.live-direct-marketing.online/api/v1/seed \ -H "Authorization: Bearer $TOKEN" # Response: # { # "test_id": "abc-123", # "addresses": [ # "seed1@mail.ru", # "seed2@yandex.ru", # "seed3@gmail.com", # ... # ] # } # 2. Отправить туда боевое письмо (через ваш SMTP) # ... отправка через smtp.your-esp.com ... # 3. Запросить отчёт через 30-60 секунд curl -X GET https://check.live-direct-marketing.online/api/v1/report/abc-123 \ -H "Authorization: Bearer $TOKEN" # Response: # { # "test_id": "abc-123", # "placement": { # "mail.ru": {"inbox": 0, "spam": 3, "missing": 0}, # "yandex.ru": {"inbox": 2, "spam": 1, "missing": 0}, # "gmail.com": {"inbox": 1, "promo": 2, "spam": 0}, # ... # }, # "authentication": { # "spf": "pass", # "dkim": "fail", // <-- проблема # "dmarc": "fail" # }, # "issues": ["DKIM signature invalid for selector 'sg'"] # }
В этом примере диагноз очевиден: DKIM‑подпись не валидируется, поэтому Mail.ru стабильно режет в спам. Нужно проверить DNS‑запись sg._domainkey.yourdomain.com.
Что меняется с появлением MCP
Model Context Protocol (Anthropic) и A2A (Google) дают возможность сделать inbox check tool'ом, который вызывают AI‑агенты внутри своих pipeline'ов. Если у вас в low‑code‑агент входит шаг отправки email — вы добавляете MCP‑вызов проверки placement как один из tools модели:
# Tool schema для MCP-агента { "name": "check_inbox_placement", "description": "Check where email landed: inbox, spam, or promo across providers", "input_schema": { "type": "object", "properties": { "test_id": {"type": "string"} } } }
Агент сам после отправки вызывает этот tool, читает placement, принимает решение продолжать или менять стратегию. Это превращает deliverability из ручного процесса в наблюдаемый компонент архитектуры.
Чек‑лист для low‑code‑разработчика
DNS‑аутентификация на вашем sender‑домене:
SPF включает все ESP, через которые шлёт ваша платформа
DKIM настроен для каждого ESP с правильным селектором, ключ 2048 бит
DMARC хотя бы в
p=noneдля мониторинга
Sender‑домен — ваш собственный, не дефолтный поддомен платформы (
@bubbleapps.io,@n8n.cloud, и так далее)Аутентификация валидируется реально — проверка через отправку себе и чтение Authentication‑Results, не «настроил и забыл»
Inbox placement замеряется регулярно — через seed network, как часть pipeline или хотя бы по расписанию
Webhook на падение placement — алерт в Slack/Telegram при росте spam rate
Прогрев домена под нагрузку — не запускать сразу 1000 писем в день с домена, который раньше молчал
Bounce и complaint feedback — обрабатывать FBL от провайдеров, чистить базу
Заключение
Low‑code и zero‑code — это правильная абстракция для большинства задач разработки. Но email deliverability — это слой, который остаётся вне абстракции, потому что зависит от внешних факторов: DNS, репутации, поведения получателей. Платформа не может его «решить» вместо вас — но может (и должна) дать наблюдаемость.
На практике это значит: при выборе платформы и при проектировании уведомлений нужно явно закладывать слой мониторинга deliverability, как часть наблюдаемости системы — на уровне с метриками выполнения и логированием ошибок.
Мы у себя в LDM сделали check.live‑direct‑marketing.online как открытый инструмент с бесплатным базовым уровнем, REST API, MCP‑сервером в awesome-mcp-servers и A2A agent card — чтобы любая low‑code или агентская система могла встроить проверку placement в свой workflow за 15 минут.
Альтернативы — GlockApps, Mailgun Inbox Placement, MXToolbox Deliverability. Российской специфики (полное покрытие Mail.ru, Я.Почты, Я.360, корпоративных доменов на Я.360 и Exchange) у западных инструментов меньше — это и было главной причиной, почему мы строили своё.
Полезные ссылки и спецификации:
RFC 7208 (SPF), RFC 6376 (DKIM), RFC 7489 (DMARC)
Google Postmaster Tools — постмастер для отправителей через Gmail
Postoffice от Яндекса — аналог для Яндекс.Почты
Mail.ru для администраторов — собственный postmaster Mail.ru
Apple Mail Privacy Protection (Apple Developer documentation)
MCP specification (modelcontextprotocol.io)
A2A protocol specification