diff --git a/aiogram/dispatcher/handler.py b/aiogram/dispatcher/handler.py index 10a94924..44bb15d2 100644 --- a/aiogram/dispatcher/handler.py +++ b/aiogram/dispatcher/handler.py @@ -22,6 +22,10 @@ class CancelHandler(Exception): pass +class SkipRequest(Exception): + pass + + def _get_spec(func: callable): while hasattr(func, '__wrapped__'): # Try to resolve decorated callbacks func = func.__wrapped__ diff --git a/aiogram/dispatcher/middlewares.py b/aiogram/dispatcher/middlewares.py index 5fa09830..b2607443 100644 --- a/aiogram/dispatcher/middlewares.py +++ b/aiogram/dispatcher/middlewares.py @@ -1,5 +1,9 @@ import logging import typing +from aiogram import Bot +from aiogram.types import base +from aiogram.utils.helper import HelperMode +from aiogram.dispatcher.handler import SkipRequest log = logging.getLogger('aiogram.Middleware') @@ -106,6 +110,31 @@ class BaseMiddleware: await handler(*args) +class RequestMiddleware(BaseMiddleware): + bot: Bot + orig_request: typing.Callable + + def setup(self, manager: MiddlewareManager): + self._manager = manager + self._configured = True + bot = manager.dispatcher.bot + self.orig_request = bot.request + bot.request = self.request + + async def request(self, method: base.String, + data: typing.Optional[typing.Dict] = None, + files: typing.Optional[typing.Dict] = None, **kwargs + ) -> typing.Union[typing.List, typing.Dict, base.Boolean]: + handler_name = f"on_{HelperMode.apply(method, HelperMode.snake_case)}" + handler = getattr(self, handler_name, None) + if handler: + try: + await handler(data, files, **kwargs) + except SkipRequest: + return {} + return await self.orig_request(method, data, files) + + class LifetimeControllerMiddleware(BaseMiddleware): # TODO: Rename class