ТЗ: Telegram onboarding-бот Magnet — регистрационная и маркетинговая воронка
Метаданные
| Параметр | Значение |
|---|---|
| Дата создания | 2026-06-29 |
| Дата последнего изменения | 2026-06-29 |
| Статус апрува | ⏳ На рассмотрении |
| Дата апрува | — |
Новый сервис apps/onboarding-bot — Telegram-бот, который работает как промежуточная
воронка между первым знакомством человека с Magnet и полноценной регистрацией в кабинете
через подключение кошелька. Лидер приглашает человека в бота (а не сразу на сложную
Web3-регистрацию); бот сохраняет лида, закрепляет за пригласившим лидером, прогревает,
выдаёт персональную ссылку на регистрацию, напоминает о следующем шаге и продолжает
сопровождение после входа в экосистему.
Решаемые проблемы:
- Потеря лидов на входе в Web3. Прямая отправка на подключение кошелька даёт высокий отвал. Бот добавляет прогрев и снижает порог входа.
- Нет CRM по пред-регистрационным лидам. Сейчас лид «невидим» до момента регистрации в кабинете. Бот фиксирует контакт и стадию воронки ещё до регистрации.
- Лидер не видит, где застрял партнёр. Бот даёт лидеру реф-кабинет со статистикой по этапам и уведомления о действиях партнёров.
- Нет персонального канала сопровождения после регистрации. Бот становится каналом срочных уведомлений, дайджестов и маркетинговых рассылок.
Важно (контекст): значительная часть инфраструктуры уже существует в
apps/backendи переиспользуется (см. 3.2): привязкаusers.telegram_id, одноразовые connect-ссылки (generateTelegramConnectWalletLink),BotAuthGuard/BOT_TO_BACKEND_SECRET, реферальная модель (referral_link+users.link+users.parentId), таблицаnotifications,sessions.timeActive. Новый бот — это отдельный, более крупный funnel-бот, не путать с существующим «TransferBot» вapps/eoa-backend.
2.1. Пользовательские сценарии
Лидер
- Привязка Telegram к аккаунту Magnet. Доступно, только если у пользователя ещё нет
users.telegram_id. Лидер входит в бота → «Подключить Magnet» → бэкенд выдаёт одноразовую ссылку → лидер на сайте подключает кошелёк, авторизуется и подтверждает привязку → вusers.telegram_idзаписывается его Telegram. Еслиtelegram_idуже привязан — бот сразу доступен и связан. - Получение персональной ссылки на бота. После привязки лидер в боте видит
https://t.me/<OnboardingBot>?start=<users.link>, копирует и рассылает партнёрам (с QR). - Реф-кабинет в боте. Лидер видит метрики: переходы в бота, всего лидов, посмотрели презентацию, нажали регистрацию, зарегистрировались; список «застрявших на этапе X».
- Уведомления лидеру. Новый партнёр в боте; посмотрел презентацию; нажал регистрацию; зарегистрировался; ушёл к другому лидеру; запросил помощь. (Фаза 1 шлёт push только «новый партнёр» / «зарегистрировался» / «ушёл к лидеру»; push про «посмотрел/нажал» — Фаза 2; в Фазе 1 эти сигналы видны через метрики кабинета.)
Лид (приглашённый)
- Вход по ссылке лидера. Открывает
?start=<leaderLink>→ бот определяет лидера, закрепляет лида за ним (first-touch), запускает воронку. - Прогрев. Приветствие → «Что такое Magnet» → выбор интереса → ключевые продукты (контент — моки, настраивается позже).
- Регистрация. Получает кнопку «Зарегистрироваться в Magnet» с персональной ссылкой,
содержащей реф-код того же лидера (формат сайта
?link=) и одноразовый?telegramConnect=для связки Telegram. - Подтверждение кошелька. После регистрации бот в личке спрашивает «это ваш кошелёк
0x…?»; при подтверждении Telegram привязывается к аккаунту.
Кейс смены рефки на фронте
Лид вошёл по ссылке лидера A, но на форме регистрации поставил рефку лидера B. Тогда партнёр в Magnet уходит под B; B получает «новый партнёр», A получает «ваш партнёр ушёл к лидеру B». Дальнейшие пострег-уведомления по этому партнёру идут лидеру B (Magnet-реферер).
Администратор (Фаза 2)
- Сегментирует лидов по этапу / неактивности / уровню NFT.
- Запускает рассылки по сегментам, ручные напоминания.
- Смотрит воронку конверсии по этапам.
2.2. Бизнес-логика
Реферальная цепочка Telegram → Magnet
- Бот-ссылка лидера:
https://t.me/<bot>?start=<leader.link>, гдеleader.link— значениеusers.link(8 hex-символов, валидно для Telegram start payload). - Лид открывает ссылку → бот резолвит лидера через
GET /bot/leader/resolve?code=→ создаёт записьbot_users, закрепляяleader_link/leader_uid(first-touch lock: повторные/startс другим кодом игнорируются — анти-увод). - На этапе регистрации бот формирует URL:
${FRONT}/?link=<leader.link>&telegramConnect=<uuid>— реф того же лидера в формате сайта + одноразовый connect-токен лида.
Единый идентификатор рефки =
users.link(неrefUid/hashedUid). Резолв лидера идёт через таблицуreferral_link(тамlinkUNIQUE) чистым lookup без сайд-эффектов.
Привязка telegram_id (модель безопасности)
Связка Telegram лида с но вым Magnet-аккаунтом строится на существующем одноразовом механизме (а не на самоподписанном токене):
- Бот при выдаче кнопки регистрации вызывает
generateTelegramConnectWalletLink( inviteeTelegramId)→ одноразовыйuuid+ Redis 10 мин TTL + обратная картаtelegram-connect-<uuid> → telegramId+ пред-проверка уникальностиtelegram_id. URL содержит?telegramConnect=<uuid>. - Мост login → событие (durable). На регистрации
loginчитаетuuidизloginDto.telegramLink(соответствие: URL-параметр?telegramConnect=маппится в DTO-полеtelegramLink), резолвит обратную картуtelegram-connect-<uuid> → telegramIdи персистит pending-привязку вusers.previewTelegramId = telegramId(существующая колонка, «неподтверждённый» Telegram). Это новый код — текущий закомментированный блок лишь удалял кэш иtelegram_idне присваивал. - Корреляция событий.
wallet_connected(изfindOrCreate, синхронно вlogin) несётtelegram_id(=previewTelegramId) +magnet_uid+addr;registered(из sync-хендлера) читаетusers.previewTelegramIdи несёт тот жеtelegram_id+magnet_uid. Оба события несут консистентный ключtelegram_id— бот коррелирует сbot_usersпо нему (бот уже знаетtelegram_idлида с момента/start). - Подтверждение и привязка. Получив
registered, бот в личке показывает «это ваш кошелёк0x…?» (адрес у бота уже есть изwallet_connected). При согласии бот зовётPOST /bot/telegram/bind { magnet_uid, telegramId }подBotAuthGuard→ backend промоутитpreviewTelegramId → telegram_idчерезupdateUserTelegramId(user.id, telegramId)напрямую + пред-проверка уникальности. При отказе аккаунт остаётся непривязанным.
Почему так: публичный bearer-токен telegram_id в URL небезопасен (утечка ссылки →
привязка чужого Telegram к своему кошельку; telegram_id UNIQUE → блокировка жертвы).
In-bot подтверждение кошелька закрывает даже остаточный риск утечки connect-ссылки в окне
TTL — настоящий владелец Telegram получает DM и может отклонить чужой кошелёк.