Лидогенерация, построенная из чат-диалогов
Как только WhatsApp-бот начал квалифицировать лидов круглосуточно, почти сразу всплыла новая проблема: отдел продаж не видел, что происходит. Диалоги жили внутри WhatsApp на экране телефона, статусы лидов существовали только в базе бота, а единственный способ проверить, кто «готов купить», — напрямую делать запрос в PostgreSQL. Школе нужна была нормальная панель продаж — что-то, что команда могла бы открывать каждое утро, видеть пайплайн с одного взгляда и точно знать, кому звонить первым.
канбан и история чатов
Мы построили CRM для лидов под этот конкретный рабочий процесс. Центральный элемент — канбан-доска с четырьмя колонками: все лиды, готовы купить, квалифицированы и отложены — точно соответствующая категориям, которые WhatsApp-бот присваивает во время разговоров. Каждая карточка показывает имя лида, номер телефона, время последнего сообщения и фрагмент последнего обмена. Команда перетаскивает карточки между колонками по мере развития диалогов: тот, кто был «квалифицирован» на прошлой неделе, может переехать в «готов купить» после фоллоу-апа или в «отложен», если человек уехал в отпуск. Drag-and-drop сделан на dnd-kit, и каждое перемещение запускает оптимистичное обновление — карточка моментально двигается на экране, API-запрос уходит в фоне, а если сервер отклоняет изменение, карточка возвращается в исходную колонку. Мелочь UX, но когда вы за утренним обзором перетаскиваете десять карточек подряд, лаг недопустим.
Помимо доски, есть полный просмотр истории чатов. Каждый разговор, который вёл бот в WhatsApp, и каждое сообщение, отправленное живым менеджером после передачи диалога, видны внутри панели. Включая медиа: фотографии учебников, которые присылают студенты, скриншоты цен конкурентов, даже голосовые сообщения, отображаемые как воспроизводимые аудиоклипы. Заставить медиа корректно отображаться оказалось сложнее, чем мы ожидали. Медиафайлы WhatsApp сохраняются на сервере Node.js-мостом, но дашборд работает на отдельном фронтенде — поэтому каждое изображение и аудиофайл проходят через FastAPI-бэкенд, который отдаёт их с правильными заголовками авторизации. По сути, это медиапрокси, и он должен был справляться с типами файлов, которые WhatsApp отдаёт в своих собственных сжатых форматах.
статистика и доступ
Страница статистики даёт команде вид с высоты птичьего полёта: всего лидов за неделю, конверсия по статусам, среднее время от первого сообщения до квалификации и графики трендов, показывающие, как объём меняется со временем. Графики сделаны на Recharts, данные подтягиваются агрегированно с бэкенда. Одно из дизайн-решений, которое мы обсуждали, — должна ли статистика обновляться в реальном времени или по обновлению страницы. Реал-тайм означал бы либо WebSocket-соединения, либо постоянный polling, что добавляло сложности ради двух человек, заглядывающих в дашборд несколько раз в день. Мы остановились на polling с интервалом 30 секунд, когда страница статистики активна — просто, предсказуемо и достаточно для реального паттерна использования. Если команда вырастет и дашборд станет командным центром, перейдём на server-sent events, но переинженеренивание ради будущего, которое может не наступить, — паттерн, которого мы стараемся избегать.
Контроль доступа основан на JWT — у директора школы и двух менеджеров по продажам есть свои аккаунты, API отклоняет неаутентифицированные запросы. Настройка простая, потому что пользователей три, но слой авторизации построен правильно, и его можно будет масштабировать на роли и права без переписывания. Фронтенд — Next.js с React и Tailwind, что сохраняет стек консистентным с другими инструментами школы и упрощает поддержку.
результаты
Результат — отдел продаж начинает каждый день с ясной картиной: кто горячий, кому нужен лёгкий толчок, кто затих. Они перестали терять лидов, проваливающихся между трещинами телефонного экрана, а директор видит метрики конверсии без необходимости просить кого-то выгрузить цифры. Вывод из этого проекта: CRM не обязана быть Salesforce. Когда вы контролируете источник данных — в этом случае WhatsApp-бот, подающий квалифицированных лидов прямо в пайплайн, — можно построить что-то под конкретную задачу, что команда действительно использует, а не настраивать универсальный инструмент, который никто не открывает после первой недели.