Диалог через telegram бота между двумя пользователями в определенном состоянии FSM. Aiogram 3
Я пишу бота, используя библиотеку aiogram 3.4. И столкнулся со следующей проблемой. Мне нужно сделать диалог между одним пользователем и другим в течение определенного периода времени. Для этого мне нужно знать id обоих пользователей. Переход к диалогу должен осуществляться после нажатия на inline кнопку. Id обоих пользователей хранятся в базе данных. Я пытался сделать это через FSM, но состояние другого пользователя будет другим (сброшенным). FSM-стратегию я не могу сделать типа GLOBAL, так как она будет мешать другим функциям.
По идее, обработчик, отправляющий сообщения, должен находиться в состоянии FSM, установленном при нажатии inline кнопки. Но в этом случае непонятно, что делать со вторым пользователем. Как передать ему данные id обоих пользователей? Может быть, кто-то может подсказать способ копирования данных состояния одного пользователя в данные другого, если это возможно? Или какой-то другой вариант через промежуточное ПО?
Вторая идея, которая у меня возникла - это подключить Redis и обращаться к данным состояния напрямую из обработчика для получения id. Но на данный момент у меня нет возможности попробовать этот вариант, если он вообще осуществим.
Ответы (1 шт):
1. FSM с дополнительными данными.
Вместо хранения id второго пользователя в состоянии FSM, можно использовать словарь или другую структуру данных, привязанную к каждому пользователю. При нажатии на inline кнопку, сохраняйте id обоих пользователей в этой структуре данных. В обработчике сообщений, получайте id второго пользователя из этой структуры данных и используйте его для отправки сообщений.
2. Промежуточное ПО
Middleware, которое будет перехватывать сообщения от обоих пользователей и сохранять их в общей очереди. В обработчике сообщений получайте сообщения из очереди и отправляйте их соответствующему пользователю.
class DialogMiddleware(BaseMiddleware):
def __init__(self, queue):
self.queue = queue
async def on_process_message(self, message: types.Message, data: dict):
self.queue.put(message)
dp.middleware.setup(DialogMiddleware(queue))
@dp.message_handler(state="*")
async def handle_message(message: types.Message, state: FSMContext):
#получить сообщение из очереди и отправить его другому пользователю