Задать вопрос
@Arniss472

Почему фильтр в aiogram cрабатывает сразу на всех инлайн кнопках?

Есть кастомный фильтр aiogram, который создан через класс BoundFilter. Он устанавливает суточный лимит на некоторые запросы к боту и он работает корректно с командами, но когда дело касается колбэков, то при нажатии на кнопку срабатывают сразу все и соответственно в чат приходит сразу несколько сообщений, с предупреждением о лимите.

как это работает и можно ли это как-то исправить?

Код фильтра
from typing import Optional, Union
from datetime import datetime, timedelta

from aiogram.dispatcher.filters import BoundFilter
from aiogram import types

from app.services.users import UserService


class LimitRequest(BoundFilter):
    key = 'limit'
    datetime_limit = datetime.now() + timedelta(days=1)

    limit_dict: dict[str, int] = {}
    msg_datetime: datetime

    def __init__(self, limit: Optional[bool] = None):
        self.limit = limit

    @staticmethod
    async def _get_limit_count(call: types.CallbackQuery) -> int:
        async with UserService(call.from_user.id) as us:
            user_db = await us.get()
            limit_count = user_db['limit_count']
            return limit_count

    @staticmethod
    async def _get_limit(call: types.CallbackQuery) -> bool:
        async with UserService(call.from_user.id) as us:
            user_db = await us.get()
            is_limit = user_db['limit']
            return is_limit

    async def _check_update_datetime(self, call: types.CallbackQuery):
        self.msg_datetime = call.message.date
        if self.msg_datetime >= self.datetime_limit:
            return False
        return True

    async def check(self, call: types.CallbackQuery) -> Optional[bool]:
        is_limit = await self._get_limit(call)
        limit_count = await self._get_limit_count(call)

        if self.limit is None or not isinstance(is_limit, bool):
            return False

        if is_limit:
            if call.from_user.id not in self.limit_dict:
                self.limit_dict[call.from_user.id] = 0
                return True

            elif not await self._check_update_datetime(call):
                self.datetime_limit = self.msg_datetime
                self.limit_dict[call.from_user.id] = 0
                return True

            else:
                self.limit_dict[call.from_user.id] += 1
                if self.limit_dict[call.from_user.id] >= limit_count:
                    self.limit_dict[call.from_user.id] = limit_count
                    await call.message.answer('Превышен суточный лимит действий.\n'
                                              'Вы можете отключить лимит, если пригласите 2-х друзей.')
                    return False
                return True


Регистрирую его в боте:
dp.filters_factory.bind(LimitRequest)

Включаю фильтр при регистрации хэндлеров

def register_handlers_wildberries(dp: Dispatcher):
    dp.register_callback_query_handler(
        edit_name_card, action_cb.filter(action='edit_name'), limit=True, state='*'
    )
    dp.register_callback_query_handler(
        edit_price_card, action_cb.filter(action='edit_price'), limit=True, state='*'
    )
    dp.register_callback_query_handler(
        show_stocks, action_cb.filter(action='show_stocks'), limit=True
    )


Скрин вывода
62c5ed0a69708796604507.jpeg
  • Вопрос задан
  • 254 просмотра
Подписаться 2 Простой 2 комментария
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы