Разработка · 9 мин чтения

Телеграм бот подписка на канал: доступ, продление и отписка

Телеграм бот подписка на канал: у меня это одна из самых частых задач по автоматизации закрытых сообществ. Автору канала надоедает вручную сверять переводы в личных сообщениях со списком участников, и он хочет, чтобы бот сам пускал оплативших, продлевал доступ и убирал тех, кто перестал платить. Разбираю техническую сторону: как устроен допуск через инвайт-ссылки и заявки на вступление, как связать оплату с выдачей доступа, что делать с продлением и как аккуратно отписать человека, если он перестал платить.

Как устроен доступ: инвайт-ссылки и заявки на вступление

Бот не может напрямую «добавить» пользователя в приватный канал по его id, зато у Telegram Bot API есть два рабочих механизма, и оба я использую в разных проектах в зависимости от задачи.

Первый вариант: бот генерирует одноразовую инвайт-ссылку методом createChatInviteLink сразу после оплаты, с параметром member_limit равным единице и коротким сроком действия expire_date, например 10-15 минут. Ссылка приходит в личные сообщения, человек по ней входит в канал, и повторно ей уже никто не воспользуется, даже если случайно перешлёт другу.

Второй вариант: ссылка создаётся один раз с параметром creates_join_request и живёт постоянно, но по ней не входят автоматически, а подают заявку на вступление. Бот ловит событие заявки, сверяет user_id с базой оплативших и вызывает approveChatJoinRequest или declineChatJoinRequest. Этот способ удобнее, если оплата приходит с задержкой, заявка просто повисит до подтверждения, а не потеряется.

Для обоих сценариев боту нужны права администратора канала с возможностью приглашать пользователей и банить участников. Без этого создание ссылок и последующее удаление подписчиков просто не сработает, а ошибка Telegram в ответ будет не самой понятной.

Вот как это выглядит в коде на aiogram, если упростить до сути:

from aiogram import Bot

bot = Bot(token="BOT_TOKEN")

async def grant_access(user_id: int, chat_id: int) -> str:
    link = await bot.create_chat_invite_link(
        chat_id=chat_id,
        member_limit=1,
        name=f"sub-{user_id}",
    )
    return link.invite_link

async def revoke_access(user_id: int, chat_id: int) -> None:
    await bot.ban_chat_member(chat_id=chat_id, user_id=user_id)
    await bot.unban_chat_member(chat_id=chat_id, user_id=user_id, only_if_banned=True)

Метод ban_chat_member в канале работает как исключение участника, отдельного «ограничения» для каналов в Bot API нет. Сразу за баном я вызываю unban с флагом only_if_banned, чтобы человек не попал в постоянный чёрный список и мог вернуться после следующей оплаты.

Бота нужно куда-то посадить и держать постоянно включённым, иначе платёж пройдёт, а доступ никто не выдаст. Aiogram одинаково хорошо работает и в режиме long polling, когда бот сам постоянно опрашивает Telegram, и через вебхук, если у вас уже есть домен с HTTPS. Для одного бота с платной подпиской обычно достаточно недорогого VPS под сам процесс бота: это отдельный сервер, который придётся самостоятельно продлевать, обновлять и следить за сертификатом, на общем хостинге сайта фоновый процесс так просто не запустить. А вот обработчик вебхука от эквайринга и саму базу подписчиков вполне можно оставить на обычном хостинге, если он поддерживает PHP и MySQL, отдельный сервер под них не нужен.

Похожим образом устроена и обработка заявок на вступление, если выбрать второй сценарий допуска:

@dp.chat_join_request()
async def handle_join_request(request):
    if await is_paid(request.from_user.id):
        await request.approve()
    else:
        await request.decline()

Оплата доступа: Telegram Stars и обычный эквайринг

У Telegram есть собственный механизм платных подписок на каналы через внутреннюю валюту Stars: пользователь покупает звёзды прямо в приложении и оплачивает подписку без сторонней платёжной формы. Это удобно тем, что не нужен отдельный процессинг и договор с банком, но у продавца остаётся не рублёвая выручка, а звёзды, и часть аудитории просто не привыкла ими пользоваться.

Поэтому для русскоязычных каналов чаще делаю связку с обычным эквайрингом: пользователь платит картой через форму ЮKassa или Т‑Банка, платёжная система шлёт вебхук на бэкенд, а бэкенд по факту успешной оплаты обращается к боту и выдаёт доступ описанным выше способом. Это разработка на PHP или Python в зависимости от того, где уже крутится остальная инфраструктура клиента, отдельный сервер под простой обработчик вебхука не нужен, обычного хостинга достаточно.

Способ оплаты В какой валюте продавец получает деньги Повторное списание за новый период
Telegram Stars Звёзды (внутренняя валюта Telegram) Поддерживается штатно на стороне платформы
Внешний эквайринг (ЮKassa, Т‑Банк) Рубли на расчётный счёт Нужен отдельный рекуррентный платёж, поддерживается не на всех тарифах эквайринга

Комиссия за приём платежей у каждого банка своя и зависит от тарифа, а не от того, продаёте вы подписку на канал или доступ к курсу. Точную ставку в статье не привожу, уточняйте у своего эквайера при подключении.

Бесплатный материал

🎁 Полезный скрипт в подарок

Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.

Без спама. Отписка в 1 клик.

Продление подписки и что делать при просрочке

Дата окончания доступа хранится в собственной базе, не в Telegram: у самого мессенджера нет способа спросить, когда у этого участника заканчивается подписка, это знание живёт только у вас. На каждого подписчика я держу запись: user_id, id последнего платежа, дата начала и дата окончания периода, статус.

Дальше нужен планировщик, который раз в сутки проверяет базу: у кого срок истекает через 1-3 дня, тем шлём напоминание через sendMessage с ссылкой на оплату, у кого срок истёк сегодня, тем сразу отзываем доступ через revoke_access. Такую проверку можно повесить обычным cron-заданием на хостинге, если бот и так живёт на своём сервере, а можно собрать в n8n, туда удобно вынести логику: раз в день дёрнуть базу, отфильтровать просроченных, вызвать вебхук бота, если помимо самого бота в схеме участвуют ещё CRM или таблица учёта.

Отдельно продумываю, что происходит в момент продления: если человек оплатил заранее, до истечения текущего периода, новая дата окончания должна прибавляться к старой, а не пересчитываться от текущего момента, иначе продление за день до конца съедает у пользователя уже оплаченные дни.

Если платёж не прошёл при автосписании за новый период (карта заблокирована, кончился срок действия, недостаточно средств), большинство эквайрингов присылают об этом отдельный вебхук с отказом. На такой случай у меня обычно заведён короткий грейс-период в 1-2 дня: доступ не отзывается мгновенно, а бот присылает подписчику сообщение с просьбой обновить карту или оплатить вручную, и только если за это время платёж так и не проходит, включается обычный сценарий отзыва доступа.

Отписка и удаление из канала без лишней переписки

Отписка бывает двух видов, и их стоит различать в логике бота. Первый вариант: пользователь сам решает не продлевать. Тогда ничего специально отзывать не нужно, доступ закончится в дату истечения по уже описанному сценарию, а до этого момента подписчик пользуется каналом в полном объёме, за который заплатил.

Второй вариант: принудительный отзыв прямо сейчас, например по возврату платежа или по жалобе. Здесь работает та же пара ban_chat_member и unban_chat_member, только вызывается не по расписанию, а сразу из обработчика возврата.

Стоит поймать ещё один момент: пользователь может выйти из канала сам, не отменяя подписку. Telegram присылает боту апдейт об изменении статуса участника, и по нему в базе стоит пометить подписку как приостановленную вручную, а не тихо продолжать списывать деньги за канал, из которого человек уже ушёл.

У подписчиков в базе хранятся персональные данные: id пользователя, история платежей, статус подписки. По 152-ФЗ такие данные нужно держать на серверах в России, поэтому под них стоит завести свою базу на хостинге или сервере, а не тащить всё в Google Sheets или Airtable ради скорости.

Частые технические ловушки при разработке такого бота

За несколько подобных проектов набрался список вещей, на которых легко споткнуться.

  • Инвайт-ссылка без ограничения member_limit и с длинным сроком действия расходится по друзьям оплатившего, решается лимитом в одного человека и коротким временем жизни ссылки, либо сценарием с заявками на вступление вместо прямой ссылки.
  • Боту не выданы права администратора на приглашение и бан участников, без этого методы create_chat_invite_link и ban_chat_member просто вернут ошибку доступа.
  • Канал был открытым, а потом стал приватным с платной подпиской, старые участники, которые никогда не платили, остаются внутри, если заранее не сверить список участников с базой оплативших и не почистить его вручную перед запуском.
  • Продление считается от текущей даты, а не от даты окончания предыдущего периода, из-за этого активные подписчики теряют уже оплаченные дни при раннем продлении.
  • Отзыв доступа только через ban без последующего unban, человек формально забанен навсегда и не может вернуться в канал даже после новой оплаты.

Перед тем как подключать бота к боевому каналу, я всегда прогоняю всю цепочку на тестовом канале и тестовом платеже: создаю приватный канал-дубль, добавляю туда бота с теми же правами и прохожу сценарий оплаты, выдачи ссылки, продления и отзыва доступа от начала до конца. Так вылезают ошибки вроде забытых прав администратора или неверно посчитанной даты окончания подписки, пока это не задело ни одного живого подписчика.

Сколько стоит разработать бота с платной подпиской

Такой бот подразумевает не просто отправку сообщения по кнопке, а связку из логики Telegram Bot API, базы подписчиков и интеграции с оплатой, поэтому оценивается отдельно от простых ботов-опросников. У меня разработка телеграм-бота с платной подпиской начинается от 30 000 ₽, конкретная сумма зависит от того, нужен ли отдельный сервер для бота или он поместится на существующий хостинг, сколько тарифов подписки предполагается и с каким эквайрингом или CRM его нужно связать.

Если у канала уже есть эквайринг или CRM, куда нужно только подключить бота, это дешевле, чем поднимать всю цепочку с нуля: платёжную форму, вебхук, базу и саму логику доступа.

Обычно в объём работ входит сам бот, база подписчиков, интеграция с одним эквайрингом или с Telegram Stars, сценарий продления и отписки. Если нужно сначала прикинуть, какой вариант архитектуры подойдёт под конкретный канал и тарифы подписки, я беру за это отдельную консультацию от 3 000 ₽, и дальше она засчитывается в стоимость проекта, если доходит до разработки.

Условия и возможности Telegram меняются, поэтому перед запуском я уточняю их у самого сервиса.

Частые вопросы

Нужно ли оформлять ИП для приёма оплаты за подписку на канал?

Если принимаете рубли через обычный эквайринг, деньги должны поступать на счёт ИП, самозанятого или юрлица, принимать оплату за подписку на личную карту физлица юридически рискованно. При оплате через Telegram Stars у продавца другая схема расчётов внутри платформы, и точную юридическую конструкцию под свою ситуацию лучше проговорить с бухгалтером до запуска, а не после первых платежей.

Как бот узнаёт, что человек оплатил, и сразу выдаёт доступ?

Платёжная система, например ЮKassa или Т‑Банк, при успешной оплате отправляет вебхук на ваш сервер. Обработчик вебхука проверяет подпись запроса, находит нужного пользователя по id платежа, обновляет дату окончания подписки в базе и обращается к боту, чтобы тот создал инвайт-ссылку или одобрил заявку на вступление. Обычно вся эта цепочка отрабатывает за несколько секунд.

Что будет, если подписчик выйдет из канала сам, а потом захочет вернуться?

Если подписка ещё активна по датам в базе, бот просто создаёт новую инвайт-ссылку или одобряет новую заявку, платить второй раз не нужно. Если подписка уже истекла, человек проходит обычный сценарий оплаты заново.

Можно ли сделать пробный период перед платной подпиской?

Да, технически это та же логика доступа, только дата окончания в базе выставляется не от даты оплаты, а от даты первого входа в канал, и без привязанного платежа. По истечении пробного периода бот отзывает доступ тем же ban_chat_member, если человек не перешёл на платную подписку.

Есть задача?

Обсудим в мессенджере

Расскажите, что нужно сделать — отвечу в течение 4 часов в рабочее время. Первая консультация бесплатно.

Продолжая пользование настоящим сайтом Вы выражаете своё согласие на обработку Ваших персональных данных (файлов куки) с использованием Yandex.Metrika.
Понятно