Кампании
Многошаговые автоматические путешествия подписчика: неизменяемые версии, триггеры входа, узлы графа, предпроверка, публикация, отчёт по версии и трейс одного путешествия.
На этой странице
Кампания ведёт подписчика по нескольким шагам: после входа по триггеру следует последовательность узлов (сообщения, задержки, условия, эксперименты), которая может растягиваться на дни и недели. Это не то же самое, что рассылка или email-рассылка: у в рассылке один документ контента и одна волна отправки, а кампания строится как граф с ветвлениями, который читает и меняет данные подписчика на каждом шаге.
Версии и черновик
У кампании в любой момент ровно один редактируемый черновик (draft) и,
если она хоть раз публиковалась, история immutable-версий: draft →
published → retired. Черновик содержит триггер, аудиторию, настройки и
граф узлов. Правка черновика идёт через PUT /draft с expected_revision:
если кто-то другой уже сохранил черновик, запрос отклоняется как конфликт, а
не тихо перезатирает чужую правку.
Публикация (POST /publish) замораживает текущий черновик как новую
опубликованную версию и сразу открывает следующий черновик: его копию.
Подписчик, вошедший в кампанию во время действия версии N, доходит по её
пути до конца на версии N, даже если позже опубликуют версию N+1: триггер,
аудиторию, настройки и граф уже вошедшего путешествия версия N+1 не меняет.
Изменить граф узлов можно только после остановки кампании. При статусе «Выполняется» или «На паузе» сохранение отклоняется: подписчик может находиться на узле с этим идентификатором, поэтому менять граф во время его путешествия нельзя.
Версию можно клонировать: содержимое любого черновика, опубликованной или архивной версии заменит текущий черновик. Остановленную кампанию можно архивировать, убрав из активного списка без удаления истории.
Триггеры входа
- Вручную: без настроек; кнопка «Отправить тест себе» в редакторе вызывает тот же путь и сразу выполняет входной узел, не дожидаясь фонового обхода.
- Событие сайта: то же событие клиентского SDK/виджета, что и в реакциях, с тем же редактором условий.
- По расписанию: один раз в момент
atлибо повторяясь. Повторяющееся расписание задаёт локальное время суток (ЧЧ:MM) в явном IANA-часовом поясе: значение «Local» не принимается: опционально фильтр по дням недели и обязательныеstart_at/end_atне длиннее двух лет: у повторяющегося расписания обязательно есть конец, иначе забытая кампания сканировала бы аудиторию вечно. Момента, которого не существует из-за перевода часов весной, по умолчанию просто нет в расписании; политика «следующий существующий момент» переносит его на конец провала вместо пропуска. - Изменение метки: добавление или снятие одной конкретной метки. Эти события запускают разные путешествия с разным содержанием.
- Изменение свойства: переход одобренного свойства профиля из одного состояния в другое. Условия «было» и «стало» независимы и оба необязательны; повторное сохранение того же значения переходом не считается и вход не вызывает.
- Вход в сегмент: переход участия в готовом сегменте из «не входит» в «входит». Обычный пересчёт, который лишь подтверждает уже имеющееся участие, входом не считается.
Узлы графа
Граф состоит из узлов и рёбер между ними; у рёбра есть метка ветки (например, yes/
no). Ровно один узел без входящих рёбер: точка входа; терминальные узлы
(«Цель», «Выход») не имеют исходящих рёбер, и от каждого узла должен быть путь
хотя бы до одного терминального узла: граф с недостижимым узлом или узлом без
выхода к финалу не сохранится. У узла может быть максимум 32 КиБ конфигурации;
в кампании не больше 200 узлов и 400 рёбер.
- Сообщение: блоки текста/фото/файла/задержки, выполняются как обычная реакция тому же подписчику. Блоки ИИ, вложенная реакция, «ожидаемый ответ» и сохранение параметров с побочным эффектом здесь не поддерживаются - повторный запуск узла после сбоя должен быть безопасным.
- Контент: в отличие от «Сообщения», отправляет конкретную опубликованную и зафиксированную по версии документ на явно названный канал (Telegram, VK, WhatsApp или веб-чат) и никогда не переключается на другой канал сам: недоступность адресата либо уходит по отдельной ветке «когда канал недоступен», если она проведена, либо узел явно проваливается.
- Задержка: ждёт заданное число секунд (не больше 180 дней).
- Ожидание события: ждёт клиентское событие по имени (до 64 символов, без
зарезервированного префикса
$) с таймаутом до 180 дней; у узла ровно две ветки: основная (событие пришло) иtimeout. - Условие: ветвится
yes/noпо параметрам подписчика, периодам времени, давности последнего визита или числу сообщений: тот же словарь условий, что у реакций. - Разделение: весовое A/B-ветвление: подписчик детерминированно попадает в одну и ту же ветку по хэшу узла и своего идентификатора, и это не меняется при повторной проверке или перезапуске.
- Эксперимент: ветвится по варианту общего эксперимента с закреплёнными идентификатором и версией; от двух до шестнадцати вариантов, и каждый объявленный вариант: обязательная ветка: невыведенный вариант молча обрывал бы путешествие тем, кому эксперимент его назначил.
- Доступность канала: ветвится
yes/noпо тому, можно ли именно сейчас достучаться до подписчика на явно названном канале (email и телефон не подходят: это не канал доставки). Существует, чтобы автор явно решал вопрос резервного канала, а не полагался на то, что отправка сама переключится. - Действие: смена меток (в том числе временных, с
ttl_days); изменение прав участника в явно указанном чате (change_rights: забанить, разбанить, исключить, одобрить заявку, заглушить, снять заглушение, ограничить; полеchat_idобязательно, потому что шаг кампании выполняется без чата: так строится «через N дней после метки → исключить из закрытого чата», то есть узел Задержка и следом Действие → Изменить права → Исключить;chat_idпишется обычным числом, без пробелов, плюса и ведущих нулей, а какие именно операции доступны, зависит от канала: см. Изменение прав по каналам); снятие параметров (установка, добавление и инкремент здесь не поддерживаются: тот же принцип безопасного повтора, что у «Сообщения»); синхронный веб-запрос (без фонового режима, без вложенных реакций на успех/ошибку; заголовокIdempotency-Keyзарезервирован - платформа проставляет его сама и при повторе того же шага присылает то же значение, поэтому ваш эндпоинт может по нему отбрасывать дубли, а задать свой вы не можете); синхронизация с подключённой CRM; назначение диалога поддержки агенту или группе; отправка клиентского события (как вызовtrack()из виджета: увидят сегменты, воронки и подходящий триггер); запуск lead-бота. - Цель и Выход: терминальные узлы без настроек: первый: успешное завершение, второй: уход без успеха.
Изменение прав по каналам
Возможность забанить или заглушить участника зависит от конкретной площадки. Перед постановкой в очередь платформа проверяет, сможет ли канал подписчика выполнить именно эту операцию именно в этом чате, и если нет: шаг завершится ошибкой и путешествие останется на том же узле до следующей попытки. Ничего «наполовину выполненного» при этом не возникает.
- Telegram: доступны все восемь операций (забанить, разбанить, исключить,
одобрить заявку, отклонить заявку, заглушить, снять заглушение, ограничить)
в явно указанном в
chat_idчате: группе, супергруппе или канале, где бот администратор. - VK: сообщество модерирует только само себя. Доступны четыре операции:
забанить, разбанить, исключить, одобрить заявку, а
chat_idобязан быть равен идентификатору того самого подключённого сообщества (то же число, что показано у канала VK в разделе Каналы). Любое другое значение отклоняется: VK всё равно применил бы действие к подключённому сообществу, и граф говорил бы одно, а платформа делала другое. Заглушить, снять заглушение, ограничить и отклонить заявку в VK недоступны: у сообществ нет соответствующего API. - WhatsApp, Instagram Direct, Messenger, email и веб-виджет вовсе
не поддерживают управление правами участников: узел
change_rightsна таком канале всегда завершается ошибкой.
Предпроверка и публикация
POST /preflight проверяет форму текущего черновика (тот же граф-валидатор,
что и при каждом сохранении) и связи с другими сущностями: существуют ли
названные сегменты, документы контента, эксперименты: и ничего не отправляет.
Ответ: ready, номер версии, её контрольная сумма и список ошибок с кодом
(invalid_graph, invalid_reference) и текстом. Предпроверка не считает
размер аудитории, доступность каналов или согласия, поскольку они не входят в её
задачу.
POST /publish перепроверяет те же связи заново и в одной транзакции: клиент,
который пропустил предпроверку или у которого мир успел измениться, не
опубликует кампанию со ссылкой на удалённый сегмент или документ. Публикация
требует текущей ревизии черновика: устаревшая ревизия или уже
опубликованный черновик отвечают конфликтом без частичного результата.
Отчёт по версии и трейс путешествия
Отчёт (GET /report) считается по одной версии, а не по кампании в целом:
у версии N и версии N+1 разные счётчики, публикация новой версии не сдвигает
цифры старой. В отчёте: воронка путешествий (вошли, активны, ждут, на
повторной попытке, дошли, вышли, провалились) и по каждому узлу: вошли,
завершили, провалились. Отчёт зафиксирован (sealed), когда версия уже не
принимает новых вошедших и ни одно путешествие по ней не может сдвинуться -
такие цифры сохранены как есть и больше не пересчитываются; отчёт живой
опубликованной версии всегда пересчитывается заново.
Трейс одного путешествия (GET /journeys/{subscriberID}/{runNo}): это
ограниченный по числу событий журнал: вход в узел, сработавший эффект, уход в
ожидание, выход из ожидания, назначенная повторная попытка, отказ после
исчерпания попыток, завершение. В трейсе: идентификаторы, ветки, номера
попыток и коды ошибок, но никогда текст сообщения или ответ провайдера: это
аудит пройденного пути, а не копия того, что было отправлено. Флаг
truncated показывает, что путешествие превысило лимит событий и часть
записей не сохранилась. Отдельный список (GET /failures) показывает, кто
застрял и на каком узле, после того как раннер исчерпал попытки; застрявшее
путешествие можно перезапустить (POST /journeys/{subscriberID}/{runNo}/retry).
Тихие часы
У версии есть свободные настройки (settings), которые по умолчанию создаются
как {"allow_reentry": false, "timezone_mode": "bot", "quiet_hours": {"enabled": false}}.
Повторный вход (allow_reentry) задаётся отдельным действующим полем
кампании, а не настройками версии. Оно определяет, может ли подписчик войти
повторно. А вот
timezone_mode и quiet_hours внутри settings пока лишь
зарезервированы в конфигурации: раннер кампаний их не читает и не
применяет. Это отличает их от одноимённой функции Web Push,
где тихие часы действительно откладывают доставку. Не закладывайтесь на то,
что кампания сама подождёт «удобное» время: паузу нужно моделировать узлом
«Задержка» или условием по периоду времени.
Права
Личные токены и роли видят кампании через три отдельных scope: campaigns:read,
campaigns:write и campaigns:publish: публикация версии и перезапуск
застрявшего путешествия отдельно от обычного редактирования черновика. Все
три требуют право бота «Реакции»: без него раздел кампаний не виден и не
доступен ни на чтение, ни на запись.
Что дальше
- Рассылки: разовая отправка одного документа, без графа и без версий.
- Email-рассылки: похожий разовый сценарий для почты.
- Эксперименты и атрибуция: общий эксперимент, на который может ссылаться узел «Эксперимент».
- Люди (CRM): сегменты и метки для аудитории и триггеров.
- Студия контента: документы для узла «Контент».
- REST API и токены: маршруты кампаний и их scope.