Как сделать , чтобы кнопка 'подписался' проверяла на все ли каналы подписан пользователь и после этого пускала его к возможностям бота?

Это кнопки : sub_channel = InlineKeyboardMarkup(
    inline_keyboard =[
        [
            types.InlineKeyboardButton(text="1-й Канал?", url=""),
            types.InlineKeyboardButton(text="2-й Канал⚡️", url=""),
            types.InlineKeyboardButton(text="3-й Канал?", url=""),
            types.InlineKeyboardButton(text="Подписался✅", callback_data="check")
          
        ],
    ]
   

)

Это проверка на подписку :


class CheckSubscription(BaseMiddleware):
    async def __call__(self, handler, event, data) -> Any:
        channels = ["", "", ""]
        user_id = event.from_user.id

        for channel in channels:
            chat_member = await event.bot.get_chat_member(channel, user_id)
            if chat_member.status == 'left':
                await event.answer(
                    'Подпишись на все каналы, чтобы пользоваться ботом!',
                    reply_markup=sub_channel
                )введите сюда код
                return

        # Если пользователь подписан на все каналы
        return await handler(event, data)

Ответы (1 шт):

Автор решения: txello

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

Код написан на aiogram 3.x

from aiogram import Dispatcher, F
from aiogram.types import CallbackQuery

dp = Dispatcher()

dp.message.outer_middleware(CheckSubscription()) # Подключаем внешний мидлварь к хендлерам message
dp.callback_query.outer_middleware(CheckSubscription()) # Подключаем внешний мидлварь к хендлерам callback_query

@dp.callback_query(F.data == 'check') # Если была нажата кнопка "Подписался"
async def check_subs(callback: CallbackQuery):
    await callback.answer("Спасибо за подписки!")
→ Ссылка