Skip to main content

Обзор

Система обязательной подписки на каналы блокирует доступ к боту, пока пользователь не подпишется на все указанные Telegram-каналы. Поддерживает неограниченное количество каналов с управлением через бот и Cabinet. Основные возможности:
  • Мультиканальная подписка — произвольное количество каналов с приоритетом (sort_order)
  • Цветные кнопки (Bot API 9.4) — подписанные каналы зелёные, неподписанные синие
  • Реал-тайм обновление через ChatMemberUpdated события
  • Автодеактивация/реактивация подписок при отписке/подписке на каналы
  • 3-уровневый кэш (Redis → PostgreSQL → Telegram API) для масштабирования на 100k+ пользователей
  • Сохранение deeplinks — реферальные коды и кампании переживают блокировку подписки

Быстрый старт

1. Включите подписку

2. Добавьте каналы через бот

В админ-панели бота: Настройки → Обязательные каналы → Добавить канал. Укажите:
  • ID канала — числовой ID (например 1234567890, префикс -100 добавится автоматически)
  • Ссылкаhttps://t.me/your_channel или @your_channel
  • Название — отображается на кнопке подписки

3. Сделайте бота администратором канала

Бот должен быть администратором каждого обязательного канала — иначе он не сможет проверять подписки.
Если бот не является администратором канала, проверка подписки завершится ошибкой и пользователь не сможет пройти дальше.

Конфигурация

Переменные CHANNEL_SUB_ID и CHANNEL_LINK из старых версий больше не нужны. Каналы управляются через админ-панель бота или Cabinet API.

Как это работает

Пользовательский флоу

Цветные кнопки (Bot API 9.4)

При нескольких обязательных каналах пользователь видит прогресс подписки:
  • Синие кнопки (style: primary) — каналы, на которые нужно подписаться
  • Зелёные кнопки (style: success) — каналы, на которые уже подписан (с ✅)
После каждого нажатия «Я подписался» клавиатура обновляется — подписанные каналы меняют цвет на зелёный.

Автодеактивация подписок

При отписке от обязательного канала бот может автоматически приостановить подписку пользователя: При деактивации:
  1. Подписка переводится в статус DISABLED
  2. Пользователь отключается в панели Remnawave
  3. Пользователь получает уведомление с кнопками подписки
При повторной подписке на все каналы:
  1. Подписка автоматически реактивируется
  2. Пользователь включается в Remnawave
  3. Пользователь получает уведомление о восстановлении
Заблокированные пользователи (BLOCKED) никогда не реактивируются автоматически, даже если подпишутся на все каналы.

Управление каналами

Через бот (админ-панель)

В меню бота: Админ-панель → Настройки → Обязательные каналы. Доступные действия:
  • Список каналов — все каналы со статусом (активен/неактивен)
  • Добавить канал — пошаговый ввод: ID → ссылка → название
  • Детали канала — ID, ссылка, статус, порядок
  • Вкл/Выкл — переключить активность канала (без удаления)
  • Удалить — полное удаление канала

Через Cabinet (веб-панель)

Cabinet предоставляет REST API и UI для управления каналами. API-эндпоинты (/cabinet/admin/channel-subscriptions): Поля канала:

Архитектура

3-уровневый кэш

Система оптимизирована для масштабирования и никогда не вызывает Telegram API напрямую в основном потоке:

Реал-тайм обновление через ChatMemberUpdated

Бот получает события ChatMemberUpdated при подписке/отписке пользователя на канал и сразу обновляет PostgreSQL + Redis. Это обеспечивает актуальные данные без задержек.
Для получения ChatMemberUpdated событий бот должен быть администратором каждого обязательного канала.

Redis-ключи

Безопасность

  • Fail-closed модель: при любой ошибке (сеть, rate limit, бот удалён из канала) пользователь считается неподписанным. Ложный отказ предпочтительнее несанкционированного доступа.
  • Админы исключены: администраторы бота всегда проходят проверку подписки.
  • Email/OAuth пользователи: пользователи без telegram_id (вход через email или OAuth) пропускают проверку подписки — она работает только для Telegram-пользователей.

Если пользователь пришёл по реферальной ссылке или ссылке кампании, а подписка на канал обязательна — deeplink сохраняется:
  1. В FSM-состояние aiogram (основное хранилище)
  2. В Redis как бэкап (TTL 1 час, на случай сброса FSM)
После подписки на все каналы deeplink восстанавливается и регистрация продолжается с применением реферального кода или бонуса кампании.
Если пользователь не подпишется на каналы в течение 1 часа — deeplink из Redis истекает. FSM-состояние может сохраняться дольше.

Устранение проблем

Бот не видит подписку пользователя

  1. Убедитесь, что бот является администратором канала
  2. Проверьте channel_id — должен быть в формате -100... (числовой ID, не username)
  3. Если канал только что добавлен — подождите до 60 секунд (кэш списка каналов)

Пользователь подписан, но бот не пропускает

  1. Нажмите «Я подписался» — это инвалидирует кэш и делает свежий запрос к API
  2. Если проблема сохраняется — проверьте логи бота на ошибки TelegramForbiddenError (бот удалён из канала)

Подписка не деактивируется при отписке от канала

  1. Проверьте CHANNEL_DISABLE_TRIAL_ON_UNSUBSCRIBE=true или CHANNEL_REQUIRED_FOR_ALL=true
  2. Платные подписки (с реальными платежами) не деактивируются при CHANNEL_DISABLE_TRIAL_ON_UNSUBSCRIBE — только при CHANNEL_REQUIRED_FOR_ALL
  3. Проверьте, получает ли бот ChatMemberUpdated события (бот должен быть админом)
Deeplink хранится в Redis (TTL 1 час). Если пользователь подписался через час+ после перехода по ссылке — deeplink мог истечь.