Python aiogram inline callback does not work with active fms (state)

Рейтинг: -1Ответов: 3Опубликовано: 29.01.2023

Данная функция создает наши inline кнопки.

Без активной FMS(state) все работает корректно. Но, если я захожу в FMS(state), callback не отрабатывает

def delete_accept(user_id, mode_):

   data_base = db2.DB(user_id)
   word = data_base.select_data_(column_="temp_data", where_clmn="id", where_data=1)

   match mode_:

        case "delete":
            inline_button_1 = InlineKeyboardButton(text=f"{word[0][0]}", callback_data=f"replay_1")
            inline_button_2 = InlineKeyboardButton(text=f"Да", callback_data=f"replay_4")
            inline_button_3 = InlineKeyboardButton(text=f"Нет", callback_data=f"replay_5")

            inline_keyboard_delete = InlineKeyboardMarkup(row_width=1).add(inline_button_1)
            inline_keyboard_delete.row(inline_button_2, inline_button_3)

            return inline_keyboard_delete

        case "update":
            inline_button_1 = InlineKeyboardButton(text=f"{word[0][0]}", callback_data=f"replay_1")
            inline_button_2 = InlineKeyboardButton(text=f" Изменить eng", callback_data=f"replay_6")
            inline_button_3 = InlineKeyboardButton(text=f"Изменить rus", callback_data=f"replay_7")
            inline_button_4 = InlineKeyboardButton(text=f"Отмена", callback_data=f"replay_5")

            inline_keyboard_delete = InlineKeyboardMarkup(row_width=1).add(inline_button_1)
            inline_keyboard_delete.row(inline_button_2, inline_button_3)
            inline_keyboard_delete.row(inline_button_4)

            return inline_keyboard_delete

Вот мой обработчик для коллбеков

def register_handler_command_bu_inline(dp: Dispatcher):
     dp.register_callback_query_handler(manual, lambda call: call.data.startswith('replay'))

И собственно моя функция

async def manual(call: CallbackQuery):
# Change keyboard for test mode

   numb_button = call.data[-1]

   await call.message.edit_reply_markup(update_keyboard_main(numb_button, call.message.chat.id))

   await bot.answer_callback_query(call.id, text='✅')

На нескольких формух находил похожие вопросы, но ответов на них не было.

Ответы

▲ 0

Вот таким образом Вы можете создать inline-button в режиме FMS:

from aiogram import Bot, types
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor

bot = Bot(token='TOKEN')
dp = Dispatcher(bot)


@dp.message_handler(commands=['start'])
async def process_start_command(message: types.Message):
    inline_kb = types.InlineKeyboardMarkup()
    btn = types.InlineKeyboardButton(text='Нажми меня', callback_data='test')
    inline_kb.add(btn)
    await bot.send_message(message.chat.id, 'Нажми кнопку.', reply_markup=inline_kb)


@dp.callback_query_handler(lambda c: c.data == 'test')
async def process_callback_button1(call: types.CallbackQuery):
    await bot.send_message(call.from_user.id, '✅')

if __name__ == '__main__':
    executor.start_polling(dp)

▲ 0

Как создать callback - это понятно. Проблема в том, что когда переводишь бот в режим FMS аля:

class MyState(StatesGroup):
c_chat_id = State()
....
await FSMAdmin.c_chat_id.set()

После этого запроса, пока не финишируешь машину состояний state.finish() ни один callback не работает. Т.е. возможности "нормально" передать переменные между функциями нет...

▲ 0

Вся проблема в том, что по умолчанию при регистрации хэндлеров параметр state=None. Нужно проставить state='*' или конкретный, который вам нужен, при его регистрации.

С помощью декораторов из aiogram будет так:

@dp.callback_query_handler(state='*')

Непосредственно через метод диспетчера из aiogram:

dispatcher.register_callback_query_handler(handler.inovke, handler.query, run_task=True, state='*')