Инструменты12 минобновлено

Бот для MAX на Python

Бот для MAX на Python пишется за вечер, и почти весь этот вечер уходит не на код. Код эхо-бота занимает строк тридцать, и Claude Code выдаст их с первого раза. Время уходит на три вещи, о которых в старых примерах из интернета нет ни слова: кто вообще имеет право получить токен, почему первый же запрос падает с ошибкой сертификата и какие методы API за 2026 год уже сменили адрес или исчезли. Ниже порядок, в котором я бы делал это сейчас, со сверкой по документации dev.max.ru на 26 сентября 2026 года.

Что нужно до первой строки кода

Сначала про право на бота, потому что здесь многие застревают раньше, чем открывают терминал. Документация MAX пишет прямо: подключение к платформе MAX для партнёров, а значит к чат-ботам, мини-приложениям и каналам, доступно юрлицам, ИП и самозанятым, которые являются резидентами РФ. Если ты самозанятый и делаешь бота для компании, чек с её ИНН и документы для бухгалтерии разобраны в статье самозанятый и ООО. Создать бота можно только из верифицированного профиля. Физлицу без статуса токен не выдадут, и никакой промпт это не обойдёт.

Второе: пользователи увидят бота только после модерации. Статус модерации показан рядом с названием бота на платформе. Для первой проверки это не страшно, но срок запуска для заказчика считай с запасом на модерацию. Как взять за такую работу аванс и выбить на него чек, разобрано в статье как принимать оплату самозанятым.

Третье: сам токен. Он присваивается при создании бота. На платформе business.max.ru он лежит в разделе «Чат-боты»: выбираешь бота, жмёшь ⋮, потом «Настройки», справа от поля с токеном есть значок копирования. Если профиль верифицирован через мини-приложение «MAX для бизнеса», токен выдаёт и одноимённый бот по команде «Получить токен».

Что ещё понадобится: Python 3 на машине, установленный Claude Code и папка под проект. Агента пока нет - сперва установка Claude Code, потом возвращайся к боту.

Бот - это первый проект, где агент работает с секретом, и правила для него лучше записать заранее: какие файлы не трогать, что не печатать в чат, что спрашивать перед запуском. Если такие проверки повторяются из проекта в проект, их можно отдать отдельному агенту-помощнику: он собирается одним файлом, порядок разобран в статье как создать ИИ-агента. Шаблон таких правил для Claude Code и Codex и мои собственные настройки лежат в базе ClaudeBase.

На каком ты этапе с ботом

  • Токена нет и профиля нет. Сначала верификация на платформе MAX для партнёров. Код можно писать параллельно, но проверить его без токена не получится.
  • Токен есть, Python и Claude Code стоят. Иди сразу к разделу про сертификат, потом к промпту.
  • Бот уже написан по старому примеру и не отвечает. Смотри раздел про изменения API за 2026 год и частые ошибки: скорее всего, дело в домене или в способе передачи токена.
  • Бот работает на Long Polling, пора на прод. Тебе нужен раздел про вебхук.

Как хранить токен, чтобы агент его не засветил

Токен даёт полное управление ботом от твоего имени. Документация отдельно предупреждает: его могут отозвать за нарушение правил платформы, так что утечка обойдётся не только чужими сообщениями от твоего бота.

Правило простое. Токен лежит в файле .env в корне проекта, одной строкой вида MAX_TOKEN=.... Файл .env сразу вносится в .gitignore. В коде токен читается из переменной окружения, строкой его никто не вписывает. Этого же я прошу от агента: в CLAUDE.md проекта одна строка о том, что .env не открывать и значения из него не печатать.

С 2026 года есть ещё одна деталь, на которой ломаются старые примеры. Передача токена через параметр в адресе, ?access_token=..., больше не поддерживается. Токен идёт только заголовком Authorization, без слова Bearer перед ним. Так написано в разделе «Авторизация» документации, и так выглядит их собственный пример запроса:

curl -X GET "https://platform-api2.max.ru/me" \
  -H "Authorization: <твой токен>"

Почему первый запрос падает на сертификате

Это главный сюрприз API MAX для тех, кто раньше писал ботов для Telegram. В шапке каждой страницы документации сейчас висит одно и то же: запросы направлять на домен platform-api2.max.ru вместо platform-api.max.ru и добавить сертификат Минцифры в список доверенных.

Я проверил это на обычном Mac 26 сентября 2026 года. Сертификат platform-api2.max.ru выпущен центром «Russian Trusted Sub CA» Министерства цифрового развития. В стандартном наборе доверенных сертификатов его нет, поэтому и curl, и Python отказываются соединяться ещё до того, как сервер посмотрит на токен. Python на такой запрос отвечает так:

[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate

Чинится это двумя путями. Первый: установить корневой и выпускающие сертификаты НУЦ Минцифры в систему, как предлагает страница сертификатов на Госуслугах. Второй, который я выбираю для проекта: скачать те же сертификаты, собрать их в один файл рядом с кодом и передавать путь к нему в requests параметром verify. Так настройки твоей машины не меняются, а бот на сервере возьмёт тот же файл.

Чего делать не надо: отключать проверку сертификата. Агент иногда предлагает verify=False как быстрый способ «чтобы заработало». Работать будет, но тогда любой посредник в сети может подменить ответы сервера и прочитать токен из заголовка. Если видишь такое в плане, отклоняй.

Какой промпт дать Claude Code

Начинай с режима плана. В Claude Code он включается клавишами Shift+Tab, они переключают режимы по кругу, или приставкой /plan перед одним сообщением. Агент в нём только читает и составляет план, а файлы меняет лишь после твоего согласия.

Промпт, с которого я бы начал:

Хочу простого эхо-бота для мессенджера MAX на Python.
Документация API: https://dev.max.ru/docs-api (сверяйся с ней, а не с памятью).

Условия:
- библиотека requests, без сторонних обёрток над API MAX;
- сервер https://platform-api2.max.ru, токен в заголовке Authorization,
  читать из переменной MAX_TOKEN в файле .env;
- сертификаты Минцифры лежат в файле certs/russian_trusted.pem,
  передавать его в requests через verify, verify=False не использовать;
- получать события через GET /updates (Long Polling) с marker и timeout,
  только тип message_created;
- отвечать отправителю через POST /messages?user_id=... тем же текстом;
- при ошибке печатать код ответа и тело, не падать.

Сначала напиши отдельный скрипт check.py, который делает GET /me
и печатает имя бота. Основной бот - только после того, как check.py сработает.
.env не открывай и токен никуда не выводи.

Два момента в этом промпте важнее остальных. Ссылка на документацию: без неё модель уверенно пишет по памяти, и в память попали и старый домен, и токен в адресе. И шаг с check.py: запрос GET /me проверяет сразу токен, сертификат и сеть. Если он вернул имя бота, три из четырёх причин будущих ошибок уже исключены.

По сути промпт здесь - полное техзадание. Про то, как его формулировать, есть короткая статья в словаре: промпт.

Что должно получиться в коде

Агент может написать по-своему, но по смыслу результат должен совпадать с этим скелетом. Сравни его глазами с тем, что предложил Claude Code, прежде чем запускать.

import os
import requests
from dotenv import load_dotenv

load_dotenv()
API = "https://platform-api2.max.ru"
HEADERS = {"Authorization": os.environ["MAX_TOKEN"]}
CA = "certs/russian_trusted.pem"

marker = None
while True:
    params = {"timeout": 30, "types": "message_created"}
    if marker is not None:
        params["marker"] = marker
    r = requests.get(f"{API}/updates", headers=HEADERS,
                     params=params, timeout=40, verify=CA)
    if r.status_code != 200:
        print(r.status_code, r.text)
        continue
    data = r.json()
    marker = data.get("marker")
    for upd in data.get("updates", []):
        msg = upd["message"]
        text = (msg.get("body") or {}).get("text") or ""
        user_id = msg["sender"]["user_id"]
        requests.post(f"{API}/messages", headers=HEADERS,
                      params={"user_id": user_id},
                      json={"text": f"Ты написал: {text}"[:4000]},
                      timeout=10, verify=CA)

Что здесь проверить.

marker - номер следующего ожидаемого обновления. Документация объясняет: как только ты передал marker, все предыдущие события считаются прочитанными. Если его не передавать совсем, сервер отдаёт только последнее обновление, и бот будет пропускать сообщения, пришедшие пачкой. Агент, который забыл передать marker из прошлого ответа в следующий запрос, пишет бота, который вроде бы работает, но теряет половину диалога.

timeout в параметрах - сколько секунд сервер держит запрос открытым, ожидая событий, от 0 до 90, по умолчанию 30. Тайм-аут самой библиотеки requests должен быть больше него, иначе скрипт будет сам обрывать каждый запрос.

types отсекает лишнее. Без него придут и bot_started, и message_edited, и остальные события из объекта Update, а код выше ждёт у каждого события поле message.

sender.user_id - кто написал. В личном диалоге ответ уходит ему через POST /messages с параметром user_id. Для группового чата вместо него нужен chat_id из recipient. Текст сообщения ограничен 4000 символами, отсюда срез в конце строки.

Скелет специально сделан без классов и без асинхронности. Для первого бота важно, чтобы ты мог прочитать каждую строку. Как только поймёшь, как ходят события, попроси агента разнести код по функциям и добавить обработку команд.

На этом месте обычно встаёт вопрос, сколько свободы давать агенту: пускать ли его самого запускать скрипт, ставить пакеты, ходить в сеть. Мои ответы на это собраны в уроке «Рабочее окружение: правила проекта и разрешения», он открыт участникам курса ClaudeBase.

Я сам плачу за подписки на нейросети картой для подписок «Плати по миру»: выпускается за пару минут, пополняется рублями через СБП. Оформить карту

Что изменилось в API MAX за 2026 год

Если бот собран по статье годовой давности или агент пишет по памяти, вот что уже не так. Всё ниже взято с главной страницы документации API на 26 сентября 2026 года.

  • Домен. Рабочий адрес - platform-api2.max.ru. Старый platform-api.max.ru встречается почти во всех примерах в сети.
  • Токен в адресе. Параметр access_token в строке запроса больше не поддерживается, только заголовок.
  • Список чатов. С июня 2026 года метод GET /chats не поддерживается. Для списка групповых чатов и каналов, где состоит бот, документация отправляет к POST /subscriptions.
  • Добавление участников. Метод POST /chats/{chatId}/members ограничен с 9 сентября 2026 года и удаляется 30 сентября. Готового способа добавлять людей в групповой чат через API после этой даты нет.

Отсюда практический вывод: в каждом промпте для MAX давай агенту ссылку на dev.max.ru и проси сверяться с ней. Документация меняется быстрее, чем обновляются знания любой модели.

Когда переходить с Long Polling на вебхук

Long Polling удобен для первого запуска: скрипт работает на твоём ноутбуке, публичный адрес не нужен. Но документация MAX ограничивает его прямо. Получение обновлений через GET /updates ограничено по скорости и сроку хранения событий, и для production-окружения прямо рекомендуется только вебхук.

Вебхук включается методом POST /subscriptions: ты сообщаешь MAX адрес, куда присылать события. Требования к адресу строгие, с 25 мая документация сняла поддержку обычного HTTP: только HTTPS, самоподписанные сертификаты не принимаются, нужен сертификат от доверенного центра, в том числе подойдёт сертификат Минцифры. Значит, для вебхука понадобится сервер с доменом, а это отдельная задача, которую тоже можно отдать агенту по шагам.

Ещё два лимита, о которых стоит сказать агенту заранее. Не больше двух сообщений в секунду в один диалог, чат или канал: если бот отвечает несколькими сообщениями подряд, между ними нужна пауза или очередь. И не больше 30 запросов в секунду на сервер platform-api2.max.ru в целом. Для эхо-бота это неважно, для рассылки по базе - критично.

Если хочется сравнить, как устроена та же задача у агента от OpenAI, посмотри, чем Codex отличается от Claude Code: промпт выше подойдёт обоим почти без изменений.

Частые ошибки бота MAX

certificate verify failed: unable to get local issuer certificate

Python не доверяет сертификату сервера MAX, потому что в системе нет сертификатов Минцифры. Токен тут ни при чём, запрос до него даже не доходит. Добавь корневой и выпускающий сертификаты НУЦ Минцифры в файл и передай путь к нему через verify, как в разделе про сертификат. Отключать проверку не нужно.

{“code”:“verify.token”,“message”:“Invalid access_token”}

Сервер ответил кодом 401: токен неверный или отозван. Чаще всего при копировании захватился пробел или перевод строки, либо в .env лежит токен другого бота. Скопируй токен заново из настроек бота и проверь запросом GET /me.

{“code”:“verify.token”,“message”:“No access token”}

Заголовок Authorization не дошёл до сервера. Обычно переменная окружения пустая, потому что .env лежит не в той папке, откуда запускается скрипт, или агент забыл вызвать load_dotenv(). Попроси Claude Code вывести не сам токен, а его длину: ноль значит, что переменная не прочиталась.

Бот отвечает в личке, но молчит в группе

По документации события из групповых чатов и каналов бот получает, только если он там администратор, а новые сообщения в группе приходят при праве read_all_messages. Выдай боту права администратора в настройках чата и проверь, что в ответ идёт chat_id из recipient, а не user_id отправителя.

Чек-лист перед запуском бота

  • Профиль на платформе MAX для партнёров верифицирован, бот создан, статус модерации виден.
  • Токен лежит в .env, файл .env внесён в .gitignore, в коде нет токена строкой.
  • Все запросы идут на platform-api2.max.ru, токен передаётся заголовком Authorization.
  • Сертификаты Минцифры подключены через verify, нигде нет verify=False.
  • check.py с запросом GET /me печатает имя твоего бота.
  • Эхо-бот отвечает на сообщение в личном диалоге и не теряет сообщения, отправленные подряд.
  • Для прода запланирован вебхук на HTTPS с доверенным сертификатом.

Бот для MAX - хороший пример того, как работает вайбкодинг на живом API: код пишет агент, а твоя работа - дать ему правильные условия и проверить результат по документации. Курс ClaudeBase учит ровно этому: как ставить задачу агенту, какие правила ему записать и как проверять, что он сделал. А рабочую базу можно подключить к твоему агенту: в следующем проекте он заглянет туда без напоминаний. Термины, которые встретились по дороге, собраны в словаре: агент и MCP.

Спрашивают

Пять вопросов по теме

Можно ли создать бота в MAX физлицу?

По документации на 26 сентября 2026 года нельзя. Подключение к платформе MAX для партнёров открыто юрлицам, ИП и самозанятым, которые являются резидентами РФ, и бота создают только из верифицированного профиля. Если ты физлицо, самый короткий путь - оформить самозанятость и пройти верификацию, а до этого можно писать и проверять код на токене коллеги с его согласия.

Есть ли у MAX официальная библиотека для Python?

Официальные библиотеки MAX есть для JavaScript и TypeScript и для Go, про Python документация их не упоминает. Есть сторонние пакеты на PyPI, но для первого бота они не нужны: API работает обычными HTTPS-запросами, и два метода, GET /updates и POST /messages, закрываются библиотекой requests. Ещё есть спецификация OpenAPI на GitHub, из неё можно сгенерировать клиент.

Чем Long Polling отличается от вебхука в MAX?

При Long Polling твой скрипт сам раз за разом спрашивает сервер, нет ли новых событий, методом GET /updates. При вебхуке MAX сам присылает событие на твой адрес. Документация прямо пишет, что Long Polling ограничен по скорости и сроку хранения событий и подходит только для разработки и тестов. Для работающего бота нужен вебхук на HTTPS с нормальным сертификатом.

Почему бот MAX не видит сообщения в групповом чате?

Чтобы получать события из групповых чатов и каналов, бот должен быть в них администратором. По спецификации API сообщение в группе приходит боту, только если у него есть право read_all_messages. В личном диалоге этого не нужно: пользователь пишет боту, и событие message_created приходит сразу. Проверяй сначала личный диалог, потом группу.

Сколько сообщений в секунду может отправлять бот MAX?

В документации два ограничения. Первое: не больше двух сообщений в секунду в один диалог, групповой чат или канал, лишние надо ставить в очередь или отправлять с задержкой. Второе: для стабильной работы держать не больше 30 запросов в секунду на сервер platform-api2.max.ru. Для рассылки по многим пользователям это значит очередь с паузами.

Источники