Вызов функция по порядку не происходит, потому что параметр context_type = ['text']. Aiogram Python
Всем привет! Картина выглядит примерно так : Я делаю телеграм-бота , у которого есть функционал для пользователя (некого рабочего), который в конце смены делает отчет о проделанной им работе. Чтобы записать данные о проделанной работе , в телеграм боте есть "Меню" , из которого он выбирает по некому "дереву" данные для заполнения лога . Дерево выглядит примерно так [Изделие -> детали->тех. процесс с деталью -> количество сделанных деталей], все кнопки генерируются динамически, в зависимости от выбора предыдущего пункта юзера, а данные для генерации берутся из БД. Я столкнулся с проблемой , что функция не переходит на следующий этап , потому что в context_type в 3х декораторах стоит параметр ['text'] , однако я не могу захардкодить эту часть кода. Потому что предполагается , что не известно , какой выбор сделает юзер.
Вопрос : Как сделать так , чтобы после завершения изменения состояния одного параметра , вызывалась следующая функция.
@dp.message_handler(text=["Отчёт о работе"])
async def add_item(message: types.Message):
await WorkReport.product.set()
await message.answer(text="Выбери изделие", reply_markup=kb.product_name_panel)
@dp.callback_query_handler(state=WorkReport.product)
async def add_item_product(call: types.CallbackQuery, state: FSMContext):
async with state.proxy() as data:
data['product'] = call.data
await call.message.answer(text="Выбери деталь", reply_markup=kb.DetailsOfProductButton(product_name=call.data))
await WorkReport.next()
@dp.message_handler(content_types=['text'], state=WorkReport)
async def add_item_detail(message: types.Message, state: FSMContext):
async with state.proxy() as data:
data['detail'] = message.text
await message.answer(text="Выбери операцию", reply_markup=kb.PartOperationButton(data['product'], data['detail']))
await WorkReport.next()
@dp.message_handler(content_types=['text'], state=WorkReport)
async def add_item_operation(message: types.Message, state: FSMContext):
async with state.proxy() as data:
data['operation'] = message.text
await WorkReport.next()
@dp.message_handler(content_types=['text'], state=WorkReport)
async def add_item_amount(message: types.Message, state: FSMContext):
async with state.proxy() as data:
data['amount'] = message.text
await state.finish()
Ответы (1 шт):
Дело не в content_types=['text'], его можно даже не указывать. Проблема в том, что в хэндлере вы указываете не состояние, а саму машину состояний. Ваша FSM должна выглядеть так:
class WorkReport(StatesGroup):
product = State()
detail = State()
operation = State()
amount = State()
а дальше вы уже должны указывать нужный state для хэндлера.
Ваш код должен выглядеть как-то так:
@dp.message_handler(text=["Отчёт о работе"])
async def add_item(message: types.Message):
await WorkReport.product.set()
await message.answer(text="Выбери изделие", reply_markup=kb.product_name_panel)
@dp.callback_query_handler(state=WorkReport.product)
async def add_item_product1(call: types.CallbackQuery, state: FSMContext):
async with state.proxy() as data:
data['product'] = call.data
await call.message.edit_text(text="Выбери деталь", reply_markup=kb.DetailsOfProductButton(product_name=call.data))
await WorkReport.next()
@dp.callback_query_handler(state=WorkReport.detail)
async def add_item_detail(call: types.CallbackQuery, state: FSMContext):
async with state.proxy() as data:
data['detail'] = call.data
await call.message.edit_text(text="Выбери операцию", reply_markup=kb.PartOperationButton(data['product'], data['detail']))
await WorkReport.next()
@dp.callback_query_handler(state=WorkReport.operation)
async def add_item_operation(call: types.CallbackQuery, state: FSMContext):
async with state.proxy() as data:
data['operation'] = call.data
await call.message.answer(text="Укажите количество")
await WorkReport.next()
@dp.message_handler(state=WorkReport.amount)
async def add_item_amount(message: types.Message, state: FSMContext):
async with state.proxy() as data:
data['amount'] = message.text
await message.answer(f"Вы выбрали:\n{data['product']}\n{data['detail']}\n{data['operation']}\n{data['amount']}")
await state.finish()
Из вашего кода не понятно как именно вы генерируете клавиатуру, но указанная выше FSM подразумевает, что для product, detail и operation клавиатура будет генерироваться, а amount пользователь вводит вручную