Не регестрируются колбэки aiogram 3.0
Пишу бота для розыгрышей (первый мой проект на аиограм 3), регестрировал колбэки через dp.callback_query.register()
. Сейчас решил разбить код по роутерам. Хэнделры регестрирует спокойно, а вот колбэки не очень. Пробовал закоментировать навешивание мидлварей, не помогло.
Один из роутеров:
channel_router = Router(name="channel_router")
Его хэндлеры:
class ChannelStates(StatesGroup):
add_channel = State()
@channel_router.message(ChannelStates.add_channel, HasChannelNamesFilter())
async def add_channel_handler(message: Message, state: FSMContext, database: Database, channel_name: str, user_keyboards: UserKeyboardsBuilder) -> None:
"""Waits for user to enter channel id and adds it to user list
Args:
message (Message): message from user
state (FSMContext): state
"""
if not channel_name:
logging.info(f"User entered uncorrect channel name: {message.text}")
await message.answer(await get_text(database=database, key="invalid_channel_id", user_id=message.from_user.id), reply_markup=await user_keyboards.create_cancel_action_keyboard(database = database, user_id=message.from_user.id))
return
channel_meets_requiriments = await check_channel(channel_handle=channel_name, user_id=message.from_user.id)
logging.info(f"Checked channel for adding/deleting requiriments: {channel_meets_requiriments}")
if channel_meets_requiriments:
channel_info = await fetch_channel_info(channel_handle=channel_name, bot_token=fetch_bot_token())
channel_data = parse_channel_data(response=channel_info, user_id=message.from_user.id)
channel_exists = await check_channel_in_db(admin_id=message.from_user.id, channel_handle=channel_name, databse=database)
if not channel_exists:
await database.add_channel(channel_data=channel_data)
await message.answer(await get_text(database=database, key="confirm_channel_id", user_id=message.from_user.id))
await state.clear()
else:
await message.answer(await get_text(database=database, key="channel_is_already_exist", user_id=message.from_user.id), reply_markup=await user_keyboards.create_cancel_action_keyboard(database = database, user_id=message.from_user.id))
else:
await message.answer(await get_text(database=database, key="channel_req_failed", user_id=message.from_user.id), reply_markup=await user_keyboards.create_cancel_action_keyboard(database = database, user_id=message.from_user.id))
Его колбэки:
import logging
from aiogram import F
from aiogram.types import CallbackQuery
from aiogram.fsm.context import FSMContext
from bot.utils.db import Database
from bot.utils.languages import get_text
from bot.handlers.channel_handlers import ChannelStates, channel_router
from bot.keyboards.user_keyboards import UserKeyboardsBuilder
from bot.keyboards.channel_keyboard import ChannelKeyboardsBuilder
@channel_router.callback_query(F.data.startswith("channel"))
async def manage_channels_callback(call: CallbackQuery, state: FSMContext, database: Database, user_keyboards: UserKeyboardsBuilder, channel_keyboards: ChannelKeyboardsBuilder):
"""Form user's choice stars channel adding or deleting process
Args:
call (CallbackQuery): call form pressed button
state (FSMContext): current bot state
"""
logging.info("Callback function called -- 'manage_channels_callback'")
option = call.data.split('_')[1]
logging.info(f"Chosen option: {option}")
user_id = call.from_user.id
if option == "add":
await call.message.answer(await get_text(database=database, key="add_channel_btn_reply", user_id=user_id), reply_markup=await user_keyboards.create_cancel_action_keyboard(database = database, user_id=call.from_user.id))
await state.set_state(ChannelStates.add_channel)
logging.info("Set state to 'waiting for channel id'")
elif option == "remove":
await call.message.answer(await get_text(database=database, key="remove_channel_btn_reply", user_id=user_id), reply_markup=await channel_keyboards.create_delete_channel_keyboard(database = database, user_id=call.from_user.id))
await call.answer()
@channel_router.callback_query(F.data.startswith("?@"))
async def delete_channel_callback(call: CallbackQuery, state: FSMContext, database: Database):
"""Deletes channel from user's channel_list
Args:
call (CallbackQuery): call from pressed button with channel_handle
state (FSMContext): current bot state
"""
channel_handle = call.data.replace("?","")
await database.delete_channel(channel_handle=channel_handle)
await call.message.answer(await get_text(database=database, key="confirm_channel_id", user_id=call.from_user.id))
await state.clear()
await call.answer()
main.py и точка входа:
import asyncio
import logging
from aiogram import Bot, Dispatcher
from bot.handlers.user_handlers import user_router
from bot.handlers.channel_handlers import channel_router
from bot.handlers.giveaway_handlers import giveaway_router
from bot.middlewares.database import DatabaseMiddleware
from bot.middlewares.keyboards import UserKeyboardsMiddleware, ChannelKeyboardsMiddleware, GiveawayKeyboardsMiddleware
from bot.utils.set_bot_commands import set_bot_commands
from bot.utils.fetch_data.fetch_bot_data import fetch_bot_token
logging.basicConfig(level=logging.INFO)
bot_token = fetch_bot_token()
bot = Bot(bot_token)
async def set_bot(bot:Bot):
"""Creates bot and Dispatcher, sets menu section and user handlers
Args:
bot_token (str): API bot token
"""
dp = Dispatcher()
dp.update.middleware(DatabaseMiddleware())
dp.update.middleware(UserKeyboardsMiddleware())
dp.update.middleware(ChannelKeyboardsMiddleware())
dp.update.middleware(GiveawayKeyboardsMiddleware())
dp.include_routers(channel_router, giveaway_router, user_router)
await set_bot_commands(bot)
return dp
async def start_bot(dp:Dispatcher, bot: Bot):
"""Starts bot
Args:
dp (Dispatcher): bot's dipatcher
bot (Bot): bot object created with api token
"""
try:
await dp.start_polling(bot)
except Exception as ex:
logging.error(f"An exception occured - {ex}", exc_info=True)
pass
async def main():
"""Entry point"""
dp = await set_bot(bot)
await start_bot(dp, bot)
if __name__ == "__main__":
asyncio.run(main())
Диспетер видит все роутеры, все роутеры видят свои хэндлеры, а вот колбэки упорно не замечают. В чем может быть дело?
Во время разбивки кода на роутеры навешивал декораторы на хэндлеры и колбэки. Хэндлеры работают исправно, но ни одна инлайн конпка не работает
Ответы (1 шт):
Как я понял, дело было в импортах. Роутеры импортировались из файла с хэндлерами, а вот файл с колбэками никуда не импортировался. Доабавить импорты всех модулей с колбэками в main.py решило проблему:
from bot.handlers.user_handlers import user_router
from bot.handlers.channel_handlers import channel_router
from bot.handlers.giveaway_handlers import giveaway_router
import bot.callbacks.channel_callbacks
import bot.callbacks.user_callbacks
import bot.callbacks.giveaway_callbacks
async def set_bot(bot:Bot):
dp = Dispatcher()
dp.update.middleware(DatabaseMiddleware())
dp.update.middleware(UserKeyboardsMiddleware())
dp.update.middleware(ChannelKeyboardsMiddleware())
dp.update.middleware(GiveawayKeyboardsMiddleware())
dp.include_routers(channel_router, giveaway_router, user_router)
await set_bot_commands(bot)
return dp