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 отправки. В коде это выглядит так:
python
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:
bash
# 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 модели:
python
# 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
