Bot-Moderator for Telegram chats. Filters
Tags: beginners, python, telegram, bots
Published: 2022-09-01 11:26:01

## 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:

```py
@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:

1. this will be the kick command;
2. the command starts with "!" or "/";
3. 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:

```py
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:

![decorator preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fvfzdheh026hjya8oe64.PNG)

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:

```py
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**:

```py
...
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`:

```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`:

```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](https://github.com/aiogram/aiogram/blob/dev-2.x/aiogram/dispatcher/filters/builtin.py).

## References 🔗

- [Second part file structure](https://github.com/mezgoodle/devto-posts/tree/main/bot-moderator/second-part)

Thank you for reading! ❤️ ❤️ ❤️