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

Как можно предотвратить обработку нажатия на другие кнопки, пока не будет обработано нажатие на одну из них ботом, который выводит сообщение с 8 кнопками?
  • 30 апреля 2024 г. 9:30
Ответы на вопрос 2
Для добавления ограничений на количество раз, которое можно нажать на кнопку в боте с использованием aiogram, можно использовать переменную для подсчета количество нажатий на кнопку и проверять ее значение перед обработкой нажатия. Например:

```python
from aiogram import Bot, Dispatcher, types
from aiogram.dispatcher import FSMContext
from aiogram.contrib.middlewares.logging import LoggingMiddleware
from aiogram import executor

API_TOKEN = 'YOUR_API_TOKEN'

bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)
limit = 5

@dp.message_handler(commands=['start'])
async def start(message: types.Message):
    await message.answer("Нажмите на кнопку", reply_markup=get_keyboard())

def get_keyboard():
    keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
    buttons = [types.KeyboardButton(text=f'Button {i}') for i in range(1, 9)]
    keyboard.add(*buttons)
    return keyboard

limit_counter = {}

@dp.message_handler(lambda message: message.text.startswith('Button'))
async def button_click_handler(message: types.Message):
    if message.text in limit_counter and limit_counter[message.text] >= limit:
        await message.answer(f'Превышено ограничение по количеству нажатий на кнопку "{message.text}"')
    else:
        if message.text not in limit_counter:
            limit_counter[message.text] = 1
        else:
            limit_counter[message.text] += 1

        await message.answer(f'Вы нажали на кнопку "{message.text}" {limit_counter[message.text]} раз')

if __name__ == '__main__':
    executor.start_polling(dp, skip_updates=True)
```

Чтобы предотвратить обработку нажатия на другие кнопки, пока не будет обработано нажатие на одну из них, можно использовать FSM (finite state machine) контекст в aiogram. Создайте отдельное состояние для обработки нажатия на кнопку и в это состояние переходите сразу после нажатия на одну из кнопок. Пока состояние активно, блокируйте обработку других сообщений.

Пример:

```python
from aiogram import Bot, Dispatcher, types
from aiogram.dispatcher import FSMContext
from aiogram.contrib.middlewares.logging import LoggingMiddleware
from aiogram import executor

API_TOKEN = 'YOUR_API_TOKEN'

bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)
state = None

@dp.message_handler(commands=['start'])
async def start(message: types.Message):
    global state
    state = True
    await message.answer("Выберите одну из кнопок", reply_markup=get_keyboard())

def get_keyboard():
    keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
    buttons = [types.KeyboardButton(text=f'Button {i}') for i in range(1, 9)]
    keyboard.add(*buttons)
    return keyboard

@dp.message_handler(lambda message: message.text.startswith('Button'))
async def button_click_handler(message: types.Message, state: FSMContext):
    global state
    if state:
        await message.answer(f'Вы нажали на кнопку "{message.text}"')
        await state.finish()
        state = None

if __name__ == '__main__':
    executor.start_polling(dp, skip_updates=True)
```

В этом примере, после нажатия на одну из кнопок, состояние state становится активным и блокирует обработку других сообщений, пока не будет обработано нажатие на кнопку. После обработки нажатия состояние завершается и обработка других сообщений возобновляется.
Со стороны телеграмма никак. 

Но есть вариант, использовать FSMContext для их проверки.

К примеру нажал человек на кнопку, в этой кнопке меняем информацию о состоянии, создавая ключ pressed=True и при нажатии на другие кнопки, получаем текущее состояние пользователя и проверяем её информацию на наличие ключа pressed.
Похожие вопросы