Почему не работает FSM(state) при channel_post_handler?
При нажатии на кнопку бот отправляет сообщение с просьбой указать название (название отправляю в ответ), записывая message_data (для примера), дальше через через state должен вызываться обработчик постов в канале, но этого не происходит(в коде не отправляет последний print "test handler"). Если использовать без state все работает, так же если использовать это в самом боте через message_handler тоже все работает. Почему не работает и как можно использовать FSM для сообщений в канале, ибо нужно сохранять несколько подряд сообщений от туда при нажатии кнопки.
@dp.callback_query_handler(text='test_video')
async def test_video(call: types.CallbackQuery, state: FSMContext):
message_data = await bot.send_message(chat_id=call.message.chat.id, text='Хорошо теперь отправь мне название', reply_markup= ikb_back)
async with state.proxy() as data:
data['message_data'] = message_data
print("test set") # отправляет
await astate.Admin_State.test_video.name.set()
@dp.channel_post_handler(state=astate.Admin_State.test_video.name)
async def print_test_video(message: types.Message, state: FSMContext):
print("test handler") # не отправляет
Ответы (1 шт):
FSMContext устроен так, что для каждого диалога хранит свой контекст — вы упустили это. После нажатия на кнопку в одном диалоге активировался нужный вам state, который вы потом пытаетесь поймать уже в другом диалоге — канале, для которого этот state не задан. Перенести контекст одного диалога в контекст другого — так сделать не получится.
Тогда, сообщение, в котором находится кнопка test_video, тоже должно быть отправлено в канал. Либо же, наоборот, как вы сделали, считывать сообщения не из канала, а из того же диалога при помощи message_handler.
Чтобы решить проблему, с которой вы столкнулись, вам необходим пустой хэндлер сообщений из канала и внешняя переменная, в которой вы будете хранить необходимое вам состояние:
get_video_name = False
@dp.callback_query_handler(text='test_video')
async def test_video(call: types.CallbackQuery):
message_data = await bot.send_message(chat_id=call.message.chat.id, text='Хорошо теперь отправь мне название', reply_markup= ikb_back)
async with state.proxy() as data:
data['message_data'] = message_data
print("test set") # отправляет
get_video_name = True
@dp.channel_post_handler()
async def print_test_video(message: types.Message):
if get_video_name:
print("test handler") # не отправляет
get_video_name = False
Конечно, не очень уместно делать так, как это сделал я. Хранить какие бы то ни было данные в виде глобальных переменных — не совсем хорошая практика, и гораздо лучше, если у вас есть какая-то БД или в крайнем случае JSON-файл, где вы могли бы это хранить.