Зачем мы построили собственный ad-attribution стек
Экосистема Telegram Mini App выросла за последние 18 месяцев, а маркетинговая инфраструктура для платного приобретения внутри Telegram-каналов — нет. Когда мы начали закупать платные shoutout-ы в @fuckingenglish (322k подписчиков, изучающих английский через сленг), стандартный playbook был: бросить t.me/wall/app deep-link, посчитать регистрации в БД на следующий день, надеяться на лучшее.
Это работает для одной кампании. Это разваливается в момент, когда ведёте 5+ кампаний через несколько каналов с разными creative-вариантами. Нужно было: per-channel атрибуция, per-creative разбор (кнопка vs гиперссылка в тексте vs link-preview), orphan-safe логирование URL с опечатками и два URL-формата для in-Telegram vs off-Telegram поверхностей. Готовые трекеры не подходят для Telegram-Mini-App модели — они построены под browser-only журнеи.
Поэтому мы построили его сами на уровне бота. Wall Ad Network Phase 0 вышел в проде в мае 2026. Публичные документы архитектуры — на wall.support/ad-network.
Анатомия URL
Каждая URL платной кампании на Wall кодирует канал, креатив и placement в один hyphen-separated токен после ref_:
https://t.me/wall/app?startapp=ref_<root>-<utm1>-<utm2>-<utm3>
- root — зарегистрированный
ReferralLink.slug, принадлежащий покупателю (например,adдля namespace Wall Ads) - utm1 — код канала-источника (например,
fe= @fuckingenglish,tgl= @tglive) - utm2 — идентификатор креатива / поста (например,
tagged,replyguy) - utm3 — placement (
btn= inline-кнопка,body= гиперссылка в тексте,qr= QR-код,dm= личный шеринг)
Bot-handler /start и /api/init Mini App'а оба парсят этот токен, ищут root в БД и сохраняют полный UTM-разбор в ReferralEvent.metadata. SQL-фильтрация по metadata->>'utm1' = 'fe' (например) даёт мгновенный per-channel cohort-анализ без отдельного analytics warehouse.
Два формата URL — для внутри и снаружи Telegram
Архитектура экспонирует два URL-формата на slug, используются в разных контекстах:
- 📱 In-Telegram deeplink —
t.me/wall/app?startapp=ref_<token>. Telegram открывает Mini App за 1 тап без браузерного flash. Используется для inline-кнопок в постах каналов, гиперссылок в тексте, DM-шеров, пересланных сообщений. - 🌐 Universal redirector —
wall.tg/r/<token>?c=&s=. Логирует событие клика до 302-редиректа в Telegram. Используется для off-Telegram поверхностей (Twitter, блоги, QR-коды, email-кампании), где нужно поймать клики, даже если /start никогда не сработает.
Redirector также фильтрует известные User-Agent link-preview ботов (TelegramBot, TwitterBot, facebookexternalhit, LinkedInBot, Slackbot, WhatsApp, Discordbot, Googlebot, bingbot, YandexBot, Pinterest, redditbot, Applebot, DuckDuckBot, Mastodon), чтобы preview-обращения не засоряли click-метрику.
Orphan-safe атрибуция
Опечатки случаются. URL кампании может быть вручную отредактирован админом канала, и дефис случайно превращён в подчёркивание. Без orphan-логирования эти клики бы тихо терялись, и мы потеряли бы paid-campaign ROI на misattribution.
Парсер Wall логирует каждый нераспознанный реферальный токен как ReferralEvent { type: 'unknown_ref' } с сохранением исходного URL в metadata.rawParam. Покупатели могут периодически сканировать orphan-лог через SQL:
SELECT metadata->>'rawParam' AS bad_url, COUNT(*) AS hits
FROM referral_events
WHERE type = 'unknown_ref'
AND created_at > NOW() - INTERVAL '7 days'
GROUP BY bad_url ORDER BY hits DESC;
После определения частых опечаток (например, fe_tagged_bttn вместо fe-tagged-btn), админы вручную re-bind'ят эти события на правильный slug — сохраняя атрибуцию, которая иначе была бы потерянным ROI на платной кампании.
Что в проде сегодня vs Phase 1+ roadmap
Phase 0 (live): парсер в lib/referral-token.ts, redirector в app/r/[slug]/route.ts, UTM-aware /start handler в bot/index.ts, UTM-aware /api/init в Mini App. Per-slug аналитика через прямой SQL на referral_events.metadata уже питает наши внутренние дашборды.
Phase 1 (в разработке): dedicated AdCampaign + AdClick таблицы БД для persistent campaign aggregation. Bridge от off-Telegram кликов (логированных в redirector) к /start событиям (когда юзер достиг Mini App) через Redis. Off-Telegram клики, не достигшие /start, получают AdClick строку с resultedInStart = false — full top-of-funnel visibility.
Phase 2: /promo cabinet UI для рекламодателей. Список кампаний, per-campaign A/B charts, per-channel cohort LTV, ROI-калькулятор. Доступ через Profile.role IN ('admin', 'ad_buyer').
Phase 3: publisher cabinet на /publisher для админов каналов, продающих ad-слоты. Marketplace для покупателей + escrow flow.
Phase 4: публичный REST API для third-party рекламодателей. Автоматическое bid management.
Первая кампания — @fuckingenglish (322k подписчиков)
Первая ad-закупка запущена в мае 2026: двухпостовый арк на популярном русскоязычном канале изучения английского @fuckingenglish, разбирающий сленг-слова «tagged» и «reply guy». Использованные URL:
ref_ad-fe-tagged-btn ← POST 1 inline-кнопка
ref_ad-fe-tagged-body ← POST 1 гиперссылка в тексте
ref_ad-fe-replyguy-btn ← POST 2 inline-кнопка
ref_ad-fe-replyguy-body ← POST 2 гиперссылка в тексте
Все 4 URL имеют один root (ad) — одна строка ReferralLink владеет всей кампанией. Per-creative + per-placement разбор приходит из SQL по metadata.utm2 и metadata.utm3. A/B кнопка-vs-in-text видна с первого часа после публикации; per-user cohort-анализ (какие подписчики позже становятся Premium) определяет re-buy решение для следующей кампании в том же канале.
Зачем публиковать архитектуру вместо того, чтобы делать из неё moat
«Конкурентное преимущество» скрытых архитектурных решений переоценено. Публичная документация заставляет внутреннюю clarity (нельзя написать то, чего не понимаешь), привлекает collaborator-grade юзеров (разработчики + журналисты + power-users) и создаёт credibility-moat, который paid-PR не повторит.
Для Wall конкретно ad-network — одна из немногих infrastructure surfaces, которую большинство Mini App платформ outsource'ят к third-party трекерам. Публикация полного механизма — с SQL-примерами, code-references и 4-фазным roadmap — позиционирует Wall как платформу, которая шипает свои маркетинговые примитивы end-to-end. Этот сигнал значит больше, чем секретность.
Читайте больше
- wall.support/ad-network — полная архитектура, FAQ, SQL-примеры
- wall.support/case-studies — реальные кампании с цифрами (победы и провалы)
- wall.support/security — как работает bot-level auth + rate limits
- wall.support/api — публичный
/api/productJSON-эндпоинт - wall.foundation/transparency — operating principles + decision log
- github.com/gmediaorg/wall-public — публичное зеркало (docs, canonical HTML, daily-stats; live app-source остаётся приватным)