События и конверсии: денежный слой воронки
Клик - это расход, пока событие не докажет, что он окупился. В Leadgram каждая конверсия - старт бота, регистрация, депозит - это событие, привязанное к конкретному клику, и именно эта связка кормит всё, что происходит дальше: выручку в Отчётах, постбэки в партнёрские трекеры, серверные конверсии, которые уходят обратно в Meta и Google, и пуш подписчику, который сконвертился - если это прописано в вашем Флоу. Наладите события правильно - и трекер начнёт показывать правду о вашем спенде.
Типы событий
- Воронка -
click,land,bot_start,channel_join,join_request,first_dm,miniapp_launch. Показывают, как пользователь движется по вашей Telegram-воронке. - Конверсии -
lead,registration,deposit,ftd,purchase. За них платит рекламодатель. - Кастомные -
custom_1-custom_8под любую специфику оффера.
Большинство конверсионных событий также двигают статус клика на странице Клики: Клик → Лендинг → Старт → Регистрация → Лид → Депозит → FTD. Статус двигается только вперёд - если registration придёт уже после ftd, клик назад не откатится. Исключение - purchase: он биллится и попадает в отчётность как любая другая конверсия, но статус клика не трогает. Так же ведут себя channel_join и события custom_* - все три записываются в базу, просто не участвуют в лестнице статусов воронки.
Как события попадают в систему
- S2S / API. Ваш бэкенд (или постбэк-скрипт рекламодателя) шлёт
POST /api/eventsсclickId, типом события и опциональнымиpayoutиnonce. API-ключ для внешних инструментов вроде Keitaro или собственных скриптов создаётся в Настройках → API ключи. Забрать события обратно можно черезGET /api/events(с пагинацией, с фильтром поtype) - удобно, когда нужно сверить, что реально сработало, с вашими собственными записями. - Флоу. Поставьте узел «Триггер события» в нужный шаг Флоу - событие сработает автоматически, когда подписчик до него дойдёт. Регистрации и депозиты прямо из Telegram-воронки, без единой строчки кода.
- Сам Leadgram. Часть типов трекер пишет сам - из апдейтов Telegram, которые ваш бот и так получает. Следующий раздел говорит, какие именно, и какие останутся пустыми, пока вы их не пришлёте.
Дедупликация детерминированная: повторная отправка того же clickId + типа без nonce считается ретраем той же конверсии и никогда не создаёт вторую строку, второе списание или дубль Purchase в Meta. Настоящая повторная конверсия (второй депозит с того же клика) обязана идти с уникальным nonce.
Какие типы Leadgram пишет сам
То, что тип есть в списке узла «Триггер события», смаплен на событие Meta и принимается API, ещё не значит, что его трекают за вас. Групп три, и разница решает, ждать вам цифру или присылать её самому:
- Пишет Leadgram -
bot_start,channel_join,join_request,purchase,subscription_renewedиsubscription_cancelledберутся из апдейтов Telegram, которые ваш бот и так получает;miniapp_launchпишется на сервере, но только после того, как сниппет из гайда Mini Apps дёрнет эндпоинт запуска - сам Telegram о запуске Mini App никому не сообщает. Подключите бота или канал - и типы из апдейтов пойдут сами, с одним условием: событие записывается, только если апдейт удалось связать с кликом. Что связать не удалось, событием не становится вовсе и попадает в «Дропы без атрибуции» на странице Доставка конверсий. Сильнее всего это бьёт поbot_start: кто открыл бота по юзернейму, а не по вашей трекинговой ссылке, старта не создаёт. - Только приём извне:
click,land- редирект создаёт строку клика на странице Клики, а не событие, и за вашим лендингом никто не наблюдает. Поэтому статус клика никогда не дойдёт до Лендинга, пока вы сами не пришлёте событиеland. - Только приём извне:
first_dm- вебхуки Bot API покрывают только чаты с вашим ботом; чтобы поймать первое сообщение в личку обычного аккаунта, нужна MTProto-сессия пользователя, а её Leadgram не держит. Отправляйте событие узлом «Триггер события» или вPOST /api/events. - Присылаете вы -
lead,registration,deposit,ftdиcustom_1-custom_8. Только ваш бэкенд знает, когда рекламодатель подтвердил конверсию.
Присылать тип из первой группы самому можно, и иногда это правильно (например, ваш собственный биллинг репортит purchase), но рядом с автоматическим появится второе событие. Исключение - bot_start: вебхук, узел «Триггер события» и API сходятся в одно событие на пользователя, поэтому повторно отправленный старт ничего не удвоит. Сходятся они по паре «бот + пользователь Telegram», поэтому для этого типа API требует пользователя - передайте telegram_user_id, tg_user_id, from.id или user.id внутри payload. bot_start без него отклоняется с кодом 422 (bot_start_missing_telegram_user_id), а не записывается вторым стартом, который ушёл бы в Meta вторым Lead.
Чем на самом деле оборачивается задвоенный старт. Не деньгами: вы платите один раз за человека в рамках рабочего пространства - списание происходит на его первом платном событии, а Telegram-аккаунт узнаётся без срока давности, - поэтому второй bot_start по уже оплаченному человеку закрывается как free и баланса не касается. Бьёт он дальше по цепочке. У дубля другой event_id, поэтому собственная дедупликация Meta свести его с первым не может, и оптимизатор кампании узнаёт, что один человек сконвертился дважды, - за этот урок вы потом платите на каждом аукционе. На ту же величину разъезжаются цифры воронки в Отчётах. Ради этого и нужны правила пары ниже, а не ради второго счёта.
У этой пары есть два условия, и лучше назвать их прямо:
- По API бота должно быть чем назвать. Передайте
bot_username(@имя) илиbot_idвнутриpayload- либо назовите такойclickId, у клика которого бот есть: клик несёт бота своей кампании, а у клика из обычной редирект-кампании бота нет, как и у клика, чьего бота удалили. Вызов, который не называет бота ни тем, ни другим способом, пару назвать не может, поэтому записывается отдельным событием, а не сходится с общим. Явно названный бот выручает и в случае нескольких ботов: бот клика - это лишь запасная догадка, и она неверна, когда человек запустил другого вашего бота. - Узел «Триггер события» попадает в эту пару только для тех проходов Флоу, где записан пользователь Telegram. Проходы, начатые до появления этой механики, его не записали, а восстановить задним числом нельзя. Для них узел по
bot_startне создаёт ничего, вместо того чтобы гадать, - этот старт всё равно уже записал вебхук. Молчит узел и по второй причине: проходу Флоу без клика старт не к чему привязать, поэтому вместо события, которое всё равно никуда бы не уехало, потеря попадает в «Дропы без атрибуции» на странице Доставка конверсий.
«Только приём извне» - это про код как он есть, а не про фичу в пути. Если first_dm никто не шлёт, строки first_dm не появится никогда: то, что тип можно выбрать в узле и он смаплен в Meta Contact, автоматическим его не делает.
Ретаргетинг: второй клик того же человека
Повторный клик по объявлению - обычное дело: тот же человек кликает снова, получает новую строку клика и снова стартует бота. bot_start считается один раз на бота и пользователя Telegram, навсегда, поэтому второй старт не создаёт ни нового события, ни нового списания, ни второго Lead в Meta. Это осознанный выбор: иначе на одного человека придётся два Lead, а это портит тот самый оптимизатор, обучение которого вы оплачиваете.
Цена этого выбора видна ровно в одном месте: новый клик остаётся в статусе «Клик» на странице Клики, хотя человек в бота зашёл. Двигать его нечем - на уровне событий ничего нового не произошло. Когда меряете ретаргетинговую кампанию, считайте старты по событиям, а не по статусам кликов.
Биллинг-гейт
Записать событие и доставить его дальше - две разные вещи. У каждой строки события есть billing_status: пока идёт списание, он pending, затем становится charged или free. Отправка в CAPI, постбэки и пуш подписчику по событию срабатывают только после того, как этот статус разрешится в charged или free - у приостановленной организации или при пустом балансе строка остаётся blocked (при сбое списания - error), и событие лежит в базе, так и не дойдя ни до Meta, ни до Google, ни до вашего постбэк-эндпоинта, ни до подписчика.
Если конверсия появилась в списке событий, а на другом конце ничего не сработало - сначала проверьте биллинг, а не интеграцию. Событие в статусе blocked не сломано, оно ведёт себя ровно так, как задумано.
Поле payout
Передавайте payout (USD, до двух знаков после запятой) с каждой платящей конверсией. Оно попадает в два места:
- Выручка в Отчётах - колонка выручки складывается из payout всех подтверждённых событий.
- Google Ads - payout становится
conversionValueсерверной конверсии, и Smart Bidding оптимизируется на реальные деньги.
Постбэки payout не передают. Партнёрским трекерам доступны плейсхолдеры {click_id}, {event_type}, sub-цепочка и нативные click id рекламных площадок - полный список смотрите в Постбэках. Если вашему трекеру нужна сумма конверсии, передавайте её через собственную интеграцию.
Что значит колонка CAPI
В таблице «Последние события» на Дашборде у каждого события есть статус CAPI: Отправлено означает, что все рекламные площадки, привязанные к кампании, приняли конверсию; В ожидании означает, что хотя бы одна доставка ещё в очереди или падает. Детали по площадкам - попытки, последняя ошибка, повторная отправка в один клик - на странице Доставка конверсий.
Безопасное тест-событие
На странице Facebook у каждого CAPI-аккаунта Meta есть кнопка «Отправить тест-событие». Она шлёт синтетический Purchase с вашим кодом Test Events из Meta Events Manager, поэтому событие появляется во вкладке Test Events и никогда не затрагивает оптимизацию рекламы, атрибуцию или списания. Это самый быстрый способ убедиться, что пиксель и токен работают, ещё до того, как потрачен первый доллар. Без кода кнопка не сработает - событие без кода Meta засчитала бы как настоящее.
Частые грабли
- Пропустить
nonceна повторной конверсии - второй депозит молча посчитается ретраем и будет отброшен. - Отправлять события без
payout- выручка в Отчётах останется нулевой, а Google получит конверсии без ценности. - Отправить
registrationдля клика, который уже дошёл доftd, и ждать, что статус изменится - не изменится, так задумано. - Ждать, что
purchaseсдвинет статус клика по воронке - никогда не сдвинет, хотя биллится как любая другая конверсия. - Читать «В ожидании» в колонке CAPI как баг - сначала загляните в Доставку конверсий, там обычно названа конкретная ошибка площадки.
- Считать, что записанное событие уже доставлено - статусы биллинга
blocked,errorиpendingозначают, что оно так и не дошло ни до CAPI, ни до постбэков, ни до пушей. - Оценивать ретаргетинговую кампанию по статусам кликов - повторный клик человека, который уже стартовал бота, так и останется в статусе «Клик», и это задумано: старт считается один раз на человека.
- Ждать, что
miniapp_launchпоявится сам - Telegram апдейта о запуске не шлёт, и цифра будет нулевой, пока не заработает сниппет из гайда Mini Apps.