Email-рассылки
Подготовка, проверка, планирование и управление email-рассылкой, трекинг и режим приватности, входящие ответы и контракт вебхуков провайдера.
На этой странице
Email-рассылка отправляет одну опубликованную версию контента аудитории, давшей согласие, с вашего подтверждённого домена.
Что нужно до первой рассылки
Нужны две вещи: тариф с email-каналом и подтверждённый домен отправки. Проверять их стоит именно в таком порядке.
Тариф с email-каналом
Email относится к конструктору ботов, а в линейке конструктора четыре тарифа:
- «Старт»: бесплатный, email в него не входит;
- «Про», «Бизнес» и «Enterprise»: платные, email входит в каждый.
Проверяйте названия тарифов: «Старт» бесплатный, а младший платный тариф называется «Про».
Ни один тариф линейки «Коммуникации с клиентами» email не даёт: ни «Общение», ни «Поддержка», ни «Маркетинг», ни «Маркетинг Эксперт». Пункт «Кампании» у двух последних означает проактивные сообщения и попапы в виджете, писем он не включает. Бесплатное включение конструктора вместе с платным тарифом CE также не даёт email, поскольку это тариф «Старт».
На тарифе без email-канала закрыт весь email-раздел: домены отправки, входящие маршруты, рассылки и их статистика. Любой запрос к ним отвечает 402 и называет недостающую возможность (email). Тариф стоит проверить до правки DNS: без email-канала домен добавить не получится, и настройка SPF, DKIM и DMARC пройдёт впустую. См. Тарифы.
Подтверждённый домен отправки
Пока домен не подтверждён, письма не отправляются вообще. Как его подключить, описано в статье Email с вашего домена.
Когда оба условия выполнены, откройте раздел Email и перейдите по ссылке Email-рассылки.
Редактор
Редактор рассылки состоит из четырёх шагов.
Письмо и отправитель. Название рассылки (до 160 символов), домен отправки, имя отправителя, адрес для ответа, тема (до 255 символов) и прехедер (до 500 символов). Адрес для ответа указывается «голым», например hello@example.com, без отображаемого имени. Переводы строки в имени отправителя, адресе для ответа, теме и прехедере запрещены: через них возможна подмена заголовков письма.
Контент и предпросмотр. Выберите опубликованную версию email-контента или создайте её из шаблона. Рассылка сохраняет идентификатор документа вместе с точным номером версии, поэтому последующая публикация документа не изменит уже запланированную рассылку.
Аудитория и эксперимент. Либо все email-подписчики бота, либо один готовый сегмент. При желании подключите A/B-эксперимент: при планировании рассылка зафиксирует версию эксперимента и будет отчитываться по этому снимку.
Расписание и приватность. Время отправки, режим часового пояса, писем в минуту (от 1 до 10 000) и переключатель сбора открытий. Время отправки указывать необязательно: рассылка без него стартует сразу при запуске.
Режимов часового пояса два. По времени рассылки все получают письмо в один абсолютный момент, посчитанный в часовом поясе рассылки. По местному времени получателя у каждого на часах одно и то же время в его собственном поясе.
Список поясов фиксированный: Москва, Белград, Лондон, Берлин, Дубай, Алматы, Тбилиси, Ереван, Ташкент, Бангкок, Токио, Нью-Йорк, Лос-Анджелес, UTC.
Перевод часов обрабатывается явно:
- редактор не принимает время отправки, которого в этот день не существует в часовом поясе рассылки, и пишет об этом под полем;
- в режиме местного времени получатель, у которого это время на часах в тот день не наступает, попадает в проверку с кодом
nonexistent_local_time, и запуск заблокирован, пока время не изменят; - если время на часах повторяется дважды, для всех берётся более ранний момент.
В режиме местного времени человек без пригодного часового пояса исключается из рассылки, поэтому письмо в произвольный час ему не уйдёт.
Проверка получателей до отправки
Кнопка Проверить получателей ничего не отправляет. Она собирает аудиторию по текущему черновику и правилам согласия и отвечает, сколько человек получит рассылку, сколько исключено и почему, а также какие в контенте ошибки и предупреждения. Коды в ответе совпадают с кодами в интерфейсе.
Адрес попадает в исключённые, если:
- его подписка не в состоянии «подписан», причиной тогда указано само состояние:
unsubscribed,bouncedилиcomplained; - адрес пуст или непригоден (
invalid_email); - такой же нормализованный адрес уже есть в этой рассылке (
duplicate); - включён режим местного времени, а у человека нет часового пояса (
missing_timezone), он не распознан (invalid_timezone) либо такого местного времени в этот день не существует (nonexistent_local_time); - согласие было отозвано между подготовкой списка и попыткой отправки (
no_consent).
Запуск блокируют именно ошибки:
domain_not_verified: домен отправки не подтверждён;content_not_published: выбранной версии контента нет или она не опубликована;audience_not_ready: выбранного сегмента нет или он ещё не пересчитан;experiment_not_ready: связанный эксперимент не запущен либо его текущая версия распределяет не по подписчикам;scheduled_in_past: время отправки уже прошло;nonexistent_local_time: см. выше;empty_audience: рассылку никто не получит;- все ошибки контента из Студии контента, привязанные к полю
content_document_idи к проблемному блоку.
Предупреждения контента приходят там же, плюс одно собственное:
missing_plain_text: в контенте нет читаемого текста, только медиа и кнопки, поэтому текстовая часть письма окажется пустой.
Рассылку можно запустить только при нуле ошибок. Предупреждения запуск не блокируют.
Кнопка Отправить тестовое письмо отправляет контент рассылки на один уже подтверждённый и не отписавшийся email-контакт этого бота. Строки получателей рассылки при этом не затрагиваются, а произвольный адрес ввести нельзя, поэтому тест не может испортить запланированную отправку.
Запуск и управление
Запустить можно только рассылку в состоянии «Черновик». Запуск требует явного подтверждения и ревизии, которая сейчас на экране. При запуске платформа фиксирует версию контента, отправителя, аудиторию, расписание и версию эксперимента в неизменяемом снимке отправки. Для каждого подходящего адреса создаётся строка получателя.
После этого рассылку нельзя редактировать. Чтобы что-то изменить, нажмите Создать копию и запустите копию.
Статусы: Черновик, Запланирована, Отправляется, На паузе, Завершена, Отменена, Не удалась, В архиве. Из каких статусов доступны действия:
- Поставить на паузу: из «Запланирована» или «Отправляется».
- Продолжить: из «На паузе», обратно в «Запланирована».
- Отменить: из «Черновик», «Запланирована», «Отправляется» или «На паузе». Тем, кому ещё не отправили, письмо не уйдёт.
- В архив: из «Черновик», «Завершена», «Отменена» или «Не удалась».
Каждое действие управления тоже несёт ожидаемую ревизию, поэтому два оператора не могут незаметно перебить работу друг друга.
Сама отправка идёт с заданной скоростью писем в минуту, выполняется пачками с арендой задания и переживает перезапуск воркера. Получателя с временной ошибкой отправки повторяют с растущей задержкой: начиная с 15 секунд и не больше 15 минут. Если провайдер отправку принял, но её исход не подтверждён, получатель записывается со статусом «Статус неизвестен». Повтор в этом случае рисковал бы вторым письмом тому же человеку, поэтому его нет.
Трекинг, приватность и отписка
Для пикселя открытия, перехода и отписки используется подписанный токен вашей установки вида https://<ваш-хост>/e/t/<токен>. Токены подписаны HMAC, ограничены одним ботом, рассылкой и получателем и истекают через 90 дней после отправки. Ключ подписи выводится из секрета почтовых вебхуков установки, и без этого секрета рассылка не отправится вообще, так что письма с неотслеживаемыми ссылками не уходят.
- Для необязательного отслеживания открытий используется GIF 1×1. Если выключить «Собирать статистику открытий», пиксель просто не добавляется, а доставка, переходы, жалобы и отписки продолжают считаться. Открытия всегда занижены, объяснение есть в статье Email с вашего домена.
- Отслеживание переходов переписывает только кнопки-ссылки на
https://. Токен перехода несёт адрес назначения, и этот адрес обязан бытьhttps://-ссылкой с хостом и без встроенных учётных данных, поэтому перенаправить его в другое место нельзя. - Токены отписки не несут ни идентификатора ссылки, ни адреса перехода: по такому токену можно отписаться, но нельзя никуда перенаправить.
Недействительный, истёкший, чужой или неизвестный токен получает 404 без подробностей, поэтому по токену нельзя разведать существующие рассылки и получателей.
Отписка работает по RFC 8058 в один клик. GET показывает простую HTML-страницу подтверждения без JavaScript, а POST с единственным полем формы List-Unsubscribe=One-Click выполняет отписку. Повторная отписка тем же токеном считается успехом: почтовые клиенты предзагружают ссылки, а люди кликают дважды. Отказ записывается и в строку получателя, и в канонический учёт согласий одной транзакцией, поэтому ссылка не может отчитаться об успехе, оставив согласие активным.
Отчёт
В отчёте по рассылке отдельно показаны: Получатели, Исключены, Ожидают, Отправляются, Принято провайдером, Статус неизвестен, Доставлено, Открыто, Переходы, Возвраты, Жалобы, Отписки, Ошибки и Отменены. Переходы показываются по каждой ссылке, а получателей можно листать постранично со статусом и причиной исключения.
Атрибутированная выручка показывается отдельно по каждой модели атрибуции и каждой валюте и никогда не суммируется между ними: разные модели законно приписывают одну конверсию по-разному, а смешанная по валютам сумма не имеет смысла.
Ответы получателей
Входящий маршрут превращает адрес на подтверждённом домене в обращение в поддержку. Локальная часть адреса хранится только в виде необратимого хеша, поэтому сам адрес рядом с маршрутом не сохраняется.
Экрана для маршрутов в панели пока нет. Управляйте ими через API с токеном, у которого есть settings:read / settings:write:
curl -X POST "$BASE_URL/api/bots/$BOT_ID/email/inbound-routes" \
-H "Authorization: Bearer $PAT" -H "Content-Type: application/json" \
-d '{"domain":"mail.example.com","local_part":"support"}'
Локальная часть приводится к нижнему регистру и должна подходить под [a-z0-9][a-z0-9._+-]{0,62}. Домен уже должен быть подтверждён для этого бота, иначе ответ будет 422; повторный тот же адрес даст 409. Полный адрес возвращается один раз, при создании: в списке потом виден только домен, потому что локальная часть не хранится. Если в установке не настроен секрет почтовых вебхуков, ответ будет 503, и входящая почта выключена целиком.
Входящее письмо нормализуется до того, как попадёт в диалог:
- отправитель сопоставляется с подписчиком по нормализованному адресу;
In-Reply-ToиReferencesпродолжают существующую переписку, но только если она принадлежит тому же человеку;- цитируемая история вырезается из текста;
- исходное письмо ограничено 8 МиБ, извлечённый текст 256 КиБ, тема 255 символами, а
References32 записями; - сохраняется не больше 5 вложений размером не больше 1 МиБ каждое, по контентному ключу; исполняемые вложения (
.bat,.cmd,.com,.dll,.exe,.msi,.scrи MIME-типы исполняемых файлов) отклоняются; - письмо только в HTML сводится к тексту.
Письмо на неизвестный маршрут отклоняется с кодом 404. У этого есть цена, о которой лучше знать заранее: провайдер считает 404 неудачей доставки и будет повторять попытку часами, а потом отчитается о ней вам. Опечатка в адресе или маршрут, которого нет, оборачиваются часами повторов у провайдера.
Причина в том, как хранятся маршруты. Локальная часть лежит в виде хеша, посчитанного на секрете почтовых вебхуков установки, и пересчитать эти хеши при смене секрета нельзя, поэтому после ротации секрета ни один маршрут больше не находится. Ответ «принято» в такой ситуации сообщал бы провайдеру об успешной доставке, и входящая почта исчезала бы совсем тихо: ничего не повторялось бы и никто об этом не узнал. Отказ с 404 делает поломку видимой.
Практический вывод: если после смены секрета почтовых вебхуков вы видите повторы и жалобы провайдера на входящие, заведите входящие маршруты заново, старые уже не сработают.
Контракт провайдера
Если вы держите собственную установку или пишете адаптер к почтовому провайдеру, вот два публичных эндпоинта, с которыми он общается. Оба проверяют подпись HMAC-SHA256 по сырому телу запроса, в hex, в заголовке X-Signature, на настроенном секрете вебхуков почты. Запрос без подписи отклоняется с 401, и так же отклоняется любой запрос, если секрет не настроен: эндпоинт закрывается по умолчанию.
События доставки и вовлечения
POST /esp/{provider}/webhook, тело до 1 МиБ:
{
"provider_id": "prv_00000000-0000-0000-0000-000000000000",
"event": "delivered",
"bounce_class": "hard",
"url": "https://example.com/offer",
"event_id": "evt_0000000001",
"tag": "email-campaign:11111111-1111-1111-1111-111111111111:22222222-2222-2222-2222-222222222222"
}
Это собственный обобщённый контракт платформы, а не формат какого-то одного провайдера. Ваш адаптер переводит callback провайдера в него.
eventпринимает значенияdelivered,opened,clicked,bounced,complained,unsubscribed. Незнакомое значение сохраняется для разбора и ничего не меняет.bounce_classравенhardилиsoftи имеет смысл только дляbounced.tagсодержит стабильные метаданные, переданные при отправке, в видеemail-campaign:<id рассылки>:<id подписчика>. Он позволяет найти получателя, если callback пришёл раньше, чем сохранился идентификатор провайдера.
Как события отображаются в состояния:
delivered: письмо и получатель рассылки переходят в «Доставлено»;bouncedсbounce_class: hard: письмо «Возврат», адрес исключается, получатель «Возврат»;bouncedсbounce_class: soft: записывается только событие. Мягкий возврат говорит о конкретной попытке, а не об адресе, поэтому он никого не исключает и не меняет состояние получателя;complained: записывается жалоба, адрес закрывается навсегда;unsubscribed: согласие отзывается, получатель «Отписан»;openedиclicked: записываются как события, состояние не меняется.
Callback, пришедший не по порядку, не может откатить конечное состояние назад.
Идемпотентность строится на event_id, если провайдер его присылает, иначе на SHA-256 сырого тела. Проверка, эффекты и отметка о приёме пишутся одной транзакцией, сериализованной по паре «бот и ключ», поэтому два одновременных дубля одного события не применятся дважды.
Коды ответа подсказывают адаптеру, что делать:
200: событие понято. Сюда же попадают намеренно проигнорированные события: дубль или неизвестный идентификатор письма, которое эта установка не отправляла. Повтор ничего не изменит.400: некорректное тело или отсутствуетprovider_idлибоevent.401: подпись неверна или отсутствует.413: тело больше лимита.500: временный сбой на нашей стороне. Повторять стоит только этот класс.
Входящая почта
POST /esp/{provider}/inbound, тело до 12 МиБ:
{
"event_id": "in_0000000001",
"raw_mime": "<base64 исходного MIME-письма>"
}
Раскодированный MIME не должен превышать 8 МиБ. Ответы:
200с{"created": true|false}: письмо принято;falseозначает дубль уже записанногоevent_id.404: адрес получателя не совпал ни с одним маршрутом. Повторять эту попытку стоит: маршрут может появиться, а безответная потеря входящей почты хуже лишних повторов. См. выше, «Письмо на неизвестный маршрут».400: конверт или MIME не разобрались.401: подпись не сошлась.413: тело запроса больше 12 МиБ.
Ни один из эндпоинтов не возвращает учётные данные провайдера, адреса получателей, которых не было в запросе, и локальную часть входящего маршрута. Ошибки трекинга и отписки отвечают 404, не сообщая, какая именно проверка не прошла.
Что делать, если
- Любой экран или запрос email отвечает
402: на вашем тарифе нет возможностиemail. Это не сбой настройки: домены отправки, входящие маршруты, рассылки и их статистика закрыты целиком, пока тариф не сменён на «Про», «Бизнес» или «Enterprise». Записи в DNS тут ни при чём. - Ничего не отправляется, а на карточке домена предупреждение: домен отправки ещё не подтверждён. См. Email с вашего домена.
- «Рассылку пока нельзя запустить»: откройте проверку получателей и устраните все ошибки; одни предупреждения запуск не блокируют.
- Много получателей исключено по причине
missing_timezone: рассылка идёт по местному времени, а у людей нет часового пояса. Переключитесь на время рассылки или заполните поле профиля. - Время отправки не принимается или проверка отдаёт
nonexistent_local_time: такого времени на часах в этот день не существует из-за перевода часов. Выберите другое время. - Открытий подозрительно мало: такой результат ожидаем, точнее посчитать их нельзя. Сравнивайте рассылки по переходам.
- События провайдера не приходят: проверьте, что адаптер подписывает ровно сырое тело и что секрет вебхука совпадает; неподписанный callback получает
401. - Провайдер жалуется на повторы входящих писем: адрес, на который пишут, не соответствует ни одному маршруту. Проверьте список маршрутов, а если недавно менялся секрет почтовых вебхуков, заведите маршруты заново.
Что дальше
- Студия контента: подготовка и публикация контента письма.
- Email с вашего домена: DKIM, SPF, DMARC, отписки и возвраты.
- Рассылки: отправка одного контента в Telegram, VK, WhatsApp, веб-чат или email.
- Эксперименты и атрибуция: A/B-эксперименты и выручка.