Как происходит перенаправление заявки в боте
Что проверяют
Понимаете ли вы путь заявки от сообщения пользователя до оператора или внешней системы и обратно, и что происходит, когда на этом пути что-то падает. Следом обычно спрашивают, как оператор ответит пользователю и не потеряются ли заявки при перезапуске бота.
Как отвечать
Опишите на примере Telegram и aiogram 3:
- сбор заявки: пользователь проходит шаги диалога, состояние хранится в FSM:
StatesGroup,State,FSMContext. Для продакшена нуженRedisStorage, а неMemoryStorage, иначе при рестарте недозаполненные заявки пропадут; - сохранение: заявка сразу пишется в базу со статусом и id, до любой отправки дальше;
- маршрутизация: по типу заявки, региону или загрузке выбирается адресат. Это может быть чат операторов, отдельная тема форума в группе (
message_thread_id) или конкретный сотрудник; - перенаправление:
bot.copy_message()илиsend_message()в чат операторов с инлайн-кнопками «взять в работу» и «закрыть». Данные кнопок описывают черезCallbackData, а на нажатие обязательно вызываютcallback.answer(), иначе у оператора крутится индикатор; - обратный путь: храните связку между сообщением в чате операторов и пользователем. Оператор отвечает реплаем, бот по связке пересылает ответ;
- внешняя система: если заявка уходит в CRM или хелпдеск, вызов делается асинхронно через
httpxилиaiohttp, с таймаутом и повторами, а лучше через очередь, чтобы недоступность CRM не блокировала бота.
Учитывайте ограничения Telegram: бот не может написать пользователю первым, а частые сообщения в одну группу упираются в лимиты и ошибку 429 с retry_after.
Где спотыкаются
Вызывают requests внутри асинхронного обработчика. Синхронный запрос блокирует event loop, и пока CRM думает, бот не отвечает никому.
Пишут код на Updater и Filters из старого python-telegram-bot. С версии 20 библиотека асинхронная, Filters заменён модулем filters, а бот собирается через Application.builder().
Не сохраняют заявку до пересылки. Упал запрос к CRM или бот перезапустился, и заявка пропала без следа. Повторная отправка при этом должна быть идемпотентной, чтобы у оператора не появлялось дублей.