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)