
Когда я писал своего первого более-менее серьезного бота под Max, случилась классика. Я и мой ИИ-ассистент (Cursor) пишем код, строго опираясь на официальную документацию Max API. Запускаю — падает. Сижу по 5-6 итераций, пытаюсь отдебажить базовый функционал, который под ту же Телегу пишется с закрытыми глазами.
В какой-то момент меня это достало. Я понял, что проблема не во мне и не в галлюцинациях нейронки. Я просто включил логирование всех входящих POST-запросов и стал дампить реальные вебхуки, которые прилетают от серверов Max. Открыв логи, я понял, почему мы так долго буксовали: то, что написано в документации, и то, что прилетает по факту — это две большие разницы. А слепая привычка писать архитектуру под Telegram Bot API делает только хуже.
Различия с официальной документацией Max API (Docs vs Реальность)
Обертка (Update Wrapper): В доках написано, что тебе приходит чистый объект
Message. В реальности всё завернуто в мета-контейнер: корень JSON содержитupdate_typeиuser_locale, а самmessageуже запрятан внутри.Таймстемпы: Доки обещают классический «Unix-time» (что логично воспринимать как секунды). В реальности Макс шлет таймстемпы в миллисекундах. Парсишь в лоб как секунды — улетаешь в 57000-й год.
Путь к тексту: В доках указано просто
body.text. В реальности текст закопан глубоко по пути:payload['message']['body']['text'].
Отличия от Telegram Bot API (TG vs Max)
Где лежит юзер: В Телеге мы берем инициатора из
message.from. В Максе это поле называетсяsender. Причем у обычных юзеров там часто вообще нетusername, опираться приходится только на полеname.Архитектура кнопок (Callbacks): В Телеге при нажатии кнопки
messageвложено внутрьCallbackQuery. В Максе инфа о нажатии (callback) и само сообщение (message) приходят на одном уровне, как братья. ID того, кто нажал кнопку, нужно искать вcallback.user.user_id, а не в отправителе сообщения.Где лежат клавиатуры: В Телеге кнопки живут в удобном отдельном поле
reply_markup. В Максе клавиатура — это просто одно из вложений. Она лежит в массивеattachments(с типомinline_keyboard), прямо вперемешку с отправленными картинками.
Как отучить ИИ галлюцинировать (и спасти свои нервы)
Всю эту боль я собрал в единый файл-шпаргалку: MAX_API_Real_Payloads_2026.md. Поначалу я просто держал его открытым на соседнем мониторе, чтобы каждый раз сверяться: «А не бьюсь ли я сейчас лбом об один из этих шести пунктов?».
Но основную разработку я веду в Cursor, и меня дико бесило, что ассистент постоянно пытается подсунуть мне телеграмовские структуры. Решение оказалось до смешного простым. Я положил этот файл в корень проекта и прописал жесткое условие в .cursorrules: «Прежде чем писать любой код для интеграции с Max API, обязательно спарси файл MAX_API_Real_Payloads_2026.md и используй структуры только оттуда».
Работа пошла х2 быстрее. Я перестал тратить часы на дебаг абсолютно тривиального функционала.
Поняв, что эта проблема массовая, я пошел в опенсорс. Сделал Pull Request в самую популярную Python-библиотеку под Max — maxapi. Автор оценил проблему, вмержил PR, и теперь шпаргалка официально лежит у них в папке /docs.
Затем закинул аналогичный PR ребятам из официального SDK на Go — max-bot-api-client-go. Они тоже приняли изменения, файл теперь живет у них в директории /schemes.
----------------------------------------------------------------------------
Готовая таблетка: Boilerplate без боли
Поняв всю эту архитектурную дичь, я решил, что парсить многоуровневые словари через dict.get() и ловить KeyError — это путь в никуда. Поэтому я собрал max-bot-aio-template. Это не "hello world", а нормальный стартовый каркас для ботов, ориентированный на строгую типизацию.
Что под капотом:
Pydantic V2 на входе: Никаких сырых JSON. Все кривые ответы MAX API (с их миллисекундами и спрятанными текстами) сразу валидируются и превращаются в предсказуемые объекты.
Зашитый AI-контекст: Тот самый
MAX_API_Real_Payloads_2026.mdи.cursorrulesуже лежат в репозитории. Клонируешь, открываешь в Cursor/Copilot — и нейронка с ходу пишет правильный код под Макс.Изоляция логики (Layered Architecture): Бизнес-логика полностью отвязана от API мессенджера. Если завтра Макс выкатит v2, переписывать придется только слой Delivery.
Джентльменский стек: Python 3.12, асинхронная SQLAlchemy 2.0, Redis и настроенный Docker с миграциями.
? Ссылка на файл: https://github.com/Danya2904/max-bot-aio-template/blob/main/docs/MAX_API_Real_Payloads_2026.md
Ссылка выше это файл Paa max-bot-aio-template на GitHub
Буду рад звездам и форкам. Если Макс снова поменяет API (а он их рано или поздно поменяет) — давайте контрибьютить новые пейлоады вместе, чтобы поддерживать актуальный стандарт и не дебажить поодиночке.
? А если хотите обсудить архитектуру под новую платформу — залетайте в наш профильный чат: Max Chat.
Комментарии (14)

notlimitedwolf
01.03.2026 22:08Во время чтения статьи постоянно было ощущение, что рук здесь нет у автора, а не у создателей api. Сейчас ради интереса открыл доки их api, с которыми раньше вообще не работал, и первое же что я вижу - это update, которого якобы
Обертка (Update Wrapper): В доках написано, что тебе приходит чистый объект Message. В реальности всё завернуто в мета-контейнер: корень JSON содержит update_type и user_locale, а сам message уже запрятан внутри
там нет.
Ну и предъяву
Архитектура кнопок (Callbacks): В Телеге при нажатии кнопки
messageвложено внутрьCallbackQuery. В Максе инфа о нажатии (callback) и само сообщение (message) приходят на одном уровне, как братья. ID того, кто нажал кнопку, нужно искать вcallback.user.user_id, а не в отправителе сообщения.
Я тоже не понял. Для меня звучит логично. Просто надо не втупую всё нейронкам кормить а самому в коде разбираться

ArtyomOchkin
01.03.2026 22:08Верно отметили. Ещё когда не было возможности у любого создания там ботов, как и каналов, глянул API, и как ни странно, выглядело уже ближе к середине - концу 2025 вполне прилично. А авторов со слабым пониманием "их" кода на Хабре всё больше. Увы...

Freeman_RU
01.03.2026 22:08Вот оно, покаление вайб-кода. Можно узнать где в документации написано, что вам прилетает message, когда в подписке белым по черному, и даже на русском языке написано, что вы подписываетест на update, и там даже сразу дана ссылка на объект update?
Про время могу согласиться, но должно же было натолкнуть на мысль разрядность int64 ( обычное влезает в int32). Проверяйте за нейронкой, много времени съэкономите.

NaroMori
01.03.2026 22:08TLDR: отличное от telegram приложение имеет отличный от telegram API. Для написания обёртки под вышеуказанной API потребовались часы работы и помощь ИИ агента.
Может у меня уже PTSD, но статья тоже нейрослоп?:
... (Docs vs Реальность)
... — улетаешь в 57000-й год.
В реальности...(x10)

dmitrik4321
01.03.2026 22:08Да, тоже заметил, если не полностью, так доработать. Предположу, что Qwen, ибо chatgpt

Crot_slm
01.03.2026 22:08И ведь не стыдно не то что пользоваться, а пилить контент под этот вирусняк.

olololollloo
01.03.2026 22:08После телеграм бот апи и телеграм апи, там же как в песочнице поковыряться, не понял проблемы вообще

Danya2904 Автор
01.03.2026 22:08Я тоже считаю, что апи с телеграмом практически идентичны. Вот я и описал главные различия, в которые могут уперется разработчики, переходя из Telegram Bot API в Max API

slgfire
01.03.2026 22:08А зачем привязываться к used_id на колбеках? А если у тебя 2 3 ветки колбэков в чате с 1 юзером? Мне кажется mid самое оно, макс вроде на него заточен, и вообще вся эта типизация - у кого-то много времени, делаешь path поиск по json и вообще по барабану что туда накидают и в какой версии....
TimurZhoraev
Самое интересное - попросить написать скрипт для реверс-инжиниринга пакетов. Вполне возможно что при сопоставлении с RAG документацией эта ошибка будет найдена. Тогда вопрос - можно ли это автоматизировать средствами самого курсора или вскода. Получится тогда тест-обёртка спецификаций - весьма полезная штука от ленивых разработчиков документации.