Skip to main content

ADR 009: Quiz Open Access Strategy

Status

Accepted - 2026-03-04

Context

Вопрос

Нужно ли требовать подписку на Telegram-канал для ответа на квизы в discussion group?

Текущая архитектура

  • Квизы публикуются в discussion group через Telegram Bot
  • Ответы обрабатываются через callback_querytelegram-quiz-answer.service.ts
  • Пользователь автоматически создаётся при первом ответе на квиз (phantom user)
  • Для входа в TMA (Telegram Mini App) уже требуется подписка на канал

Анализ угроз

УгрозаРискСуществующая защита
Спам ботовНизкийRate limiter: 50 req/sec global, 10 req/min per user
Подделка identityНевозможноTelegram гарантирует ctx.from.id в callback_query
DDoS через квизыНизкий1 ответ на 1 квиз (duplicate check), rate limiter
Неподписанные зарабатывают scrapНекритичноScrap бесполезен без входа в TMA (требует подписку)
Забаненные голосуютНекритичноЗабаненные не могут войти в TMA, scrap бесполезен

Decision

Не добавлять проверку подписки на канал для квизов. Оставить квизы открытыми для всех.

Rationale: Quiz как воронка, а не забор

Сценарий с проверкой подписки (отвергнут):

Человек видит квиз → нажимает → "Подпишись!" → не хочет → ушёл навсегда

Сценарий без проверки (текущий, принят):

Человек видит квиз → играет → выигрывает → радуется
→ хочет посмотреть награды → открывает TMA
→ TMA требует подписку → подписывается добровольно
→ видит накопленный scrap → вау-эффект → лояльный пользователь

Ключевые аргументы

  1. Двойной забор не нужен. TMA уже требует подписку на канал. Ставить второй забор на квизах — убивать конверсию на верхнем этапе воронки.

  2. Phantom users — фича, не баг. Пользователи, отвечающие на квизы без TMA, накапливают scrap. При первом входе в TMA они видят "бонус" — это повышает retention.

  3. Scrap без TMA бесполезен. Даже если неподписанный отвечает на квизы — он не может потратить scrap, открыть кейс или получить предмет без входа в TMA.

  4. Забаненные безвредны. Забаненные пользователи заблокированы в TMA. Их ответы на квизы не влияют на экономику — scrap нельзя реализовать.

  5. Техническая простота. Не нужно: Telegram API вызовы (getChatMember), кэширование подписок, обработка ошибок API, новые зависимости в handler.

Consequences

Positive

  • ✅ Максимальная конверсия: нулевой барьер для участия в квизах
  • ✅ Накопление scrap как мотиватор для входа в TMA и подписки
  • ✅ Нулевая нагрузка на Telegram API (нет getChatMember вызовов)
  • ✅ Простота кода: не добавлены новые зависимости, кэши, edge cases
  • ✅ Будущее: бот в чужих группах — пользователи играют, потом приходят в наш канал

Negative

  • ⚠️ Неподписанные пользователи влияют на статистику квизов (correctAnswers, totalAttempts)
  • ⚠️ Забаненные могут продолжать отвечать (но scrap бесполезен)

Accepted Risks

  • Статистика квизов включает ответы неподписанных — некритично для бизнес-метрик
  • Забаненные накапливают бесполезный scrap — нулевой impact

Alternatives Considered

OptionEffortImpactDecision
Открытые квизы (без проверки)NoneЛучшая конверсияACCEPTED
Проверка подписки с кэшем 24чMedium~10k API calls/день❌ Избыточный контроль
Проверка подписки с кэшем 5минMedium~30k API calls/день❌ Перебор
Бан-проверка в processAnswerLowБлок единичных забаненных❌ Не оправдано (TMA блокирует)

Re-evaluation Criteria

Пересмотреть решение если:

  • Бот добавлен в чужие группы И нужна принудительная конверсия (не органическая)
  • Обнаружена масштабная эксплуатация квизов ботами (>10% phantom users)
  • Scrap станет реализуемым без TMA (новые каналы монетизации)