Чат-бот в MAX можно связать с Laravel-приложением через вебхуки и API мессенджера. MAX передает приложению события пользователя, Laravel обрабатывает входящие данные и при необходимости отправляет ответ в чат.
В этой статье разберем основную схему интеграции: как принимать события через webhook, работать с JSON, отвечать текстом и кнопками, а также загружать изображения и другие файлы.
Интеграция строится на событийной модели.
Когда пользователь отправляет сообщение, нажимает кнопку или запускает бота, MAX формирует соответствующее событие и отправляет HTTP POST-запрос на URL вебхука.
Laravel-приложение:
принимает запрос;
проверяет его подлинность;
определяет тип события;
извлекает нужные данные из JSON;
выполняет бизнес-логику;
при необходимости обращается к API MAX и отправляет ответ пользователю.
После успешного приема события сервер должен вернуть корректный HTTP-ответ. Если подтверждение не получено, событие может быть отправлено повторно, поэтому обработчик вебхука должен учитывать возможность повторных запросов.
Работа начинается в Business MAX. Разработчик создает чат-бота, указывает его параметры и URL вебхука. Этот URL становится единой точкой входа для событий, которые Laravel должен принимать и обрабатывать.


После настройки вебхука взаимодействие работает по циклу «событие → обработка ? ответ». Например, при создании нового сообщения MAX передает событие message_created. В запросе содержатся сведения о событии, чате, отправителе и самом сообщении.
В Laravel под webhook создается отдельный маршрут, который передает запрос в соответствующий контроллер или обработчик.
Внутри приложения желательно отделять прием webhook от основной бизнес-логики. Контроллер отвечает за получение и первичную проверку запроса, а работа с сообщениями, медиа, базой данных и сторонними системами выносится в отдельные сервисы.
Общая последовательность выглядит так:

При вызове вебхука Laravel получает HTTP POST-запрос с JSON-объектом. В нем находятся поля, по которым приложение определяет событие и получает данные для дальнейшей обработки.
Одно из ключевых полей — update_type. В отдельных событиях для обозначения типа может использоваться type.
Например:
message_created — создано новое сообщение;
bot_started — пользователь запустил бота;
message_callback — пользователь нажал интерактивную кнопку.
По типу события приложение выбирает соответствующую логику. Сообщения можно передавать в один обработчик, запуск бота — в другой, callback кнопки — в отдельный метод.
Такой подход позволяет оставить один URL вебхука и распределять события уже внутри Laravel-приложения.
Поле timestamp содержит время возникновения события.
При работе с ним следует учитывать единицы измерения. Значение может передаваться в миллисекундах, тогда как часть функций PHP работает с Unix-временем в секундах.
Поэтому перед использованием timestamp имеет смысл проверить размер числа и при необходимости привести его к секундам.
Это требуется, например, для:
сортировки сообщений;
ведения истории диалога;
сохранения времени события в базе;
сравнения событий по времени.
Основная информация о сообщении находится внутри объекта message.
Для отправки ответа особенно важен идентификатор чата. Он связывает входящее событие с диалогом, в который Laravel впоследствии отправит ответ.
Данные пользователя находятся в объекте отправителя. В приложении их можно использовать для идентификации пользователя и связи профиля MAX с внутренней учетной записью.
Текст обычно находится внутри объекта содержимого сообщения.
При обработке медиа нужно учитывать, что текст может отсутствовать либо использоваться как подпись к вложению. Поэтому обработчик лучше строить с учетом нескольких вариантов структуры входящих данных.
Медиафайлы приходят в массиве вложений. Один элемент массива описывает отдельный файл.
У вложения может быть указан тип:
image;
file;
video;
audio;
voice.
Дополнительные технические сведения находятся внутри payload. Они используются приложением для дальнейшей обработки файла.
В Laravel работу с такими объектами удобно вынести в отдельный сервис. Он получает исходную структуру MAX и преобразует ее в единый внутренний формат с ID, MIME-типом, размером, URL, токеном и другими необходимыми параметрами.
Основные поля входящих данных можно представить так:

После обработки входящего события приложение может отправить пользователю ответ через REST API MAX.
Для этого удобно создать отдельный сервис-обертку, отвечающий за работу с API мессенджера. Тогда бизнес-логике приложения не требуется напрямую формировать HTTP-запросы.
Для простого текстового ответа сервис получает как минимум:
chat_id;
текст сообщения.
После этого Laravel формирует HTTP POST-запрос к эндпоинту отправки сообщений, например /messages.
chat_id обычно извлекается из входящего события. Благодаря этому ответ отправляется в тот же диалог, из которого поступило сообщение.
После успешной отправки API возвращает результат операции. Приложение может сохранить его в лог, записать статус сообщения в базу или использовать дальше в бизнес-логике.
В обработчике можно реализовать разные сценарии в зависимости от текста пользователя.
Например:
/start запускает начальный сценарий;
команда может переводить пользователя к следующему этапу авторизации;
запрос может получать информацию из базы;
неизвестная команда возвращает сообщение с подсказкой.
Состояние диалога при этом можно хранить отдельно, например в кеше или базе данных.
Laravel обрабатывает входящее сообщение и отправляет ответ в MAX

Как работают кнопки и callback-события
Вместо обычного текста бот может отправить сообщение с интерактивными кнопками.
В JSON передается объект клавиатуры с набором кнопок. У каждой кнопки есть отображаемый пользователю текст и идентификатор действия.
Когда пользователь нажимает кнопку, MAX отправляет новый webhook с событием message_callback.
Вместе с событием приложение получает callback_data. По его значению Laravel определяет выбранное пользователем действие и выполняет соответствующий сценарий.
Например, callback можно использовать для:
подтверждения заявки;
отмены операции;
перехода к следующему пункту меню;
выбора одного из вариантов;
изменения состояния диалога.
Так можно создавать последовательные сценарии без необходимости заставлять пользователя каждый раз вводить команду вручную.
Отправка медиа отличается от обычного текстового сообщения.
Текст можно передать непосредственно в запросе отправки сообщения. Для изображения, документа или другого файла сначала требуется загрузить сам файл.
Процесс состоит из нескольких этапов.
Laravel отправляет запрос на эндпоинт загрузок с указанием типа файла.
Для изображения это может выглядеть как запрос:
POST /uploads?type=photo
В ответ MAX возвращает временный URL, на который можно передать содержимое файла.
Такой адрес действует ограниченное время и используется только для загрузки конкретного объекта.
После получения URL Laravel отправляет отдельный HTTP-запрос уже на этот адрес.
Для передачи бинарного файла используется multipart/form-data. Файл помещается в соответствующее поле запроса вместе с необходимыми параметрами.
После успешной обработки MAX возвращает JSON с данными загруженного объекта, включая токен файла.
Полученный token идентифицирует загруженный файл.
Laravel формирует обычный запрос отправки сообщения, однако дополнительно передает объект вложения с:
типом файла;
токеном.
MAX по токену связывает сообщение с уже загруженным файлом, поэтому повторно передавать содержимое изображения или документа не требуется.
Весь процесс можно представить следующим образом:

URL вебхука является внешней точкой входа в приложение. Если оставить обработчик без проверки, на него можно отправлять произвольные запросы и имитировать события мессенджера.
Поэтому входящие запросы необходимо проверять.
Для этого может использоваться секретный токен или подпись HMAC. Laravel сравнивает полученное значение с рассчитанной на своей стороне подписью. Если проверка не проходит, запрос отклоняется.
Помимо проверки подлинности, следует продумать обработку ошибок.
Webhook желательно выполнять через try...catch, чтобы один некорректный запрос не приводил к сбою всего обработчика.
После успешного приема события сервер должен вернуть HTTP 200 OK. Тяжелые операции — работу с крупными файлами, внешними сервисами, базой данных и длительные вычисления — при необходимости можно передавать в очередь.
Это позволяет быстро подтвердить прием webhook и продолжить основную обработку асинхронно.
При интеграции необходимо учитывать ограничения API:
допустимый размер JSON;
ограничения на размер файлов;
требования к заголовкам запросов;
таймауты;
повторную доставку событий;
ошибки при работе со сторонними сервисами.
Если файл превышает установленный платформой лимит, приложение должно корректно обработать ответ API и сообщить пользователю о проблеме.
Перед запуском бота стоит пройти несколько этапов.
Определить события. Зафиксировать типы событий, которые должен обрабатывать бот, и сценарий для каждого из них.
Защитить webhook. Настроить URL в Business MAX и реализовать проверку подлинности входящих запросов.
Разделить код по зонам ответственности. Обработку событий, работу с API, медиафайлами, базой данных и другими внешними системами лучше вынести в отдельные сервисы.
Изолировать тяжелые операции. Длительную обработку и внешние интеграции можно выполнять через очереди.
Предусмотреть отказоустойчивость. Обрабатывать исключения, логировать ошибки и своевременно возвращать HTTP 200 для успешно принятых событий.
Проверить интеграцию тестами. Для внутренних сервисов использовать unit-тесты, для взаимодействия с API и webhook — интеграционные тесты.