What are the filters? 💭
When we register a handler, we specify what command it should respond to, what type of message to accept, etc. For example:
@dp.message_handler(is_admin=True, commands=['kick'], commands_prefix='!/', chat_type=[ChatType.GROUP, ChatType.SUPERGROUP]) async def kick_user(message: Message):
As you can see, here the handler will be executed only when:
- this will be the kick command;
- the command starts with "!" or "/";
- The command is written in a group or supergroup.
These are all called filters. Somewhere deep in the library, handler registration takes place, where its filters are registered for each handler:
def register(self, handler, filters=None, index=None): """ Register callback Filters can be awaitable or not. :param handler: coroutine :param filters: list of filters :param index: you can reorder handlers """ from .filters import get_filters_spec spec = _get_spec(handler) if filters and not isinstance(filters, (list, tuple, set)): filters = [filters] filters = get_filters_spec(self.dispatcher, filters) record = Handler.HandlerObj(handler=handler, spec=spec, filters=filters) if index is None: self.handlers.append(record) else: self.handlers.insert(index, record)
If we look at what the handle decorator accepts, we will see the following:
and today we will learn to create a custom filter.
Create your own filters ✍️
First, we need to create a file in the filters folder, for example, admin.py
:
📦tgbot
┣ 📂filters
┃ ┣ 📜admin.py
┃ ┗ 📜init.py
and add the following code inside:
from aiogram import types from aiogram.dispatcher.filters import BoundFilter class IsAdminFilter(BoundFilter): key = 'is_admin' def __init__(self, is_admin): self.is_admin = is_admin async def check(self, message: types.Message) -> bool: member = await message.bot.get_chat_member(message.chat.id, message.from_user.id) return member.is_chat_admin()
As you can see, the filter is a simple Python class that inherits a BoundFilter class that allows us to create our own filters. We have a field key = 'is_admin'
that shows how we will describe our filter in the handlers. In addition to the structure, we have the main method async def check()
. You can describe any of your logic inside it, but this method must return a Boolean value (True or False).
Connecting own filters ⛓️
Simply creating a class is not enough. Next, you need to go to the bot.py
file, import out filter and bind it to the dispatcher:
... from tgbot.config import load_config from tgbot.services.setting_commands import set_default_commands from tgbot.filters.admin import IsAdminFilter ... def register_all_filters(dispatcher: Dispatcher) -> None: logger.info('Registering filters') dispatcher.filters_factory.bind(IsAdminFilter)
Now we can add our filter to the handlers as I showed in the first picture. In this article, we will not yet write handlers for administering chats.
Additional part 😺
For now, let's program the handlers for the two commands: /start
and /help
:
-
tgbot/handlers/start.py
:
from aiogram.types import Message from aiogram.dispatcher.filters.builtin import CommandStart from loader import dp @dp.message_handler(CommandStart()) async def start_command(message: Message) -> Message: return await message.answer('Add a bot to the chat, give the administrator permissions and use it')
-
tgbot/handlers/help.py
:
from aiogram.types import Message from aiogram.dispatcher.filters.builtin import CommandHelp from loader import dp @dp.message_handler(CommandHelp()) async def help_command(message: Message) -> Message: """ This handler will be called when a user sends `/help` command """ return await message.answer(""" User's command: /help - get commands /admins - get chat admins /dice - roll a dice Administrator's command: !kick - kick a user !ban - ban a user !mute - mute a user !unmute, !unban - opposite commands """)
Here, the decorators have already used filters built into aiogram. The entire list of such filters can be found here.
References 🔗
Thank you for reading! ❤️ ❤️ ❤️
Top comments (0)