Короткий ответ. Интеграцию бота MAX с CRM безопаснее строить как обмен через промежуточный слой: MAX принимает или отправляет сообщение, интеграционный сервис нормализует данные, CRM возвращает свой результат, а отдельный журнал хранит сопоставление идентификаторов и статусов. Официальные методы MAX для сообщений описаны в документации POST /messages, события бота — в документации Webhook. Названия полей и правила конкретной CRM нужно проверять по её собственной документации.
Где заканчивается MAX и начинается CRM
MAX отвечает за канал общения, а CRM — за внутреннюю карточку клиента, лид, сделку или обращение. Между ними не должно быть неявного преобразования. Событие от пользователя содержит идентификатор отправителя, получателя, время и тело сообщения; схема Message описывает эти части. Внутри интеграции их превращают в нормализованный объект, не заставляя CRM разбираться в особенностях транспорта.
Сначала решите, какой объект создаётся. В одном процессе это может быть новый лид, в другом — сообщение в существующем обращении. Если не определить правило заранее, повторное сообщение пользователя будет создавать новые карточки вместо продолжения истории. Критерий сопоставления должен быть явным: внутренний идентификатор, разрешённый внешний идентификатор или подтверждённый контакт.
Модель данных между системами
Минимальная модель содержит внешний идентификатор пользователя MAX, внутренний идентификатор CRM, идентификатор сообщения, время события, тип события, нормализованный текст и статус обработки. Поля для имени, телефона и других персональных данных добавляйте только если они действительно нужны процессу и разрешены вашей политикой обработки данных.
| Группа | Пример поля | Назначение | Правило |
|---|---|---|---|
| MAX | user_id, timestamp | Связать событие с каналом | Сохранять как внешний ключ |
| Сообщение | message_id, body | Восстановить контекст | Не терять исходный тип |
| CRM | record_id, status | Обновлять карточку | Не подменять статус догадкой |
| Интеграция | attempt, error | Разбирать сбои | Маскировать секреты и данные |
Храните исходное событие отдельно от результата преобразования. Это помогает понять, была ли ошибка в MAX, в маппинге полей или в ответе CRM. При изменении схемы добавляйте версию преобразования, чтобы старые записи можно было прочитать по прежним правилам.
Приём событий от MAX
Для продуктивной интеграции MAX описывает Webhook через HTTPS. Endpoint должен быть доступен на порту 443, иметь доверенный сертификат и отвечать успешно в установленный срок. Если при подписке задан секрет, сервер проверяет заголовок X-Max-Bot-Api-Secret. Проверка выполняется до передачи события во внутреннюю обработку.
Webhook-обработчик не должен синхронно ждать CRM, если операция может быть долгой. Он проверяет запрос, фиксирует событие с уникальным ключом и возвращает ответ, а дальнейшее сопоставление выполняет очередь. Документация также описывает повторные доставки при неуспехе. Значит, обработчик обязан быть устойчивым к повтору: повторный запрос с тем же внешним событием не должен создавать вторую карточку без проверки.
Отправка ответа из CRM в MAX
Когда менеджер меняет статус или добавляет ответ в CRM, интеграционный сервис может сформировать сообщение и вызвать POST /messages. В запросе используются актуальный домен platform-api2.max.ru, заголовок Authorization и один из адресатов, предусмотренных документацией. Текст и вложения должны пройти собственную проверку длины, типа и содержания до вызова API.
Не отправляйте в MAX внутренние комментарии, технические трассировки и поля, предназначенные только для сотрудников. Полезно выделить отдельный слой представления: он превращает внутренний статус в понятную пользователю фразу, но не меняет сам статус CRM. Если MAX вернул ошибку, исходный статус CRM не следует откатывать автоматически без бизнес-правила.
Сопоставление статусов
Статусы двух систем редко совпадают один к одному. CRM может иметь «новый», «в работе», «ожидает клиента» и «закрыт», а диалог — «нужно уточнение», «ответ отправлен» и «оператор подключён». Составьте таблицу соответствий и определите, кто является источником истины для каждого перехода.
| Событие | Изменение CRM | Сообщение MAX |
|---|---|---|
| Первое обращение | Создать или найти карточку | Подтвердить приём |
| Нужны сведения | Поставить ожидание клиента | Задать конкретный вопрос |
| Ответ менеджера | Сохранить комментарий | Передать согласованный текст |
| Закрытие | Зафиксировать причину | Сообщить результат без лишних данных |
Не используйте текст сообщения как единственный источник статуса: свободная формулировка может быть неполной или измениться. Статус хранится структурированно, а текст является представлением для канала.
Дубли и повторные попытки
У каждого входящего события создайте ключ, включающий источник, внешний идентификатор и версию обработчика. Перед созданием карточки проверьте этот ключ в базе интеграции. Для исходящих сообщений используйте отдельный ключ операции и адресата. Если ответ CRM потерян, не создавайте новый объект вслепую: сначала выполните предусмотренный поиск по внешнему ключу или отправьте запись в ручной разбор.
Повторять можно только ошибки, которые вероятно временные. Ошибка схемы, отсутствие обязательного поля, неверная авторизация или запрет доступа требуют исправления конфигурации. Ограничение количества повторов защищает CRM и MAX от лавины запросов. Для отложенных ошибок используйте отдельную очередь, чтобы новые обращения не блокировались старой неисправностью.
Безопасность данных
Токен MAX передаётся через заголовок и хранится в секретном хранилище; официальная документация предупреждает о недопустимости разглашения токена. У CRM должны быть собственные учётные данные с минимальными правами. Интеграционному сервису не нужны права на удаление всех сделок, если задача ограничена созданием обращений и добавлением комментариев.
В журналах маскируйте телефоны, токены и содержимое сообщений, если оно может содержать персональные данные. Ограничьте срок хранения сырого события и разделите доступ к техническим логам и карточкам клиентов. Webhook-секрет проверяйте до постановки в очередь. Ссылки в сообщениях строьте только на разрешённые внутренние адреса, чтобы пользовательский текст не превращался в открытый redirect.
Учебный сценарий интеграции
В условном сценарии пользователь пишет в MAX с вопросом о заказе. Webhook принимает событие, проверяет секрет и сохраняет его с ключом внешнего сообщения. Нормализатор извлекает идентификатор пользователя, время и текст, затем ищет связанную карточку. Если карточка найдена, создаётся комментарий; если нет, создаётся новый объект по правилам CRM. Очередь фиксирует ответ, а отправитель сообщения сообщает пользователю, что обращение принято.
Если CRM недоступна, событие получает статус ожидания и не теряется. Если повторная доставка приходит после успешной записи, уникальный ключ не даёт создать вторую карточку. Это учебный пример архитектуры, а не описание реальной интеграции или обещание конкретного результата.
Тестирование до запуска
- Проверить успешное создание новой карточки.
- Повторить то же событие и убедиться, что дубль не создаётся.
- Проверить сообщение для существующей карточки.
- Отключить CRM и проверить отложенную обработку.
- Передать неверный Webhook-секрет.
- Проверить просроченный или удалённый внешний идентификатор.
- Проверить ошибку MAX при отправке ответа.
- Убедиться, что токены и персональные данные не попадают в логи.
Чек-лист эксплуатации
- Определён источник истины для каждого статуса.
- Есть таблица маппинга и версия преобразования.
- Входящие события сохраняются до долгой обработки.
- Повторы безопасны и ограничены.
- Ошибки схемы не повторяются бесконечно.
- Доступы MAX и CRM разделены.
- Мониторятся возраст очереди, ошибки и ручные разборы.
- Инструкция содержит способ отключить исходящие сообщения.
Как вводить интеграцию поэтапно
Не начинайте с двусторонней синхронизации всех сущностей CRM. Первый этап может принимать одно событие из MAX и создавать один тип обращения. На этом этапе проверяются авторизация, маппинг обязательных полей, уникальный ключ и ручной разбор ошибок. Только после подтверждения этих свойств добавляйте обратную отправку сообщений.
Второй этап вводится в режиме наблюдения: интеграция формирует предполагаемый результат, но оператор подтверждает его перед изменением CRM. Так можно увидеть, как реальные данные расходятся с учебной схемой. Например, в сообщении может не быть контакта, карточка может быть закрыта, а внешний идентификатор — относиться к другому типу пользователя.
Третий этап включает ограниченную автоматическую обработку типовых переходов. Для каждого перехода сохраняйте автора, время, источник и версию правила. При откате отключайте конкретный маршрут, а не весь канал MAX, если это безопасно. В документации проекта укажите, какие операции можно повторять, а какие требуют ручного подтверждения.
Что проверять в рабочем журнале
Журнал интеграции должен позволять ответить на вопрос владельца: «Почему в CRM нет этой заявки?» Для этого нужны внешний ключ, время приёма, результат маппинга, запрос к CRM без секретов, ответ, число повторов и текущий владелец ошибки. Запись «ошибка API» слишком общая: сохраняйте код и безопасное описание, чтобы отличить отказ авторизации от отсутствующего обязательного поля.
Сверяйте журнал с CRM и MAX на небольшой выборке. Ищите события, для которых нет внутренней записи, записи без CRM-объекта и CRM-объекты без исходного события. Это не доказывает наличие конкретной причины, но показывает, где нужен разбор. Регулярная сверка особенно важна после изменения формата сообщения, прав токена или правила сопоставления.
Согласование ответственности
До включения автоматизации назначьте владельцев трёх зон. Владелец канала отвечает за токен, подписку и Webhook. Владелец CRM отвечает за обязательные поля, права и смысл статусов. Владелец процесса отвечает за то, какие действия можно выполнять автоматически и какие требуют подтверждения. Без такого разделения технический сбой легко принять за ошибку бизнес-правила.
В рабочей инструкции укажите контакт для каждой ошибки, допустимый способ повторной обработки и способ остановить интеграцию. Если оператор исправляет запись вручную, он должен отметить причину, чтобы следующий разбор не выглядел как случайное изменение. Это особенно важно для спорных статусов и обращений, где повторное сообщение может запутать клиента.
При смене ответственного пересматривайте доступы и секреты, а не только список контактов. Удалённый сотрудник не должен сохранять возможность отправлять сообщения или менять карточки через старый токен. Любое такое изменение фиксируйте в журнале релизов.
Проверка контрактов данных
Перед каждым заметным изменением полезно сравнивать фактические входящие события с ожидаемой схемой. Проверяйте обязательные поля, типы значений, кодировку текста и допустимые значения статусов. Если MAX или CRM добавляет поле, не подставляйте его смысл автоматически: сначала обновите модель и тестовый набор. Если поле исчезает, интеграция должна выдать понятную ошибку и передать запись в разбор, а не создать неполную карточку.
Контракт данных можно проверять на сохранённых обезличенных примерах. Такие примеры не являются реальными кейсами и не должны содержать секреты. Их задача — показать допустимые варианты сообщений, пустые поля, повтор события и ошибочный тип. После проверки результаты сохраняйте вместе с версией маппинга.
Практический вывод
Интеграция MAX с CRM получается устойчивой, когда канал, бизнес-объект и журнал обмена разделены. Официальные методы MAX задают формат сообщений и событий, но правила сопоставления, дедупликации, повторов, доступа и хранения данных остаются частью вашей архитектуры. Начинайте с одной операции и измеримого статуса, затем расширяйте обмен после проверки повторов и ошибок.