Mini Apps: трекайте запуск, не втрачаючи атрибуцію
Якщо ваша воронка завершується не діалогом з ботом і не вступом до каналу, а Mini App, то конверсія - це сам запуск застосунку. Відбувається він на вашому домені, де наш бот не бачить нічого. Короткий сніпет закриває цей розрив: читає параметри запуску, які Telegram і так передав застосунку, надсилає їх у Leadgram, і запуск потрапляє у воронку подією miniapp_launch, прив'язаною до кліку, який привів людину.
Як працює трекінг Mini App
Під час запуску Telegram віддає кожному Mini App підписаний рядок initData. У ньому користувач, мітка часу і - якщо застосунок відкрили за діплінком - start_param. Рядок підписано токеном вашого бота, тому, отримавши його, ми можемо перевірити, що запуск справді прийшов з Telegram і саме для вашого бота. Підробити запуск, не маючи вашого токена, неможливо.
Далі ми визначаємо, якому кліку належить запуск. Якщо в start_param лежить click id Leadgram - це і є атрибуція, так само як з діплінками /start у ботів. Якщо ні - беремо останній клік цього Telegram-користувача у вашій організації за останні сім днів. Якщо не знайшлося ні того, ні іншого, запуск просто не трекається: атрибуцію ми ніколи не вгадуємо.
Сніпет лише ЧИТАЄ параметри запуску. Він не викликає методи Telegram.WebApp, а отже переживає origin-захист, який Telegram вмикає з 20 липня 2026 року, - і працював би навіть виконуючись на чужому домені. Подробиці - в Origin-захисті Mini App.
Додайте сніпет
Вставте це у свій Mini App - на сторінку, яку Telegram завантажує першою. Ані бібліотек, ані JS-моста Telegram не потрібно.
<script>
(function () {
// Параметри запуску Telegram кладе у фрагмент URL. Щоб їх прочитати,
// міст Telegram.WebApp не потрібен - тому сніпет переживає origin-захист.
var params = new URLSearchParams(window.location.hash.slice(1));
var initData = params.get("tgWebAppData");
if (!initData) return;
fetch("https://leadgram.org/api/miniapp/YOUR_BOT_ID/event", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ initData: initData }),
}).catch(function () {
// Трекінг не має ламати ваш застосунок - глушимо помилки.
});
})();
</script>
Замініть YOUR_BOT_ID на id бота зі сторінки ботів. Цей id не є секретом: він лише вказує, чиїм токеном перевіряти підпис, а запит без валідного підпису відхиляється.
Якщо ваш Mini App - SPA, викличте сніпет один раз під час першого завантаження. Смикати його на кожній зміні роуту нешкідливо (повторні запуски однієї людини схлопуються в одну подію), але це зайві запити.
Передайте click id
Щоб прив'язати запуск до конкретного кліку, покладіть click id у діплінк, який відкриває Mini App:
https://t.me/YOUR_BOT/YOUR_APP?startapp={click_id}
Telegram доставить {click_id} у застосунок як start_param усередині initData, а сніпет передасть його далі недоторканим. Ваше трекінгове посилання редиректить на цей URL, тож click id іде від оголошення до застосунку сам, без вашої участі в проміжку.
Не вказуйте трекінгове посилання Leadgram у полі Mini App URL у BotFather. Редирект спрацює, але ваш Mini App опиниться зареєстрованим на домені трекера, а не на вашому, і origin-захист Telegram зламається для всього застосунку. Вказуйте в BotFather свій справжній домен, а click id передавайте через startapp.
Що ви побачите
Перевірений запуск з'являється на сторінці Подій як miniapp_launch - з прив'язкою до кліку, що привів, і з start_param у payload. Далі він поводиться як будь-яка подія: піднімає ваші постбеки, потрапляє у звіти і мапиться у ViewContent на боці Meta - залучений перегляд контенту, не лід і не покупка.
Повторні запуски однієї людини дедуплікуються: Mini App відкривають знову і знову, і кожне відкриття - не нова конверсія. Якщо всередині застосунку ви ще й продаєте за Telegram Stars, такі покупки приходять окремо - див. Події та конверсії.
Коли запуск справжній, але кліку за людиною немає, ендпоінт відповідає 200 і tracked: false. Це не помилка: інтеграція працює, просто конкретно цей користувач прийшов повз відстежувану кампанію.