Клиент — сервисная компания по бытовому ремонту (сантехника, электрика, сборка мебели, мелкий ремонт): 6 мастеров и один диспетчер на телефоне. Заявки приходили вразнобой: звонки, личка в Telegram, комментарии под объявлениями на Авито. Диспетчер вручную выяснял в переписке район, адрес, что сломалось и когда удобно принять мастера — по 6–8 сообщений на одну заявку. Часть обращений терялась вечером и в выходные, часть — в чатах при переключении между клиентами; данные потом переносили в таблицу руками, с ошибками в телефонах и адресах. Клиент после заявки не понимал, принята ли она и когда ждать мастера, и звонил уточнять.
Цель, которую поставил клиент: принимать заявки круглосуточно в одном месте, получать их сразу в структурированном виде без уточнений в чате и держать клиента в курсе статуса без звонков диспетчера.
Требования: — клиент оформляет заявку сам за 1–2 минуты: услуга, район, дата, описание проблемы, фото, имя, телефон; — заявка приходит менеджеру в чат в готовом виде и сохраняется в таблице/CRM автоматически; — статусы заявок с уведомлениями клиенту на каждом шаге: принята, назначен мастер, перенос, выполнена; — запись на свободные слоты без пересечений в расписании мастеров; — работа в Telegram и MAX с единой базой заявок и клиентов; — ИИ-ассистент для ответов по прайсу, зонам выезда и срокам, с передачей сложных обращений оператору; — всё на сервере клиента, тексты, услуги и районы меняются без разработчика.
Архитектура: один backend на Node.js/TypeScript (Fastify), адаптеры каналов — grammY для Telegram и @maxhub/max-bot-api для MAX. Бизнес-логика (заявки, статусы, слоты, уведомления) общая, адаптеры только переводят сообщения и кнопки. PostgreSQL через Prisma — заявки, клиенты, мастера, слоты; Redis — состояние анкеты и защита от дублей; Docker Compose для развёртывания.
Что сделано:
Анкета заявки. Пошаговый сценарий: услуга из списка → район → удобная дата и интервал → описание проблемы → фото (опционально) → имя → телефон с валидацией → экран подтверждения с итогом. Кнопки «Назад» и «Отменить» на каждом шаге. Состояние хранится в Redis — при перезапуске бота или обрыве связи клиент продолжает с того же места, а не с начала.
Доставка заявки менеджеру. В чат/группу менеджеров приходит карточка: услуга, район, дата, описание, фото, контакт, ссылка на клиента и кнопки смены статуса прямо под сообщением. Параллельно строка уходит в Google Sheets и по webhook в CRM — без ручного копирования.
Статусы и уведомления. Цепочка «Новая → В работе → Назначен мастер → Выполнена / Отменена». Смена статуса кнопкой в чате менеджеров или в админке; клиенту автоматически уходит сообщение: заявка принята, назначен мастер (имя, время), время перенесено, работы завершены — с просьбой оценить. Клиент не звонит уточнять.
Запись на слоты и Google Calendar. Расписание мастеров с интервалами, свободные слоты считаются из графика и уже занятых заявок. Подтверждённая заявка создаёт событие в Google Calendar мастера; перенос или отмена из бота обновляют событие — пересечений нет.
Админка. Список заявок с фильтрами по статусу, услуге, району и дате; карточка клиента с историей обращений; управление услугами, районами, мастерами и текстами бота без правок кода; выгрузка за период.
ИИ-ассистент (включается опционально). Отвечает на вопросы по прайсу, зонам выезда, срокам и правилам работы по базе знаний компании (RAG). Задаёт уточняющие вопросы для квалификации лида. Вопрос вне базы или конфликтная ситуация — передача оператору с историей диалога. Порог релевантности исключает выдуманные цены.
Единая база для двух каналов. Клиент, написавший в MAX, а потом в Telegram, — одна карточка; заявки из обоих каналов в одной таблице и одном чате менеджеров.
Надёжность. Идемпотентная обработка сообщений — дублей заявок при повторных нажатиях нет; очередь уведомлений с повтором при сбое; ежедневный бэкап БД; алерты об ошибках администратору в Telegram.
Передача. Docker Compose на VPS клиента, README с инструкцией по запуску, обновлению и откату; все тексты, услуги, районы и статусы — в конфигурации и админке.
Срок: 3 недели, демонстрация рабочих частей каждые 3–4 дня: сначала анкета и доставка менеджеру, затем статусы и уведомления, слоты и календарь, админка, ИИ.
Стек: Node.js, TypeScript, grammY, @maxhub/max-bot-api, Fastify, PostgreSQL, Prisma, Redis, Docker, Google Sheets, Google Calendar, webhook-интеграции с CRM, OpenAI-compatible API.
Заявки принимаются 24/7; около 40% обращений теперь приходят через бота вечером и в выходные, когда раньше они терялись. — Диспетчер получает заявку сразу в готовом виде: 6–8 уточняющих сообщений на заявку → 0. Время обработки одной заявки сократилось с 15 минут до 2. — Потерь заявок и ошибок при переносе в таблицу нет — данные попадают в Sheets и CRM автоматически. — Входящие звонки «а приняли ли заявку?» сократились примерно на 60% за счёт уведомлений о статусе. — Пересечений в расписании мастеров нет — слоты и календарь синхронизированы. — ИИ-ассистент закрывает около половины вопросов по цене и зонам выезда до того, как они дойдут до менеджера. — За первый месяц через бота прошло более 300 заявок; компания отказалась от второго диспетчера, которого планировала нанимать.
Как применяют: бот работает как основной канал приёма заявок в Telegram и MAX; ссылку на бота разместили в объявлениях на Авито, на сайте и в QR на визитках мастеров. Новые услуги и районы добавляют через админку. Решение переиспользуемо для сантехников, электриков, клининга, ремонта техники, мебельщиков, монтажников и сервисных центров — меняются только справочники услуг и тексты.
Заказчик получил исходный код, инструкцию и месяц поддержки после запуска.