Skip to content

Фильтры

Фильтры решают, должен ли хэндлер обработать событие. Любой callable возвращающий истинное значение — проходит.

Встроенные фильтры

Command

from fastvk.filters import Command

Command("start")                          # совпадает с /start
Command("start", "help")                  # совпадает с /start или /help
Command("ban", prefix="/!")               # совпадает с /ban и !ban
Command("buy", prefix="/")               # совпадает с /buy

CommandStart / CommandHelp

from fastvk.filters import CommandStart, CommandHelp

@bot.message(CommandStart())
async def start_handler(message): ...

@bot.message(CommandHelp())
async def help_handler(message): ...

StateFilter

from fastvk.filters import StateFilter
from fastvk.fsm import State, StatesGroup

class Form(StatesGroup):
    waiting_name = State()

@bot.message(StateFilter(Form.waiting_name))
async def handler(message, state): ...

# совпадает с любым не-None состоянием:
@bot.message(StateFilter("*"))
async def any_state_handler(message): ...

Text

from fastvk.filters import Text

Text("hello")                # точное совпадение
Text("hello", "hi")          # любое из этих
Text(contains="world")       # совпадение подстроки
Text(startswith="!")          # совпадение с началом

F — Magic filter

F строит ленивые выражения фильтрации через доступ к атрибутам и операторы.

from fastvk import F

Доступ к атрибутам

F.text          # message.text
F.from_id       # message.from_id
F.payload       # callback.payload (dict)
F.payload.vote  # callback.payload["vote"]

Сравнения

F.text == "hello"
F.text != "bye"
F.from_id > 0

Строковые методы

F.text.startswith("/")
F.text.endswith("!")
F.text.contains("vk")
F.text.regexp(r"^\d+$")     # regex совпадение (re.search)

Принадлежность

F.from_id.in_(1, 2, 3)
F.text.in_("yes", "да", "y")

Существование

F.payload.exists()    # значение не None
F.text.exists()

Логика

~F.text.startswith("/")              # НЕ
(F.text == "a") | (F.text == "b")   # ИЛИ
(F.from_id > 0) & F.text.exists()   # И

Кастомные фильтры

Подходит любой callable:

def is_admin(message: Message, data: dict) -> bool:
    return message.from_id in ADMIN_IDS

@bot.message(is_admin)
async def admin_cmd(message): ...

Или класс:

class IsAdmin:
    def __init__(self, *ids: int) -> None:
        self._ids = set(ids)

    def __call__(self, message: Message, data: dict) -> bool:
        return message.from_id in self._ids

@bot.message(IsAdmin(111, 222))
async def admin_cmd(message): ...