Переадресация с Тильды на Телеграм бот - место, где я чаще всего вижу потерянные заявки у клиентов. Кнопка стоит, ссылка ведёт на бота, а дальше бот получает голый /start и не понимает, кто пришёл: с лендинга по рекламе, с блока цен на второй странице или из письма рассылки. За практику с Тильдой я настраивал такой переход для лендингов с оплатой через T‑Bank, для интернет-магазинов с доставкой СДЭК и для обычных лид-форм, где нужно было просто передать боту имя и телефон из формы. Разберу рабочую схему: кнопка на Тильде, deep link со start-параметром, разбор параметра в боте на aiogram и учёт источника трафика без сторонних сервисов аналитики.
По теме статьи
Готовое решение
Ограничение применения промокода в корзине Tilda
Промокод в Tilda не действует на выбранную категорию (например, «Распродажа»). Готовый скрипт + инструкция по подключению.
от6 000 ₽
Кастомный скрипт
Когда стандартных блоков не хватает
Доработка сайтов на Тильде: скрипты для корзины, промокоды, зоны доставки, интеграции с CRM и Telegram. Простой скрипт от 3 000
от3 000 ₽
Зачем нужна переадресация с Тильды в Телеграм-бота
Обычная кнопка Тильды со ссылкой вида t.me/username открывает диалог с ботом, но не передаёт ничего, кроме факта перехода. Deep link устроен иначе: ссылка t.me/botusername?start=payload прокидывает произвольную строку до 64 символов прямо в событие /start, и бот получает её как аргумент команды. Разница между этими двумя вариантами - это разница между «кто-то написал в бота» и «написал клиент с карточки товара X, который увидел баннер с промокодом Y».
На одном проекте с оплатой через T‑Bank кнопка «Оформить в боте» стояла на трёх разных блоках лендинга: в шапке, в блоке с ценами и в попапе с брошенной корзиной. Без deep link в статистике бота эти три источника были неотличимы друг от друга, и заказчик не мог понять, какой блок вообще приносит заявки. После того как каждая кнопка стала передавать свой payload, стало видно, что попап с брошенной корзиной даёт втрое больше стартов бота, чем кнопка в шапке, хотя дизайнер был уверен в обратном.
Кнопка на Тильде: html-блок и переход в бота
Встроенный виджет «Telegram» в Тильде подходит только для ссылки на канал или профиль без параметров - для deep link он не годится, потому что поле принимает голый username. Рабочий вариант - кастомный HTML-блок с обычной ссылкой на t.me и своей вёрсткой кнопки:
<a href="https://t.me/kalinkindev_bot?start=lp_header" class="tg-btn" target="_blank" rel="noopener">
Написать в Telegram
</a>
<style>
.tg-btn {
display: inline-block;
padding: 14px 28px;
border-radius: 8px;
background: #229ED9;
color: #fff;
text-decoration: none;
font-weight: 600;
}
</style>
Здесь payload lp_header зашит статически прямо в вёрстке - для страницы с одной кнопкой этого достаточно. Если кнопок несколько и нужно собирать источник динамически, например подставлять utm-метки посетителя, payload собирают скриптом при загрузке страницы и подставляют в href перед показом блока.
Бесплатный материал
🎁 Полезный скрипт в подарок
Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.
Без спама. Отписка в 1 клик.
Deep link с параметром: как передать данные о посетителе в start
Telegram жёстко ограничивает содержимое start-параметра: только латинские буквы, цифры, подчёркивание и дефис, максимум 64 символа. Кириллицу, знаки равенства и амперсанд передать нельзя, значит строку вида utm_source=yandex&utm_medium=cpc в чистом виде в ссылку не вставить.
На практике я собираю компактную строку из нужных полей, кодирую её в base64url (это тот же base64, но без символов + и /, которые в start запрещены) и обрезаю до лимита. Если полей много и они не помещаются в 64 символа, лучше сохранить исходные utm-метки в свою базу или таблицу заявок на сервере, а в start-параметр положить только короткий идентификатор записи - тогда бот всегда получает валидный payload независимо от длины исходных данных.
function buildStartPayload() {
const params = new URLSearchParams(window.location.search);
const raw = [
params.get('utm_source') || 'direct',
params.get('utm_campaign') || 'none'
].join('|');
const encoded = btoa(unescape(encodeURIComponent(raw)))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '')
.slice(0, 64);
document.querySelectorAll('.tg-btn').forEach((btn) => {
const url = new URL(btn.href);
url.searchParams.set('start', encoded);
btn.href = url.toString();
});
}
document.addEventListener('DOMContentLoaded', buildStartPayload);
Скрипт добавляется в код страницы Тильды через настройки «Ещё» и «Вставка кода на страницу», в зависимости от того, нужен он на одной странице или на всём проекте.
Обработка start-параметра на стороне бота
На стороне бота payload нужно раскодировать обратно и достать поля. Пример для aiogram 3.x:
import base64
from aiogram import Router
from aiogram.filters import CommandStart, CommandObject
from aiogram.types import Message
router = Router()
def decode_payload(payload: str) -> dict:
padded = payload + "=" * (-len(payload) % 4)
raw = base64.urlsafe_b64decode(padded).decode("utf-8", errors="ignore")
source, campaign = (raw.split("|") + ["none", "none"])[:2]
return {"source": source, "campaign": campaign}
@router.message(CommandStart())
async def on_start(message: Message, command: CommandObject):
if command.args:
data = decode_payload(command.args)
else:
data = {"source": "direct", "campaign": "none"}
await save_lead(user_id=message.from_user.id, **data)
await message.answer("Здравствуйте! Чем можем помочь?")
Важный момент: если пользователь открыл бота вручную, без ссылки, command.args будет пустым - обязательно нужна ветка на этот случай, иначе бот упадёт на распаковке payload. Если нужна интеграция с CRM или сложная логика распределения заявок по менеджерам, такую разработку Telegram-бота под конкретный процесс продаж обычно делают отдельным проектом, а не одной кнопкой на лендинге.
Учёт источника трафика: способы, которые я использую на практике
Есть три рабочих подхода, выбор зависит от того, сколько у сайта точек входа и насколько глубоко нужна аналитика.
| Способ | Что передаёт | Когда использую |
|---|---|---|
| Статический payload на каждой кнопке | Только метку блока (шапка, попап, футер) | Одна-две страницы, источники известны заранее |
| JS-скрипт с автосбором utm-меток | utm_source, utm_campaign, иногда referrer | Много страниц входа, трафик из разных рекламных каналов |
| Короткий id записи и база на сервере | Ссылку на полную запись с любым числом полей | Нужно передать больше двух-трёх параметров или данные из формы |
Для интернет-магазинов с доставкой через СДЭК я обычно комбинирую второй и третий способ: utm-метки летят в payload напрямую, а привязку к конкретному заказу или брошенной корзине бот получает по короткому id, у которого в базе уже лежит адрес, сумма и статус доставки.
Отдельно скажу про хранение данных, которые бот получает из start-параметра вместе с именем и телефоном из формы Тильды. Это персональные данные, и держать их стоит на своей базе или в отечественной CRM, а не в Google Таблицах или Airtable, требование локализации по 152-ФЗ никуда не девается от того, что заявка пришла через Telegram, а не через сайт напрямую. Если заявки нужно автоматически раскладывать по менеджерам или прогревать цепочкой сообщений, эту логику удобно собрать в n8n, подключив вебхук бота как триггер сценария.
Частые ошибки при настройке перехода с Тильды в Телеграм
- Использовать встроенный виджет «Telegram» вместо кастомной ссылки - он не поддерживает start-параметр в принципе.
- Передавать в payload кириллицу или пробелы - Telegram либо обрежет параметр, либо бот получит пустой command.args.
- Превышать лимит в 64 символа - лишние символы отбрасываются, и часть данных теряется без явной ошибки.
- Не проверять сценарий на iOS Safari - если Telegram не установлен, ссылка может увести в App Store вместо ожидаемого перехода в чат.
- Забыть про пользователей, которые уже писали боту раньше - для них тоже нужно свежее декодирование payload при каждом новом /start.
Настройка кнопки и deep link без дополнительной логики - это доработка скрипта на Тильде, от 3 000 ₽. Если переход должен завязываться на CRM, эквайринг и разные боты под разные продукты, это уже комплексная интеграция, от 40 000 ₽. Разработка самого бота с обработкой параметров, хранением заявок и рассылками - от 30 000 ₽.
Частые вопросы
Как передать телефон клиента из формы Тильды сразу в Telegram-бота?
Форма на Тильде сама по себе не делает редирект с параметрами - она отправляет данные через вебхук в свою CRM или на внешний адрес. Чтобы связать заявку с ботом, я перехватываю успешную отправку формы через колбэк Тильды, генерирую короткий id записи на сервере и уже после этого показываю пользователю кнопку с deep link, где payload содержит этот id.
Можно ли передать в start-параметре кириллицу или спецсимволы?
Нет, Telegram разрешает только латинские буквы, цифры, подчёркивание и дефис, до 64 символов. Кириллицу и любые другие символы нужно кодировать, обычно через base64url, либо заменять на короткий идентификатор записи в базе.
Что если пользователь уже переписывался с ботом раньше, deep link всё равно сработает?
Да, каждый переход по ссылке с start заново вызывает команду /start с новым payload, и aiogram-обработчик получает свежие параметры при каждом клике, даже если история переписки с ботом уже есть.
Как понять, какая кнопка на сайте реально приводит клиентов в бота?
Присваивайте каждой кнопке или каждому источнику трафика свой payload и логируйте его при получении /start в базу или CRM. Через одну-две недели набирается достаточно данных, чтобы сравнить блоки лендинга или рекламные каналы по числу реальных стартов бота, а не только по кликам на кнопку.