Telegram-боты и каналы: одно подключение - полная атрибуция

В Telegram-трафике бот - это мост атрибуции. Сам по себе клик по рекламе - просто редирект: как только бот подключён, Leadgram точно знает, какой клик нажал Start, из какой кампании пришёл подписчик, и может передать эти конверсии в Meta или Google, чтобы алгоритм закупки приводил вам больше пользователей, которые реально доходят до конверсии. Десять минут настройки здесь делают измеримым каждый доллар спенда потом.

Добавление бота

  1. Откройте @BotFather в Telegram, отправьте /newbot и скопируйте API-ключ, который он вернёт (выглядит как 110201543:AAHdqTcv...).
  2. Перейдите в Боты и нажмите «Добавить бота».
  3. Вставьте ключ в поле «API-ключ Telegram-бота» - платформа проверит токен и сама подтянет @username бота.
  4. Нажмите «Добавить бота».

Сохранение бота заодно регистрирует для него Telegram-вебхук, так что поднимать сервер или куда-то вставлять URL не нужно. Бейдж статуса показывает, чем эта регистрация закончилась на самом деле: «Активен» значит, что Telegram её принял, «Ожидание» или «Ошибка» - что не принял: строка бота сохранилась, но /start до вас не доходит. Неактивная строка так и пишет об этом на месте и несёт кнопку «Зарегистрировать вебхук», которая повторяет вызов, - обращаться из-за этого в поддержку не нужно.

Как только вебхук заработал, Telegram присылает на него сообщения и нажатия кнопок, и то и другое уходит в вашу воронку. Изменения состава канала и заявки на вступление приходят на тот же вебхук и превращаются в события channel_join / join_request для тех каналов, которые вы отслеживаете, - об этом ниже.

Список ботов с бейджем «Активен» и типомСписок ботов с бейджем «Активен» и типом

Как бот атрибутирует клики

Цепочка выглядит так: трекинг-ссылка кампании → лендинг → deep-link t.me/your_bot?start=click_id. Когда пользователь жмёт Start, Leadgram сопоставляет payload с сохранённым кликом (подойдёт и ref_id от внешнего трекера), запускает активный флоу, привязанный к этому боту, с его первого узла и записывает чат в базу подписчиков бота. Добавьте во флоу узел события «Старт бота» - и клик перейдёт в статус «Старт» и уйдёт серверной конверсией. Повторный /start всегда перезапускает воронку с начала - именно так пользователи Telegram и ожидают от бота.

Удаление бота

У каждой строки на странице Боты есть кнопка «Удалить». Подтверждение перечисляет, чего удаление коснётся, и разблокируется только после того, как вы заново наберёте @username бота, - потому что за один раз сдвигаются сразу четыре вещи:

  • Флоу, «Активные» на этом боте, падают в «Черновик» и перестают работать. Привяжите другого бота и снова включите их.
  • Список подписчиков бота удаляется вместе с ним. Пушам по этой аудитории будет некому уходить, а человек вернётся в список, только если нажмёт Start в другом боте.
  • Каналы, которые активировал этот бот, перестают считать вступления. Бейдж «Активен» у них останется, поэтому, пока вы не активируете их заново другим ботом, тишина ничем себя не выдаст.
  • Клики, кампании и пуши остаются - у них лишь очищается ссылка на этого бота, поэтому отчёты за прошлые периоды сохраняют свои цифры.

В самом Telegram бот не трогается: его токен продолжает работать, поэтому бота можно подключить сюда заново - или отозвать токен в @BotFather, если он больше не нужен.

Каналы и события вступления

Назначьте бота администратором канала - и этот канал появится на странице Каналы с бейджем «Обнаружен». Обнаруженная строка пока ничего не отслеживает, и этот барьер сделан намеренно: добавить вашего публичного бота в свой канал может кто угодно. Нажмите «Подтвердить», чтобы начать отслеживание, или «Отклонить», чтобы убрать строку: отклонённый канал сам собой больше не всплывёт, а так как он ничего и не отслеживал, ничего и не теряется.

Канал можно добавить и до назначения бота: кнопка «Не видите свой канал?» просит «Telegram ID канала» (отрицательное число, начинается с -100 - найдите его через @userinfobot или переслав любой пост канала в @JsonDumpBot), название и тип. Такая строка ждёт в статусе «Ожидание». Назначение бота администратором сразу её активирует, а кнопка «Активировать» делает то же самое по требованию: проверяет, что бот действительно администрирует канал, и вычисляет канонический chat id, по которому сопоставляются вступления.

Отслеживается только канал в статусе «Активен» и только через того бота, который его активировал. Реальное вступление после этого поднимает событие channel_join: его можно пересылать через Постбэки, а при доставке в Meta оно маппится на событие Subscribe. Если в канале включено одобрение заявок, сначала поднимается join_request, а channel_join приходит уже после одобрения заявки.

Smart Delay (кнопка «Настройки» у активного канала) придерживает вступление и засчитывает его, только если человек всё ещё в канале, когда окно закрывается, - это фильтр от тех, кто заглянул и вышел. Компромисс, который стоит знать до того, как ставить длинное окно: событие уходит в рекламный кабинет в момент закрытия окна, а не в момент вступления.

Удаление канала

У строк каналов тоже есть кнопка «Удалить» с тем же барьером «наберите заново», только здесь это Telegram ID канала. Удаление сразу останавливает отслеживание вступлений и стирает запись о тех, кто уже вступил. Добавите канал заново - и человек, вступивший раньше, может быть засчитан как новая конверсия и повторно отправлен в рекламный кабинет (per-user дедуп CAPI, если включён в кампании, повтор подавит). Биллинг помнит подписчиков на уровне организации, поэтому повторного списания за того же человека не будет. Кампании, которые ссылались на канал, продолжают работать и лишь теряют ссылку, уже записанные конверсии остаются в отчётах, а настройка Smart Delay пропадает вместе со строкой. Сама строка тоже не вернётся: ваш бот уже администратор, поэтому нового события о назначении Telegram не пришлёт.

Залив на заявку в закрытый канал

Если закрытый канал принимает по заявке, целевым действием кампании может быть сама заявка, а не вступление: человек нажимает «Подать заявку» и попадает в канал позже, когда её одобрят. Leadgram считает это двумя разными событиями: заявку - join_request, вступление - channel_join.

Чтобы заявка вообще записалась, нужны две вещи. Первая - канал в статусе «Активен»: заявки считает только тот бот, который его активировал. Вторая - человек, прошедший через бота по вашей трекинговой ссылке. Сама заявка клика не несёт, Telegram присылает в ней только аккаунт человека, поэтому клик ищется по его недавнему проходу через бота: по запуску флоу или по /start у бота без флоу, не старше окна атрибуции (по умолчанию 7 дней). Кто пришёл в канал по прямой ссылке-приглашению, минуя бота, ни к какому клику не привязывается: события не будет вовсе, а на странице Доставка конверсий вырастет строка «Заявка на вступление» в блоке «Дропы без атрибуции».

Автоприём заявок

Настройка «Автоприём заявок» живёт в «Настройках» активного канала, рядом со Smart Delay, и по умолчанию выключена. Выключена - значит заявки висят, пока админ не одобрит каждую руками в Telegram; до этого момента человек в канал не вступил, channel_join не поднимается, и конверсии «вступление» не будет ни в отчётах, ни в рекламном кабинете, ни в постбэке. Ровно так выглядит воронка, где заявок много, а вступлений почти нет.

Включённый автоприём одобряет заявки за вас. Поле «Задержка, секунд» принимает целое число от 0 до 86400 (86400 - это 24 часа), где 0 - одобрять сразу, а любое другое значение - через столько секунд после заявки. Одобряет только активационный бот канала, и ему нужно админ-право «Добавление подписчиков»: без него Telegram отказывает, заявка остаётся висеть, и на экране об этом ничего не появится - проверять придётся в самом Telegram.

Две вещи стоит знать заранее. Заявка ставится в очередь на одобрение раньше, чем система ищет для неё клик, - одобрят и того, чью заявку не удалось ни к чему привязать. А выключенный посреди задержки автоприём отменяет то, что ещё не одобрено: перед каждым одобрением настройка канала перечитывается, и «выключено» побеждает.

Что уходит наружу и за что списывают

Заявка и вступление - разные события с разными именами и разным временем, поэтому при одобрении наружу уйдут оба. В правиле Постбэков заявка стоит в списке триггеров рядом со вступлением, так что в свой трекер её можно отдать отдельной строкой - и не ждать вступления, которого при ручном одобрении может не случиться. Дедупликация их не путает: по умолчанию она выключена и в правиле постбэка, и в кампании, а режимы «Один раз на пользователя» и «Один раз на пользователя на источник» держат тип события частью ключа. В режиме «Любой тип события - один раз на пользователя» заявка вступлению тоже не мешает, но в правиле и в кампании по разным причинам. Правило постбэка срабатывает на одном типе события, поэтому заявка и вступление всегда лежат в разных правилах и за один ключ не спорят: там этот режим работает так же, как «Один раз на пользователя», и правило может подавить только повтор своего же события. В кампании общий ключ настоящий - он один на человека на всю кампанию, независимо от события, - и заявка из него исключена. Иначе она заняла бы ключ и подавила вступление того же человека, а кампания, оптимизированная на вступления, начала бы получать заявки. Плата за это исключение принята сознательно: в кампании повторная заявка того же человека уйдёт повторно, потому что подавлять её больше нечем. Как каждое из двух событий выглядит на стороне площадки, описано в Meta CAPI и Google Ads CAPI.

Заявка бесплатна: join_request лежит в том же списке бесплатных типов, что клик, открытие лендинга и отмена подписки. Платите вы за человека, а не за событие - списание происходит один раз на пару (ваша организация, человек), на его первом платном событии, обычно на старте бота или на самом вступлении. Поэтому цепочка «заявка → одобрение → вступление» стоит одно списание, а заявки, которые никто не одобрил, не стоят ничего.

И то, чего заявка не делает: она не двигает статус клика - и вступление, кстати, тоже, - так что в списке Кликов человек останется в том статусе, до которого дошёл раньше, а сама заявка видна в истории событий этого клика. Smart Delay на неё не действует: удерживать нечего, в канал человек ещё не вступил, окно Smart Delay относится только к вступлению.

Где боты встречаются в продукте

  • Флоу - флоу можно создать без привязанного бота, но перед тем как перевести его в статус «Активна», бот понадобится. Селектор бота в диалоге создания флоу показывает ботов, добавленных здесь.
  • Кампании - бот кампании проставляется на каждый клик, чтобы сопоставление по /start срабатывало надёжно.
  • Пуши - список получателей - это подписчики, которых бот собрал через Start. Из списка выпадает любой чат, которому Telegram отказался доставить, а таких исходов четыре: человек заблокировал бота, аккаунт удалён, диалога не было никогда и бота выгнали из группы. Вернуть в список может только новый /start из того же чата, поэтому удалённый аккаунт не вернётся никогда, а выгнанная группа - даже после того, как админ вернёт туда бота. Разбор всех четырёх - в гайде Пуши.

Частые грабли

  • Токен не принимается. Копируйте ключ из BotFather целиком: цифры, двоеточие и 35-символьный хвост. Обрезанная вставка мгновенно проваливает валидацию.
  • Бот молчит на Start. Одна и та же картина может быть вызвана двумя разными причинами. Чаще всего бот отвечает только тогда, когда к нему привязан флоу в статусе «Активна»; без активного флоу апдейт игнорируется - так задумано. Вторая причина - вебхук, который так и не зарегистрировался: тогда бейдж показывает «Ожидание» или «Ошибка» вместо «Активен», а на самой строке есть кнопка «Зарегистрировать вебхук» для повтора.
  • Старты без атрибуции. Пользователи, открывшие бота по username, минуют трекинг-ссылку - в payload нет click id. Весь платный трафик ведите только через трекинг-URL кампании.
  • Канал завис в «Ожидании». «Ожидание» означает, что бот ещё не подтверждён как администратор этого канала. Назначьте его в Telegram или нажмите «Активировать» на строке и выберите бота. Пока канал не «Активен», ни одно вступление не отслеживается.
  • Тесты на живом боте. Держите отдельного бота для экспериментов с флоу. «Живым» бота делает только то, что на него указывает реклама, - второй бот, которого нет ни в одной кампании, безопасная песочница: сломанный тест никогда не заденет живой трафик.
  • Удаление бота на бегу. Подтверждение не зря перечисляет все последствия - прочитайте их до того, как наберёте username. Чаще всего упускают одно: каналы, которые активировал этот бот, продолжают показывать «Активен», ничего при этом не считая.