Логистический бизнес генерирует много типовых обращений: «сколько будет стоить», «где мой груз», «когда доставите», «можно перенести доставку». Если на эти вопросы отвечают живые диспетчеры, половина рабочего дня уходит на одни и те же ответы, а в пиковые сезоны телефония и почта захлёбываются. Бот в MAX закрывает эти запросы без участия операторов и держит клиента в курсе всю цепочку — от оформления заявки до выдачи груза получателю. Параллельно второй контур того же бота работает для водителей и диспетчеров: распределение заказов, статусы, фото подтверждения, координаты в реальном времени.
В этой статье разбираем три параллельных сценария — клиентский, водительский и диспетчерский, — а также интеграции с TMS/WMS, документооборот и нагрузочные ограничения. Все примеры — для российских реалий 2026 года: 1С, МойСклад, СДЭК, Почта России, DPD, Яндекс.Карты, 2GIS, электронные ТТН и УПД.
Три контура одного бота
Логистический бот в MAX — это не одно приложение, а три параллельных интерфейса с общей серверной частью:
| Контур | Кто пользуется | Ключевые сценарии |
|---|---|---|
| Клиентский | Отправитель/получатель груза | Расчёт, заявка, трекинг, уведомления, претензии |
| Водительский | Водители и курьеры на линии | Получение задания, статусы, фото, координаты, навигация |
| Диспетчерский | Диспетчеры, логисты, начальники смены | Распределение, мониторинг, реакция на ЧП, чаты смен |
Технически это один Bot API в MAX, но разные FSM-сценарии и разные права. Разделение по user_role хранится в таблице bot_users: клиент видит только свои заказы, водитель — только назначенные ему задания, диспетчер — всю смену. Один и тот же телефон может быть в нескольких ролях (например, водитель на полставки + клиент сервиса), и FSM при старте спрашивает, в какой роли пользователь сегодня заходит.
Расчёт стоимости перевозки
Базовый клиентский сценарий — калькулятор перевозки: откуда, куда, что, габариты, срок. У междугородних перевозчиков есть тарифные сетки, которые легко перевести в формулу. У сборных грузов — расчёт по объёмному весу и зонам. У международной логистики — таможенные коэффициенты, и тут без интеграции с TMS не обойтись.
Технически логика такая: бот собирает параметры через FSM, отправляет POST в калькулятор (свой или вендорский), возвращает результат. Кэшировать имеет смысл только справочники городов и почтовых индексов — сами расчёты идут на актуальных тарифах, иначе клиент получит устаревшую цену и потом будет ругаться на «обман».
Объёмный вес считается стандартной формулой (длина × ширина × высота в см) / 5000 для авиадоставки и / 6000 для автодоставки. Бот должен показывать оба значения — фактический и объёмный — и считать тариф по большему. Это снижает количество споров у выдачи: «я платил за 5 кг, а вы говорите 18».
def calc_volumetric_weight(length_cm, width_cm, height_cm, mode="auto"):
divisor = 5000 if mode == "air" else 6000
return (length_cm * width_cm * height_cm) / divisor
def chargeable_weight(actual_kg, length_cm, width_cm, height_cm, mode):
vol = calc_volumetric_weight(length_cm, width_cm, height_cm, mode)
return max(actual_kg, vol)
Для сборных грузов и LTL (less-than-truckload) добавляется зональная сетка: страна — регион — город — район. Тариф в крупный город может быть в 2–3 раза дешевле, чем в посёлок в 50 км от него, и это надо честно показывать на этапе расчёта, а не «уточнять при оформлении».
Оформление заявки
После расчёта клиент нажимает «Оформить» — бот собирает контакт отправителя и получателя, точные адреса, желаемую дату забора, тип упаковки, особые условия (хрупкое, не кантовать, терморежим). Если клиент уже знаком, контакты подставляются из истории, и поля сворачиваются в «всё как обычно?».
Заявка уходит в TMS (1С:ТМС, Logist.Pro, собственная система). Возвращается номер заказа и ссылка на трекинг. Здесь критична идемпотентность: если пользователь нажмёт «Оформить» дважды (плохая связь, лагает MAX, нетерпеливый палец), заявка не должна создаваться дважды. Реализуется через unique-ключ на стороне TMS либо короткий лок в Redis на 30–60 секунд по ключу (user_id, hash(payload)).
Адреса забора и доставки лучше валидировать через Яндекс.Геокодер или DaData: пользователь пишет «Пушкина 10», а система возвращает нормализованный «г. Москва, ул. Пушкина, д. 10, кв. ?» с уточнением квартиры/офиса. Это сокращает количество промахов курьера на последней миле в 3–5 раз. 2GIS пригождается там, где Яндекс плохо знает дворовую разметку — в промзонах и логопарках.
Трекинг груза для клиента
Главный убийца времени диспетчера — запросы «где мой груз». Бот закрывает это отдельным сценарием: пользователь вводит номер заказа (или выбирает из списка своих) → бот возвращает текущий статус, последнее событие, прогноз по времени и, если груз в пути, — кнопку «Показать на карте» с актуальной точкой машины.
Источников статусов несколько:
- Собственная TMS даёт логистические события (принят, на сортировке, в пути, прибыл на склад).
- GPS-трекеры на машинах — координаты в реальном времени, скорость, остановки.
- Подрядчики на последней миле — СДЭК, Почта России, DPD, Boxberry — пушат статусы по своим API.
- Бот водителя — события, которые водитель проставляет вручную (взял груз, прибыл к получателю, выдал).
Все статусы собираются в единый Event Store (обычно отдельная таблица tracking_events с полями order_id, source, event_code, event_time, payload jsonb) и нормализуются в общий словарь. На выходе у пользователя — простая лента из 6–8 этапов, без сырого мусора вида STATUS_CODE_47 или DELIVERY_ATTEMPT_RESULT_3.
Бот для водителя
Второй контур — приложение водителя. Раньше это был отдельный мобильный клиент, который надо устанавливать, обновлять, обучать. Сейчас MAX закрывает 90% сценариев чатом + инлайн-кнопками + Mini App для карты.
Базовый сценарий смены:
- Водитель заходит в бот, нажимает «Начать смену», выбирает машину.
- Диспетчер видит водителя в пуле «свободные» и распределяет ему задания.
- Водитель получает уведомление: «Заказ №L-78231, забор в 14:00 по адресу X, доставка по адресу Y. Принять / Отказаться».
- На каждом этапе водитель шлёт статус кнопкой: «Выехал к отправителю», «Принял груз», «В пути», «Прибыл к получателю», «Выдал».
- На точке выдачи прикладывает фото подтверждения (груз + подпись получателя на бумажной ТН или фото электронной подписи).
- Если ЧП — отдельная кнопка «Проблема»: повреждение, отказ получателя, нет на месте, ДТП.
Координаты в реальном времени бот получает либо из встроенной геолокации MAX (если водитель явно поделился), либо из сторонних телематических систем (Wialon, GLONASSsoft, Omnicomm) через их API. Прятать факт сбора координат нельзя — водитель должен явно согласиться на смене, иначе попадаем под 152-ФЗ.
🚚 Заказ №L-78231
📦 Забор: г. Москва, ул. Складская, 14, к. 3
Контакт: +7 (903) 555-12-34, Иван
Слот: 14:00–16:00
📍 Доставка: г. Подольск, пр-т Юных Ленинцев, 8
Контакт: +7 (915) 222-33-44, Мария
Слот: до 19:00
Вес: 12 кг, объём: 0.08 м³
Особые условия: хрупкое, не кантовать
[ Принять ] [ Отказаться ] [ На карте ]
Фотофиксация и электронные документы
Фото на приёмке и выдаче — самая частая «страховка» от споров о повреждениях. Минимум:
- На приёмке у отправителя: общий вид груза, упаковка со всех сторон, маркировка/номер места, состояние коробки.
- На выдаче получателю: груз в момент передачи, подпись на бумажной ТН или экране, лицо получателя по согласию.
Фото уходят сразу в S3-совместимое хранилище (Yandex Object Storage, MinIO), в БД сохраняется только URL и метаданные (геокоординаты EXIF, время). При споре о повреждении за минуту поднимаются все фото по order_id.
Электронные ТТН и УПД через ЭДО (Контур.Диадок, СБИС, Такском) подключаются как отдельный модуль. Бот не сам формирует и подписывает документы, а триггерит формирование на стороне TMS/учётки и присылает водителю PDF-копию с QR-кодом для проверки на стороне получателя. Подписание УКЭП — на стороне ЭДО-провайдера; бот лишь показывает статус «подписан / ожидает подписи / отклонён».
Бот для диспетчера
Диспетчерский контур — это панель управления сменой прямо в чате. Базовые экраны:
- Список открытых заявок — отсортирован по времени забора, цветовая маркировка по срочности.
- Пул свободных водителей — кто на смене, где находится, какая машина, остаток рабочих часов.
- Распределение — кнопка «Назначить» в карточке заявки → выбор водителя из пула или ручной ввод.
- Мониторинг ЧП — отдельный канал, куда сыплются проблемные события: опоздания больше 15 минут, отказы получателей, сработки тревожной кнопки.
- Чат смены — групповой чат всех активных водителей и диспетчеров; быстро объявить «всем — пробка на МКАД 78-й км, объезд через М-10».
Хорошая практика — реакции вместо ответов. Диспетчер увидел ЧП → ставит реакцию «🆘» — все остальные диспетчеры видят, что событие подхвачено. Это убирает классическую проблему «думал, ты ответишь / думал, ты ответишь».
Распределение заказов можно автоматизировать (алгоритм по близости водителя к точке забора, остаткам времени, типу машины), но финальное «принять/изменить» лучше оставлять диспетчеру — алгоритм не знает, что у Иванова сегодня день рождения и его лучше не грузить «вечеркой».
Уведомления для клиента: какие события и когда
Не нужно слать сообщение на каждый чих. Реальные триггеры:
- Заявка создана — номер, ссылка на трекинг.
- Груз принят у отправителя — фото упаковки, ФИО водителя.
- Передан на следующий хаб — для сборных грузов и междугородки.
- Груз в городе получателя — за сутки до выдачи.
- Прибудет сегодня — за 2–4 часа до выдачи, со слотом.
- Курьер выехал — за 30–60 минут.
- Доставлен — фото подтверждения, кнопка «Оценить доставку».
- Проблема — опоздание, повреждение, отказ получателя, недозвон.
Восьмой пункт — самый важный. Здесь бот должен не просто уведомить, а сразу предложить варианты: связаться с диспетчером, перенести доставку на завтра, оставить груз на ближайшем ПВЗ, оформить возврат отправителю. Каждая опция — отдельная инлайн-кнопка с понятным CTA, а не «свяжитесь с менеджером».
Тихие часы — обязательно. Уведомления типа 4–6 не должны прилетать в 23:00–08:00 по часовому поясу получателя (поле tz в профиле, по умолчанию — IP-геолокация при первом старте + явное подтверждение).
Интеграции с TMS, WMS и API курьеров
Бот сам по себе не источник правды — он канал. Реальные данные живут в TMS/WMS/учётной системе. Самые частые в РФ:
| Система | Тип API | Лимиты | Что отдаёт |
|---|---|---|---|
| 1С:ТМС | OData/HTTP-сервисы | Зависит от хостинга | Заказы, рейсы, ТТН, водители, машины |
| Logist.Pro | REST JSON | 100 req/min | Полный TMS-контур |
| МойСклад | REST JSON | 45 req/3 сек | Остатки, заказы, отгрузки (для логистики магазинов) |
| 1С:УТ + 1С:Розница | CommerceML, REST | Зависит от хостинга | Заказы, остатки, контрагенты |
| Wialon / GLONASSsoft | REST + websocket | 60 req/min | GPS-координаты, телематика |
API курьерских:
- СДЭК — REST
/v2/calculator/tariff,/v2/orders,/v2/deliverypoints. Возвращает тарифы, оформляет заказы, отдаёт ПВЗ. Webhooks по статусам — обязательно подписать. - Почта России —
tariff.russianpost.ruдля расчёта,otpravka.pochta.ruдля оформления,tracking.russianpost.ruдля трекинга. API нестабильный, обязательно делать ретраи и таймауты. - DPD — SOAP (да, до сих пор), отдельный SDK на Java/.NET, для Python/Go — обёртка через
zeep. - Boxberry — XML API, медленный, но широкая сеть ПВЗ в малых городах.
- 5Post — REST, быстро растёт сеть постаматов в продуктовых сетях.
Универсальное правило: обмен с внешними системами всегда асинхронный, через очередь (NATS, RabbitMQ, Redis Streams) с ретраями и backoff. Если СДЭК упал на 2 часа — ваши заявки накапливаются в очереди и догоняются потом, а не валятся клиенту в лицо ошибкой 500.
Карты, маршруты и навигация
Карта в боте нужна в двух местах: клиент смотрит, где едет машина, водитель смотрит маршрут до точки.
Для клиента подойдёт статичный фрагмент карты с пином (Static API Яндекс.Карт или 2GIS) — отправляем картинкой, не грузим Mini App. Обновление — раз в 1–2 минуты по событию или по запросу пользователя.
Для водителя сложнее. Встроенный навигатор внутри MAX не сделать, поэтому бот отдаёт диплинк в Яндекс.Навигатор / 2GIS:
yandexnavi://build_route_on_map?lat_to=55.7558&lon_to=37.6173
dgis://2gis.ru/routeSearch/rsType/car/to/37.6173,55.7558
Водитель тапает кнопку → открывается родной навигатор → строит маршрут. Это в разы стабильнее любого встроенного решения.
Для распределения заявок диспетчеру помогает геокластеризация: показать на карте все открытые заборы и всех свободных водителей, чтобы быстро видеть, кому что ближе. Это уже Mini App с Yandex.Maps JS API, отдельная разработка на 2–3 недели.
KPI водителей и аналитика
Через бот удобно собирать сырьё для KPI водителей:
- Среднее время на точке (от «прибыл» до «выехал») — выявляет медленных.
- Срыв слота (опоздание больше 15 минут к окну выдачи) — главный показатель качества для клиента.
- Доля доставок с первой попытки — здоровая норма 88–95%.
- Жалобы клиентов — привязываются к водителю по
assigned_driver_idв заказе. - Расход топлива на 100 км — из телематики, аномалии флагает скрипт.
Дашборд диспетчера / руководителя — обычно отдельный веб-интерфейс (Metabase, собственный на React), а в боте лежит только агрегированная сводка по запросу: «KPI смены за вчера», «топ-5 нарушителей слота за неделю».
Безопасность и доступ
Логистика возит деньги — буквально, в виде грузов. Поэтому базовая гигиена:
- Каждый запрос статуса заказа проверяет, что заказ принадлежит этому пользователю (по
user_idилиphone). Иначе любой угадает чужой номер и узнает адрес. - Адреса доставки не светятся в публичных каналах и не попадают в логи в открытом виде (хеш или маскирование).
- Финансовые действия (отмена с возвратом средств, изменение получателя, перенаправление груза) проходят через подтверждение оператором.
- Водительский контур требует привязки к телефону + подтверждение менеджером; нельзя зарегистрироваться водителем самостоятельно.
- Доступ к панели диспетчера — отдельная роль, выдаётся только из админки, не через бот.
Логи действий с заказами хранятся минимум 3 года (для соответствия требованиям 152-ФЗ и претензионной работы) в отдельной audit-таблице с actor_id, action, target_id, payload_diff, ts.
Стек и нагрузка
Типичный набор:
- Bot-сервис — Go или Python (FastAPI + aiogram-подобная обвязка под MAX Bot API).
- Очередь — NATS или RabbitMQ для событий из TMS/GPS/подрядчиков.
- PostgreSQL — заказы, пользователи, кэш справочников, история событий, audit.
- Redis — FSM, idempotency-ключи, антифлуд, короткоживущий кэш.
- S3-совместимое хранилище — фото подтверждений, сканы документов.
- Адаптеры — отдельные сервисы под каждый внешний источник, чтобы их падение не валило бот.
При нагрузке от тысячи заявок в день и 50–100 водителей на смене бот спокойно живёт на одном сервере 4 vCPU / 8 GB. Узкое место — это не Bot API MAX, а интеграции с подрядчиками: их API часто медленные и нестабильные. Закладывайте 30% бюджета времени именно на адаптеры с ретраями, circuit breaker и фолбэками.
При росте до 10 000+ заявок/день добавляются: репликация Postgres под чтение трекинга, шардинг истории событий по месяцам, отдельный кластер для GPS-телеметрии (в Postgres она душит индексы, лучше TimescaleDB или ClickHouse).
ROI: когда бот окупается
Грубая прикидка для средней транспортной компании 50 машин / 30 диспетчеров / 5 000 заказов в месяц:
| Статья | До бота | С ботом | Экономия/месяц |
|---|---|---|---|
| Звонки «где груз» | 1500 шт × 4 мин × 250 ₽/час | 100 шт | ≈25 000 ₽ |
| Звонки «оформить» | 800 шт × 6 мин × 250 ₽/час | 200 шт | ≈18 000 ₽ |
| Срывы слотов | 12% | 6% | ≈40 000 ₽ (компенсации + удержание) |
| Споры о повреждениях | 25 шт/мес | 8 шт/мес | ≈30 000 ₽ |
Итого порядок 100–120 тыс. ₽/мес экономии при разовой стоимости разработки 800 тыс. — 1.5 млн ₽ и поддержке 30–60 тыс. ₽/мес. Окупаемость 8–14 месяцев. Дальше — чистый плюс плюс рост NPS на 15–25 пунктов.
Чек-лист готовности логистического бота к запуску
- Идемпотентность создания заявки (Redis-лок + unique-индекс в TMS).
- Адреса нормализуются через Яндекс.Геокодер или DaData до сохранения.
- Объёмный вес считается и показывается на этапе расчёта.
- Все три роли (клиент / водитель / диспетчер) разведены по FSM и правам.
- Координаты водителя собираются только с явного согласия (152-ФЗ).
- Фото приёмки и выдачи уходят в S3, метаданные сохраняются в БД.
- Электронные ТТН/УПД через ЭДО, бот показывает статус подписания.
- Уведомления уважают тихие часы по часовому поясу получателя.
- Восьмой триггер (проблема) предлагает 3–5 вариантов решения, а не «свяжитесь с менеджером».
- Карта для клиента — статичной картинкой, для водителя — диплинк в Яндекс.Навигатор / 2GIS.
- Все интеграции с курьерами (СДЭК, Почта, DPD, Boxberry) — асинхронные с ретраями.
- KPI водителей собираются автоматически и доступны диспетчеру в боте.
- Audit-лог финансовых действий хранится не менее 3 лет.
- Чат смены и реакция «🆘» по ЧП работают в реальном времени.
- Нагрузочное тестирование на 3× ожидаемый пик (предновогодний сезон).
Итого
Бот для логистики в MAX — это не «ещё один чат», а замена половины работы диспетчерской и водительского планшета одновременно. Калькулятор, заявка и трекинг закрывают клиента; бот водителя со статусами и фото — линию; диспетчерский контур с распределением и реакциями — управление сменой. Сложность не в самом боте, а в адаптерах к TMS, телематике и подрядчикам последней мили: именно они определяют, насколько данные в чате будут совпадать с реальностью на дороге и складе. Запустите эти три контура — и поток типовых обращений упадёт в 5–8 раз, а NPS вырастет за счёт того, что клиент впервые видит свой груз, а не догадывается о нём.
Частые вопросы
Какие задачи закрывает бот для логистической компании в MAX?
Три параллельных контура. Клиентский — расчёт стоимости перевозки, оформление заявки, трекинг груза, уведомления о ключевых событиях, претензии и переносы доставки. Водительский — получение задания, статусы (взял / еду / прибыл / выдал), фото подтверждения, координаты в реальном времени, диплинки в Яндекс.Навигатор и 2GIS. Диспетчерский — распределение заказов по водителям, мониторинг ЧП, реакции на проблемные события, чат смены, агрегированные KPI. Всё это в одном Bot API MAX, разведённое по ролям через FSM и таблицу bot_users.
Как реализовать расчёт стоимости в логистическом боте MAX?
Бот собирает параметры через FSM (откуда, куда, что, габариты, срок), отправляет POST в калькулятор (свой или вендорский), возвращает результат. Объёмный вес считается формулой длина × ширина × высота / 5000 для авиа и / 6000 для авто; тариф берётся по большему из фактического и объёмного веса, чтобы не было споров у выдачи. Для сборных грузов и LTL добавляется зональная сетка страна-регион-город-район. Кэшировать имеет смысл только справочники городов и индексов — сами расчёты идут на актуальных тарифах, иначе клиент получит устаревшую цену.
Как избежать дублирования заявок при оформлении в боте?
Через идемпотентность. Если пользователь нажмёт «Оформить» дважды (плохая связь, лагает MAX), заявка не должна создаваться дважды. Реализуется через unique-ключ на стороне TMS либо короткий лок в Redis на 30–60 секунд по комбинации user_id и hash(payload). Адреса при этом валидируются через Яндекс.Геокодер или DaData: пользователь пишет «Пушкина 10», система возвращает нормализованный адрес с уточнением квартиры или офиса. Это сокращает количество промахов курьера на последней миле в 3–5 раз. 2GIS используется там, где Яндекс плохо знает дворовую разметку — в промзонах и логопарках.
Как организовать работу водителя через бот в MAX?
Водитель заходит в бот, нажимает «Начать смену», выбирает машину. Диспетчер видит его в пуле свободных и распределяет задания. На каждом этапе водитель шлёт статус кнопкой: «Выехал к отправителю», «Принял груз», «В пути», «Прибыл к получателю», «Выдал». На точке выдачи прикладывает фото подтверждения. При ЧП — отдельная кнопка «Проблема» с типом события. Координаты собираются либо встроенной геолокацией MAX (с явного согласия по 152-ФЗ), либо через телематику Wialon/GLONASSsoft. Для маршрута бот отдаёт диплинк в Яндекс.Навигатор или 2GIS — родной навигатор стабильнее любого встроенного решения.
Откуда бот берёт данные для трекинга груза?
Из четырёх источников, объединённых в единый Event Store в таблице tracking_events. Собственная TMS даёт логистические события (принят, на сортировке, в пути, прибыл на склад). GPS-трекеры на машинах — координаты в реальном времени, скорость, остановки. Подрядчики последней мили (СДЭК, Почта России, DPD, Boxberry, 5Post) пушат статусы через webhooks. Бот водителя — события, которые водитель проставляет вручную. Все статусы нормализуются в общий словарь, на выходе у пользователя простая лента из 6–8 этапов без сырого мусора вида STATUS_CODE_47.
По каким событиям бот должен уведомлять клиента и когда молчать?
Восемь триггеров: заявка создана, груз принят у отправителя, передан на следующий хаб, груз в городе получателя, прибудет сегодня (за 2–4 часа), курьер выехал (за 30–60 минут), доставлен с фото, проблема. Восьмое событие — самое важное: бот не просто уведомляет, а сразу предлагает 3–5 вариантов решения (связаться с диспетчером, перенести на завтра, оставить в ПВЗ, вернуть отправителю), каждое — отдельной инлайн-кнопкой. Тихие часы обязательны: уведомления о промежуточных статусах не приходят в 23:00–08:00 по часовому поясу получателя.
Какой стек используют для бота логистической компании в MAX?
Bot-сервис на Go или Python (FastAPI с обвязкой под MAX Bot API). Очередь NATS или RabbitMQ для событий из TMS, GPS и подрядчиков. PostgreSQL для заказов, пользователей, истории событий и audit-лога. Redis для FSM, idempotency-ключей и антифлуда. S3-совместимое хранилище (Yandex Object Storage, MinIO) для фото подтверждений и сканов документов. Адаптеры — отдельные сервисы под каждый внешний источник, чтобы их падение не валило бот. При тысяче заявок в день и 50–100 водителях на смене бот живёт на одном сервере 4 vCPU / 8 GB. При росте до 10 000+ заявок добавляется реплика Postgres под чтение трекинга и отдельный кластер под GPS-телеметрию (TimescaleDB или ClickHouse).