Роутеры¶
Роутеры позволяют разделить хэндлеры по модулям и собрать их в одном боте.
Зачем роутеры?¶
Один файл быстро разрастается. Раздели по фичам:
Создание роутера¶
# handlers/start.py
from fastvk import Router, CommandStart
from fastvk.types import Message
router = Router()
@router.message(CommandStart())
async def start(message: Message) -> None:
await message.answer("Добро пожаловать!")
Подключение роутеров¶
# main.py
from fastvk import FastVK
from handlers.start import router as start_router
from handlers.catalog import router as catalog_router
from handlers.admin import router as admin_router
bot = FastVK(token="...", group_id=123)
bot.include_router(start_router)
bot.include_router(catalog_router)
bot.include_router(admin_router)
bot.run_polling()
Вложенные роутеры¶
Роутеры могут подключать другие роутеры:
from fastvk import Router
admin_router = Router()
admin_router.include_router(admin_messages_router)
admin_router.include_router(admin_callbacks_router)
bot.include_router(admin_router)
Фильтры на уровне роутера¶
Применить фильтр ко всем хэндлерам роутера:
from fastvk import Router
from myfilters import IsAdmin
admin_router = Router()
admin_router.message.filter(IsAdmin())
admin_router.callback.filter(IsAdmin())
@admin_router.message()
async def admin_panel(message: Message) -> None:
# выполняется только если IsAdmin() пройден
await message.answer("Панель администратора")
Полный пример¶
# handlers/catalog.py
from fastvk import Router, F
from fastvk.types import Message, CallbackQuery
from fastvk.keyboard import Button, Keyboard
router = Router()
catalog_kb = (
Keyboard(inline=True)
.row(Button.callback("Товар 1", payload={"item": 1}),
Button.callback("Товар 2", payload={"item": 2}))
)
@router.message(F.text == "Каталог")
async def catalog(message: Message) -> None:
await message.answer("Выбери:", keyboard=catalog_kb)
@router.callback(F.payload["item"].exists())
async def item_selected(callback: CallbackQuery) -> None:
item_id = callback.payload.get("item")
await callback.answer(f"Выбран товар #{item_id}")