Події та конверсії: грошовий шар воронки

Клік - це витрата, доки подія не підтвердить, що він окупився. У Leadgram кожна конверсія - старт бота, реєстрація, депозит - це подія, прив'язана до одного конкретного кліку. І саме цей зв'язок живить усе інше: дохід у Звітах, постбеки в партнерські трекери, серверні конверсії, які ви віддаєте назад у Meta й Google, і пуш підписнику, який конвертнувся, якщо у флоу для цього є вузол. Налаштуйте події правильно - і решта трекера почне казати вам правду про ваш спенд.

Типи подій

  • Події воронки - click, land, bot_start, channel_join, join_request, first_dm, miniapp_launch. Показують, як користувач рухається вашою Telegram-воронкою.
  • Конверсійні події - lead, registration, deposit, ftd, purchase. Це події, за які платить рекламодавець.
  • Кастомні події - custom_1custom_8 під усе, що специфічне для оферу.

Більшість конверсійних подій також просувають статус кліку на сторінці Кліки: Клік → Лендинг → Старт → Реєстрація → Лід → Депозит → FTD. Статус рухається лише вперед - пізня registration, що приходить після ftd, клік не відкотить. Виняток - purchase: вона тарифікується і потрапляє у звіти як будь-яка інша конверсія, але статусу кліку не торкається. Так само як channel_join і події custom_* - усі три записуються, просто не просувають кліки сходами воронки.

Як події потрапляють у систему

  1. S2S / API. Ваш бекенд (або постбек-скрипт рекламодавця) викликає POST /api/events із clickId, типом події (type) і опційно payout та nonce. Для зовнішніх інструментів на кшталт Keitaro чи власних скриптів створіть API-ключ у Налаштуваннях → API ключі. Щоб звірити, що реально спрацювало, з власними записами, витягуйте події назад через GET /api/events (з пагінацією, з фільтром за type).
  2. Флоу. Додайте вузол «Тригер події» у Флоу - і подія спрацює автоматично, щойно підписник дійде до цього кроку: реєстрації й депозити прямо з Telegram-воронки, без коду.
  3. Сам Leadgram. Частину типів трекер пише сам - з апдейтів Telegram, які ваш бот і так отримує. Наступний розділ каже, які саме, і які лишатимуться порожніми, доки ви їх не надішлете.

Дедуплікація детермінована: повторне надсилання того самого clickId + type без 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}, суб-ланцюжок і нативні 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.