← Назад к портфолио

Бот для управления заказами RetailCRM

Проблема: Цветочный магазин с несколькими точками терял до 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

🔄 Как это работает

  1. Фоновый сервис OrderMonitorService каждую минуту опрашивает RetailCRM API на наличие заказов со статусом "Отправить в магазин"
  2. Для каждого нового заказа генерируется SHA256-хеш от номера и проверяется в SQLite-базе для исключения дубликатов
  3. Система извлекает склад отгрузки (shipmentStore) и находит ответственных администраторов через конфигурацию ADMIN_WAREHOUSES
  4. Формируется HTML-карточка с полной информацией: товары с составом, адрес доставки, дата/время (с корректировкой часового пояса)
  5. Через RetailCRM API загружаются изображения товаров из карточек продуктов и отправляются медиагруппой в Telegram
  6. Флорист нажимает "✅ Заказ принят" → бот обновляет статус в CRM через API и убирает кнопки / показывает новые в зависимости от типа доставки
  7. При смене статуса на "Букет готов" в CRM, система автоматически отправляет новое уведомление с кнопкой "🚚 Заказ забрали" (только для доставки)
  8. Все действия логируются в таблицу order_actions с указанием admin_id, времени и комментария для аудита

🧠 Интеллектуальные возможности

Многоуровневая система управления заказами:

  1. Разные workflow для доставки и самовывоза — автоматическое определение типа заказа и применение соответствующих статусов (самовывоз сразу переводится в "Передан на самовывоз")
  2. Умная остановка мониторинга — счетчик последовательных ошибок (5 подряд = пауза 5 минут), обработка MemoryError с очисткой кэша, graceful shutdown по SIGTERM/SIGINT
  3. Защита от race conditions — UNIQUE constraint в SQLite по order_id гарантирует невозможность дублирования даже при параллельных запусках
  4. Отслеживание возвратов — флаги was_in_no_product и returned_from_no_product позволяют отправлять повторное уведомление при возврате из "Обсуждения замен"
  5. 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 показывает подробную аналитику по каждому складу: обработано заказов, подтверждено, отклонено, выполнено

📈 Сценарии использования

  1. Цветочные магазины с филиалами — автоматическое распределение заказов между складами, координация доставки и самовывоза
  2. Интернет-магазины с мульти-складами — маршрутизация заказов по географии (Москва / Санкт-Петербург / регионы)
  3. Рестораны с доставкой — уведомления о новых заказах, управление статусами "Готовится" / "Готов" / "Передан курьеру"
  4. Дропшиппинг-бизнесы — интеграция с RetailCRM для автоматического уведомления поставщиков о новых заказах
  5. Сервисные компании — управление заявками на услуги (ремонт, клининг) с отслеживанием ответственных мастеров

✅ Этот проект подойдёт вам, если:

  • Вы используете RetailCRM и хотите автоматизировать уведомления о новых заказах
  • Управляете несколькими складами/филиалами и нужна умная маршрутизация заказов
  • Теряете заказы из-за задержек в проверке CRM-системы вручную
  • Нужна история действий сотрудников (кто принял заказ, когда отправлен курьеру)
  • Требуется защита от дублирующих уведомлений при изменении статусов
  • Хотите интегрировать Telegram с любой CRM/ERP системой для оперативного управления

Нужна интеграция Telegram с вашей CRM?

Разработаю бота для автоматизации бизнес-процессов: заказы, складской учёт, уведомления, аналитика

Обсудить проект →