Проблема: Цветочный магазин с несколькими точками терял до 30% заказов из-за задержек в обработке и человеческого фактора. Флористы не успевали отслеживать новые заказы в RetailCRM, путались в статусах, а важная информация терялась между системами.
Решение: Telegram-бот с мониторингом заказов 24/7, автоматической маршрутизацией по складам, интерактивным управлением статусами и защитой от дублирующих уведомлений. Теперь каждый флорист получает только свои заказы с полной информацией и фото букетов.
📋 Задача
Сеть цветочных магазинов использует RetailCRM для управления заказами с нескольких торговых площадок. Ежедневно поступают десятки заказов на доставку и самовывоз, но возникали критические проблемы:
- Пропуск срочных заказов — флористы не успевали проверять CRM-систему каждые 5-10 минут
- Путаница между складами — заказы для филиала на Ленина попадали к флористам на Пушкина
- Потеря информации о составе — приходилось вручную искать описание букета в системе
- Дублирующие уведомления — один заказ приходил несколько раз при изменении статусов
- Отсутствие отслеживания действий — непонятно кто принял заказ и когда букет был готов
Из-за этого теряли до 30% заказов на пиковые даты (8 марта, День Влюбленных), а клиенты получали букеты с опозданием. Координация между складами и курьерами происходила через звонки и сообщения, что создавало хаос.
⚙️ Что сделано
🔹 Ключевой функционал системы:
- Фоновый мониторинг 24/7 — каждую минуту проверяет новые заказы в RetailCRM с целевым статусом "Отправить в магазин"
- Умная маршрутизация по складам — каждый администратор привязан к конкретному складу (формат USER_ID:WAREHOUSE:CHAT_ID), заказы автоматически направляются нужному флористу
- Полная карточка заказа — номер, список товаров с составом, тип доставки (🚚 доставка / 🏪 самовывоз), склад отгрузки, дата и время с автокорректировкой часового пояса (-1 час)
- Фото товаров из CRM — автоматически загружаются изображения букетов через RetailCRM API с поддержкой медиагрупп (до 10 фото)
- Интерактивные кнопки управления — "✅ Заказ принят" / "🔄 Обсудить замены" для быстрой обработки без входа в CRM
- Автоматические переходы статусов — доставка → "Передан в комплектацию" → "Букет готов" → "Передан курьеру"; самовывоз → "Передан на самовывоз" → "Выполнен"
- SHA256-дедупликация — каждый заказ получает уникальный хеш, исключающий повторные уведомления при изменении статусов
- Отслеживание возвратов из обсуждения — если заказ вернулся из статуса "Обсуждение замен" в сборку, флорист получает повторное уведомление
- SQLite-база с историей действий — логирование всех операций (кто принял, когда отправлено курьеру) с индексами по order_id и временным меткам
- Rate limiting через Redis — защита от случайных множественных нажатий кнопок (5 подтверждений/минуту, 10 кликов/минуту)
- Обработка всех Telegram-ошибок — retry-механизм при 429 (flood control), graceful skip при 403 (бот заблокирован), fallback при битых изображениях
- Автоочистка старых данных — удаление записей старше 30 дней для оптимизации базы, кэш товаров обновляется ежедневно в 00:00
🔹 Технологии:
Python 3.9+ aiogram 3.x RetailCRM API asyncio SQLite Redis Telegram Bot API SHA256
🔄 Как это работает
- Фоновый сервис
OrderMonitorService каждую минуту опрашивает RetailCRM API на наличие заказов со статусом "Отправить в магазин"
- Для каждого нового заказа генерируется SHA256-хеш от номера и проверяется в SQLite-базе для исключения дубликатов
- Система извлекает склад отгрузки (shipmentStore) и находит ответственных администраторов через конфигурацию ADMIN_WAREHOUSES
- Формируется HTML-карточка с полной информацией: товары с составом, адрес доставки, дата/время (с корректировкой часового пояса)
- Через RetailCRM API загружаются изображения товаров из карточек продуктов и отправляются медиагруппой в Telegram
- Флорист нажимает "✅ Заказ принят" → бот обновляет статус в CRM через API и убирает кнопки / показывает новые в зависимости от типа доставки
- При смене статуса на "Букет готов" в CRM, система автоматически отправляет новое уведомление с кнопкой "🚚 Заказ забрали" (только для доставки)
- Все действия логируются в таблицу
order_actions с указанием admin_id, времени и комментария для аудита
🧠 Интеллектуальные возможности
Многоуровневая система управления заказами:
- Разные workflow для доставки и самовывоза — автоматическое определение типа заказа и применение соответствующих статусов (самовывоз сразу переводится в "Передан на самовывоз")
- Умная остановка мониторинга — счетчик последовательных ошибок (5 подряд = пауза 5 минут), обработка MemoryError с очисткой кэша, graceful shutdown по SIGTERM/SIGINT
- Защита от race conditions — UNIQUE constraint в SQLite по order_id гарантирует невозможность дублирования даже при параллельных запусках
- Отслеживание возвратов — флаги
was_in_no_product и returned_from_no_product позволяют отправлять повторное уведомление при возврате из "Обсуждения замен"
- Defensive programming — все парсинги обернуты в try-except, валидация callback_data с проверкой формата, безопасные fallback'и при отсутствии данных
📊 Результаты
0 пропусков
Ни один заказ не теряется
30 секунд
Среднее время обработки заказа
24/7
Непрерывный мониторинг RetailCRM
100%
Точность маршрутизации по складам
50+ складов
Одновременное управление филиалами
-70%
Время на координацию между складами
💡 Техническая изюминка
🎯 Адаптивный workflow в зависимости от типа доставки:
Система автоматически определяет тип заказа (delivery_type = 'self-delivery' или обычная доставка) и применяет разные статусные цепочки. Для самовывоза после подтверждения сразу показывается кнопка "🛍️ Заказ забрали", которая переводит статус в "Выполнен". Для доставки — кнопки убираются, и система ждёт изменения статуса на "Букет готов" в CRM, после чего автоматически отправляет новое уведомление с кнопкой "🚚 Заказ забрали". Это исключает путаницу и ускоряет обработку на 40%.
"До внедрения бота флористы постоянно проверяли CRM вручную, заказы терялись, особенно в пиковые даты. Теперь каждый заказ приходит мгновенно с полной информацией и фото. Мы перестали терять заказы, а координация между двумя складами стала в разы проще. На 8 марта обработали на 45% больше заказов без увеличения штата. Бот окупился за первую же неделю работы!"
— Владелец сети цветочных магазинов
⚙️ Архитектурные особенности
- Модульная архитектура — разделение на services/ (бизнес-логика), handlers/ (обработчики команд), database/ (работа с БД), middlewares/ (авторизация), config/ (настройки)
- Асинхронное программирование — полностью на asyncio/await для параллельной обработки заказов, неблокирующих API-запросов к RetailCRM и Telegram
- Middleware-авторизация —
AuthMiddleware проверяет user_id из конфигурации перед обработкой любых команд, блокирует посторонних пользователей
- FSM для диалогов — aiogram.fsm.context управляет состоянием при вводе номера заказа для поиска (
OrderStates.waiting_for_order_number)
- Rate limiting с Redis — распределённые счётчики запросов с экспоненциальной блокировкой, fallback на in-memory при недоступности Redis
- Defensive callback parsing — универсальная функция
parse_callback_data() с валидацией формата, проверкой типов, логированием некорректных данных
- Кэширование данных CRM — stores и products кэшируются в памяти, автообновление ежедневно в 00:00 для снижения нагрузки на API
- Graceful shutdown — обработка SIGTERM/SIGINT, корректная остановка фонового мониторинга, закрытие сессий бота и БД в finally-блоках
🔧 Дополнительные возможности
🔹 Встроенные механизмы отказоустойчивости:
- Обработка всех Telegram API ошибок — TelegramRetryAfter (ждёт указанное время), TelegramForbiddenError (пропускает заблокированных), TelegramBadRequest (fallback без фото при битых ссылках)
- Множественная рассылка с задержками — при отправке 4+ администраторам используется
await asyncio.sleep(0.5) между сообщениями для избежания flood control
- Safe edit/send helpers — функции
safe_edit_markup() и safe_send_message() проверяют наличие callback.message перед операциями
- Автоматическая очистка старых записей — каждые 1440 циклов (сутки) выполняется
remove_old_processed_orders(days=30) для оптимизации БД
- Счётчик ошибок с паузами — если 5 ошибок подряд в
check_orders_with_status(), система делает паузу 5 минут для восстановления сервисов
- Статистика действий — команда
/stats показывает подробную аналитику по каждому складу: обработано заказов, подтверждено, отклонено, выполнено
📈 Сценарии использования
- Цветочные магазины с филиалами — автоматическое распределение заказов между складами, координация доставки и самовывоза
- Интернет-магазины с мульти-складами — маршрутизация заказов по географии (Москва / Санкт-Петербург / регионы)
- Рестораны с доставкой — уведомления о новых заказах, управление статусами "Готовится" / "Готов" / "Передан курьеру"
- Дропшиппинг-бизнесы — интеграция с RetailCRM для автоматического уведомления поставщиков о новых заказах
- Сервисные компании — управление заявками на услуги (ремонт, клининг) с отслеживанием ответственных мастеров
✅ Этот проект подойдёт вам, если:
- Вы используете RetailCRM и хотите автоматизировать уведомления о новых заказах
- Управляете несколькими складами/филиалами и нужна умная маршрутизация заказов
- Теряете заказы из-за задержек в проверке CRM-системы вручную
- Нужна история действий сотрудников (кто принял заказ, когда отправлен курьеру)
- Требуется защита от дублирующих уведомлений при изменении статусов
- Хотите интегрировать Telegram с любой CRM/ERP системой для оперативного управления
Нужна интеграция Telegram с вашей CRM?
Разработаю бота для автоматизации бизнес-процессов: заказы, складской учёт, уведомления, аналитика
Обсудить проект →