Всем привет. Последние несколько месяцев (где-то с февраля-марта) мне пришлось активно взяться за разработку чатботов для MAX. Когда только пытался изучить в прошлом году эту тему, поиск материалов по этим вопросам дал несколько странные результаты: вроде что-то есть и описано, а бота создать «сейчас не получится, попробуйте позже». Эту проблему впоследствии частично решили, но актуальности материалам, на мой взгляд, не то что прибавилось, и тема скорее игнорируется. Поэтому для тех, кому ставятся такие задачи, задумал несколько публикаций по практике создания чатботов в MAX, а также поделиться своей библиотекой для yii2 (она уже есть и вовсю используется в production на нескольких проектах, но пока не в полном объёме, сейчас активно дорабатывается и причёсывается; к следующей публикации надеюсь дописать и выложить).
Скрытый текст
Сразу оговорюсь: здешнее отношение к маху мне известно. У меня оно сугубо прагматичное: если в каких-то условиях деструктивное нытьё не работает, то и решать проблему хочешь или нет, надо конструктивно — то есть, делом. Поставили задачу бота сделать — выполняем.
В этой, первой, публикации опишу текущий способ и условия регистрации ботов в MAX, расскажу про отличия Bot API у Telegram и MAX и приведу проверенный Hello, world на чистом PHP.
Disclaimer: материал данной части собирался и описывался в течение начала-середины 2026 года. И публикация содержит информацию, актуальную на момент сбора. Не быстро, но всё же меняются и API, и методики. Возможно, на момент прочтения информация здесь может быть не очень актуальной или содержать ошибки; для серьёзной работы рекомендуется предварительно проверить всё самостоятельно.
Порядок регистрации ботов в MAX
Начнём с условий и порядка создания ботов. Для регистрации бота на момент написания материала нужен аккаунт в MAX и верифицированный бизнес-аккаунт хозяйствующего субъекта на бизнес-портале MAX business.max.ru с тем же номером телефона. Такой аккаунт могут завести российское юридическое лицо или индивидуальный предприниматель. Верификация хозяйствующего субъекта доступна через портал госуслуг и несколько крупных банков. Обладание таким аккаунтом даёт возможность создать один публичный канал и до пяти ботов. При этом их публичные имена будут прямо указывать на владельца, т. к. содержат его ИНН. Но некоторые боты имеют нормальные публичные имена. Как они это сделали, не знаю, предполагать не буду; у меня задач по переименованию не было.
Сама регистрация бота осуществляется на бизнес-портале после верификации и привязки аккаунта в MAX. Порядок несколько месяцев назад был такой: заполняется форма с данными (а просят там в том числе сайт и телефон компании, и попробуй не введи, но никто не мешает давать ссылки на другие площадки в качестве сайта), которые после ввода уходят на модерацию. Модерация, если я правильно помню написанное (дело было уже не один месяц назад), длится до нескольких часов, в моём случае управились минут за 20. Может, потому, что делал в рабочее время по московскому, не знаю.
Уведомление о прохождении модерации приходит в MAX. Дальше на том же портале делается токен доступа к боту, который используется в API.
Подытоживаем: порядок весьма своеобразный, но в принципе работающий невзирая на ограничения. Пару ботов под отладку своей либы и отдельно ботов под проекты я завёл; разработчики, работающие на российские компании, с помощью своих работодателей тоже могут завести ботов под свои задачи. Но: практически всё делающееся через бот делается под токеном, принадлежащим бизнесу, действия логируются, а штрафы за какие-то пусть неосознанные, но незаконные действия для бизнеса, как правило, выше, чем для обычных граждан. Поэтому и с отладкой стоит быть аккуратнее, и боевые задачи, если речь идёт, например, о чувствительных данных вроде персональных, не мешает обсудить с юристом, которому дополнительно можно дать почитать громадное количество правил, требований и инструкций от MAX. Публичных каких-то средств для тестирования и отладки от MAX я не видел. Так что осваиваемся, что называется, в учебно-боевых условиях.
Разница в Bot API у MAX и Telegram
Перейдём к API. Он описан на портале для разработчиков dev.max.ru; в нём сейчас около 30 методов (а всего в библиотеке описаний запросов, ответов и объектов у меня получилось на данный момент 82, и это я ещё некоторые структуры объединил). Разработчики MAX опубликовали на github и поддерживают две официальных библиотеки — под TypeScript и Golang. В последнее время я занимаюсь работой на PHP с фреймворком yii2, и переписывать большие проекты на что-то предложенное нет ни времени, ни желания. Так что взялся за разработку библиотеки и пока в несколько недоделанном варианте использую её в нескольких проектах. Но про неё напишу в следующих частях.
Так получилось, что мне приходилось и до сих пор приходится активно заниматься разработкой и сопровождением чатботов для Telegram. И не особо сомневаюсь, что backend-коллеги, которым нужно работать по чатботам MAX, уже во многом имеют аналогичный опыт работы с Telegram-ботами. Поэтому считаю, что будет полезно описать основные глобальные и не очень отличия для понимания, как организовать разработку для своих языков программирования, сред разработки и исполнения. Всю документацию, конечно, пересказывать не буду; просто опишу то, что выловилось в процессе разработки либы.
Первое — способы отправки запросов к Bot API
В Telegram токен бота передаётся в URI запроса, а HTTP-метод запроса имеет относительно небольшое значение. Поэтому с ним для простой отправки сообщения в том же PHP можно слепить URL из всех необходимых параметров, дёрнуть его командой file_get_contents, и дело в шляпе.
С MAX так не получится: токен передаётся через заголовок запроса, параметры в зависимости от метода API приходится подставлять и в URI, и в query string, и в тело запроса JSON-ом, ну и HTTP-методы используются разные. Т. е., не обойтись без полноценного HTTP-клиента вроде curl и работы с JSON, а для экспериментов можно использовать Postman, RESTer и другие подобные продукты или небольшие скрипты. Ну хоть ответ всегда возвращается в JSON (ну кроме скачиваемого файла). Ниже, в разделе «Hello, world», будет пример кода отправки сообщения на чистом PHP; если заведёте бота, можете поэкспериментировать.
Второе — получение апдейтов
Как и в Telegram, в MAX для получения ботом информации о новых событиях (апдейтов) реализованы два механизма: long polling (запрос бота на сервер мессенджера) и вебхуки (мессенджер сам отправляет запросы на заданный URL бота).
Отличие: MAX настоятельно не рекомендует, если вообще не запрещает (в разных местах документации написано по-разному, и понять не очень просто), использовать long polling в продакшне.
Дополнение №1: при опросе MAX-бота в бесконечном цикле с какими-то другими действиями важно не забывать устанавливать в запросе параметр timeout, иначе ожидание ответа может длиться с полминуты, если апдейтов нет.
Дополнение №2: при опросе необходимо считывать из ответа и далее подставлять снова в запрос параметр marker. В противном случае апдейты в выдачах могут дублироваться.
Отдельно предостерегу от попыток использования long polling на боте, подписанном на вебхуки. Телеграм в этом случае с ходу посылает запрашивающего клиента лесом, а Макс почему-то нет. Какие апдейты он отдаст, а какие нет — непредсказуемо. Так что сначала делаем GET /subscriptions (метод получения списка подписок в MAX Bot API), затем по каждой подписке делаем DELETE /subscriptions (URL удаляемой подписки идёт в запрос), а после этого уже можно поллить.
По вебхукам у меня нормально заработал вариант с сервером в России и SSL-сертификатом от Let’s Encrypt. Работает только https на дефолтном порту TCP/443, нестандартные порты и самоподписанные сертификаты не поддерживаются. Отправку Максом вебхук-запросов за бугор (как и приём оттуда запросов) не проверял.
В вебхуках при отправке запроса на подписку очень важно задавать параметр secret и сверять его значение со значением HTTP-заголовка X-Max-Bot-Api-Secret каждого входящего запроса. По сути это единственная имеющаяся на данный момент в MAX защита от подделки входящих запросов.
Третье — начало и конец общения пользователя с ботом
В Telegram, как мы знаем, «личную» переписку с чатботом всегда начинает пользователь. При этом боту в апдейте приходит сообщение с текстом /start. А в MAX первое, что нужно сделать пользователю чатбота для начала работы с ним, это в чате или профиле бота нажать кнопку «Начать» (по сути — подписаться на бота и позволить ему отправлять пользователю сообщение). При этом боту приходит не сообщение, а апдейт с типом bot_started; при его обработке часто есть смысл зафиксировать id и контакт пользователя и отправить ему какое-нибудь приветственное сообщение. После «начала» кнопка «Начать» исчезнет, а в выпадающем меню окна профиля бота появятся варианты «Остановить» и «Удалить и остановить». При выборе любого из этих вариантов произойдёт отписка от бота, и боту отправится апдейт с типом bot_stopped. После «остановки» бота отправить пользователю сообщение не получится, пока пользователь вновь не нажмёт «Начать»; боту есть резон зафиксировать у себя, что подписка приостановлена, и до возобновления подписки не пытаться что-то этому пользователю отправлять.
Четвёртое — форматы id
У Telegram, как известно, все id числовые, а id сообщения представляет собой его порядковый номер в конкретном чате. В MAX многие id также числовые, но не id сообщения. Последний имеет строковой тип; там что-то больше похожее на длинный уникальный идентификатор, глобальный минимум в пределах всего мессенджера. И, например, при удалении сообщения соответствующему методу нужно передавать в запросе только id сообщения; id чата не нужен.
Про основные функциональные отличия
Скачивание файлов ботом
Максимальный размер загружаемого файла у обоих мессенджеров составляет 4 гигабайта. Но, если у Telegram бот может скачать файл-вложение максимум в 20 мегабайт, то у MAX такое ограничение (пока?) отсутствует. При этом, насколько я понял, ссылки на скачивание файлов MAX отдаёт не временные, а постоянные. Это очень упрощает скачивание, но насколько это безопасно — вопрос.
Получение сообщений из чата
Если бот подписан на какой-то чат или канал, то Telegram, если я правильно помню, шлёт апдейты о новом сообщении или посте в канал, и на этом всё: после обработки (или необработки) апдейта сообщение через Bot API более не доступно.
В MAX есть пока мной не проверенный, но метод GET /messages, ему можно подсунуть id сообщений или chat_id, и получай JSON с данными. На мой взгляд, это плюс, если адекватен механизм контроля доступа. Для бэкапов очень даже норм (надеюсь, никто не возражает, что резервное копирование переписки в мессенджере у себя иногда бывает очень полезным).
Кнопки под сообщениями из бота
В Telegram Bot API реализованы весьма богатые возможности для подстановки кнопок под сообщения, сформированные ботом. Но с ними не всегда с ходу получается разобраться, и порой случаются вещи, требующие долгой возни.
В MAX для этого к сообщению прикладывается относительно простой аттач с типом inline_keyboard и описанием кнопок. Но есть особенности.
Особенность 1: в MAX клавиатуру нельзя с помощью её настроек сделать исчезающей после нажатия кнопки. Пока не проверял, но, по идее, редактированием сообщения через соответствующий метод бота после обработки нажатия кнопки можно аттач убрать, и тогда клавиатура исчезнет.
Особенность 2: для MAX придётся учиться писать названия кнопок коротко. Текст названия кнопки, не помещающийся в её размер, не переносится даже по словам, а просто остаётся за границами видимой области. При этом на десктопной и мобильной версиях размеры этой видимой области получаются разные. В документации в описании к соответствующему методу MAX даны рекомендации по максимальному количеству символов, которые рекомендуется использовать.
Меню команд
В MAX Bot API есть метод задания меню команд, но вот работа созданного им меню на клиентах… я пока так до конца и не понял, как с ней обстоит дело. На мобильных под Android это меню есть, но нет отдельной кнопки для его вызова; надо догадаться нажать / на клавиатуре. На десктопной версии под Windows этого меню нет вообще (или не сработало у меня?). Веб-версию и огрызки лично не проверял (а с последними событиями появились сомнения в смысле проверки на огрызках). При этом есть распознавание текста команды в тексте сообщения с автоматической подстановкой ссылки. Но работает почему-то не у всех пользователей бота; что когда, пока так и не понял. В общем, провожу пока исследование и приглашаю коллег в помощь — вдруг кто-то уже понял принципы.
Текстовый контент сообщений
В отправляемом сообщении у Telegram Bot API можно задать один из трёх режимов парсинга текста: plain text, markdown и HTML. У MAX нет plain text. Также нет возможности сделать и задать скрытый текст. Ну и не разбирался со сколь-нибудь сложным форматированием текста; мои задачи пока этого не требовали. Под документирование этого дела есть отдельная страница на портале разработчиков MAX – https://dev.max.ru/docs-api#Форматирование текста в сообщениях
Ещё. Не проверял, как в Telegram, но в MAX не поддерживаются гиперссылки, у которых в URL указаны протоколы вроде tg, max и т. п. Такая ссылка в клиентском приложении не будет подсвечиваться как ссылка. Аналогично, если написать символ @ и публичное имя и попытаться добавить гиперссылку, например, на t.me с Telegram-профилем: у меня это не сработало (проверял с месяц назад).
Бан-разбан
Как известно, в Telegram Bot API есть запросы banChatMember и unbanChatMember. У MAX есть метод удаления пользователя из канала или чата DELETE /chat/{id}/{members}. И у этого метода есть применимый к чатам параметр block — забанить пользователя помимо удаления. Вроде бы и норм, но нигде не нашёл, как разбанить обратно. Поэтому этим параметром пользуемся с максимальной осторожностью. И тест на бан я делать точно не собираюсь. Так или иначе, пока чаты в MAX закрыты, практического смысла использовать эти методы там в принципе не очень много, да и сами принципы отображения добавления и удаления пользователей в чате имеют немало недостатков. Поэтому считаю, что лучше дождаться доработок.
Редактирование данных бота — undocumented в MAX
В документации по API MAX отсутствует информация о возможности редактировать данные бота через API; при этом соответствующий метод есть в штатной библиотеке для TypeScript, и он работает (в том числе в моей либе, но в production я его не применял). Отредактировать так публичное имя бота не получится; изменения, внесённые через API, применяются сразу, без модерации.
Опросы
В обоих мессенджерах есть возможность создавать опросы; у Telegram возможностей побольше, у MAX поменьше. Но в Telegram Bot API есть возможность отправить опрос ботом (метод sendPoll), а в MAX – почему-то нет.
Лайки
В Telegram, как известно, боты могут принимать апдейты вида MessageReactionUpdated – когда пользователь ставит лайк на сообщение. Ну и бот тоже может сам ставить лайк на какое-то сообщение, отправив запрос setMessageReaction. Это бывает удобно в рабочих чатах, когда бот является полноценным «участником» чата. В MAX, к сожалению, ничего такого (пока?) нет.
Прочее
Ещё про функциональное отличие, но уже не мессенджера. Документация по Telegram Bot API сделана в одном HTML-файле, и её легко скачать одним запросом. А для мониторинга изменений в ботовом API MAX приходится смотреть десятки ссылок.
Отдельно вкратце опишу загрузку файлов ботом MAX. Делается она в два приёма. Сначала POST-запросом передаётся тип файла, в ответ возвращаются URL для загрузки собственно файла и токен для последующей подстановки файла в отправляемые сообщения (можно не в одно). Загружаем файл POST-запросом на URL (описание API предлагает два способа), иногда ждём подготовку, и можно отправлять сообщение. Сам пока только отрабатываю эту тему на практике, отлаживая библиотеку на разрабатываемых примерах. Описано всё в документации здесь — https://dev.max.ru/docs-api/methods/POST/uploads
Также MAX имеет возможность создавать мини-приложения на базе ботов, и они уже в общем неплохо работают в качестве суррогатных заменителей комментариев к каналам. Но в этой теме, да и вообще во frontend-разработке, я не настолько силён, чтобы что-то писать. Подробности расписаны на портале разработки MAX. А мы продолжим бэк и наконец перейдём к Hello, world.
Hello, world
На чистом PHP 8-й версии с расширениями curl и json функция отправки ботом «в личку» пользователю сообщения с текстом выглядит примерно так:
/** * @param string $botToken токен бота * @param integer $userId id пользователя-получателя * @param string $text текст (HTML-код) сообщения * @return mixed Ответ от сервера */function sendTextMessage(string $botToken, int $userId, string $text): mixed{ /** @var string $url URL запроса */ $url = 'https://platform-api.max.ru/messages?user_id=' . $userId; /** @var CurlHandle $ch handle объекта cURL */ $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_VERBOSE, false); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Host: ' . parse_url($url, PHP_URL_HOST), 'Accept: application/json', 'Content-Type: application/json', 'Authorization: ' . $botToken, ]); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([ 'text' => $text, 'format' => 'html', ], JSON_UNESCAPED_UNICODE)); return curl_exec($ch);}
id своего пользовательского аккаунта в MAX для получения сообщений от бота можно получить, подписавшись на бот (кнопка «Начать» в профиле бота или чате) и приняв апдейты от бота. Дальше в материале я покажу это на практике. Если вебхуки на бот не прописаны, то для этого можно любым http-клиентом сделать такой запрос (пример — опять же функция на чистом PHP):
/*** @param string $botToken токен бота* @param string|null $types Типы апдейтов через запятую и пробел* @param integer $timeout Сколько секунд висеть запросу в ожидании апдейтов* @param integer|null $marker Маркер от предыдущего запроса* @return mixed Ответ от сервера*/function getUpdates(string $botToken, ?string $types = 'bot_started, bot_stopped', ?int $timeout = 1, ?int $marker = null): mixed{ /** @var array $getParams параметры GET-запроса */ $getParams = []; if (isset($types)) { $getParams['types'] = $types; } if (isset($timeout)) { $getParams['timeout'] = $timeout; } if (isset($marker)) { $getParams['marker'] = $marker; } /** @var string $url URL запроса */ $url = 'https://platform-api.max.ru/updates'; if (!empty($getParams)) { $url .= '?' . http_build_query($getParams); } /** @var CurlHandle $ch handle объекта cURL */ $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_VERBOSE, false); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Host: ' . parse_url($url, PHP_URL_HOST), 'Accept: application/json', 'Authorization: ' . $botToken, ]); return curl_exec($ch);}
В этом коде сначала в зависимости от значения параметров собирается key-value массив. Дальше из него формируется query string для запроса, в отдельном key-value массиве собираются заголовки запроса, всё это отдаётся в CURL, запрос отправляется, и функция возвращает контент того, что сервер отдал в ответ (в кодировке JSON).
Лирическое отступление про получение других id
С получением id чата будет посложнее. Бот добавляется в чат через интерфейс мессенджера сначала с правами рядового пользователя, а затем может быть назначен администратором. Но: апдейт с типом bot_added и id чата (собственно приём этого апдейта и есть способ получения id) придёт при добавлении бота как пользователя, а апдейты message_created (уведомления о сообщениях) будут приходить только после того, как участник с соответствующими правами в чате назначит бота админом; об этом назначении бот никакими апдейтами не уведомляется. Что можно делать боту-пользователю, не знаю, не исследовал вопрос. Пока могу только предположить, что он может просто постить какие-то сообщения, но это ещё требует проверки.
По каналам (проверял на частном) несмотря на наличие кнопки «Добавить администратора» туда добавить бота не получилось. Получилось так же, как с чатом: добавил бота подписчиком — пришёл апдейт bot_added, где в chat_id был id канала; потом назначил его администратором и таким образом получил возможность постить в канал.
На всякий случай: в MAX Bot API (во всяком случае пока) получить id и другую информацию по публичной ссылке можно только для публичного канала методом GET /chats/{ссылка}; и то это я пока не проверял. Других методов не видел.
Заканчиваем Hello, world
Для здешнего Hello, world нужно иметь машинку с PHP8, библиотекой и расширением curl и зарегистрированного MAX-бота с публичным именем и секретным токеном.
Первым делом создаём скрипт, куда копируем вышеприведённые функции и пишем их вызовы с обязательным выводом результата на экран, в файл или другое доступное место. В вызовы подставляем текст сообщения (Hello, world) и токен бота.
Теперь получаем id пользователя бота. Для этого в мессенджере по публичному имени находим бота, в нём нажимаем «Начать». После этого скриптом вызываем функцию getUpdates и в её результате находим id пользователя. Результат, конечно, записываем.
Осталось дописать в вызов функции sendTextMessage полученный id своего пользователя и выполнить этот вызов в скрипте. Если всё нормально, то пользователю от бота придёт сообщение, которое можно будет в мессенджере прочитать.
Итог
В первом материале мы разобрали особенности работы с MAX Bot API без привязки к конкретному языку с примерами на PHP. В следующем рассчитываю рассказать про yii2-библиотеку и на примерах её использования описать отправку запросов посложнее (например, сообщения с кнопками, загрузка файлов — посмотрим). Если есть какая-то актуальная тема для рассмотрения в общем плане, пишите в комментах — может, что-то уже делал, и есть что рассказать.
ссылка на оригинал статьи https://habr.com/ru/articles/1047336/