MAX Bot API · Для начинающих · 45 минут

AI‑бот в MAX: от кабинета до защищённого webhook

Разберём не только код, но и архитектуру. MAX отправляет событие на наш HTTPS‑адрес, приложение проверяет секрет, получает ответ AI и вызывает Bot API.

Ограничение платформы: создать бота может организация, ИП или самозанятый с верифицированным профилем на платформе MAX для партнёров. Если такого профиля нет, сначала пройдите верификацию.

Webhook и API простыми словами

API — набор адресов, к которым программа обращается по правилам. Webhook — обратная схема: MAX сам отправляет POST‑запрос на наш сервер при новом сообщении. Для продуктового запуска официальный MAX рекомендует webhook, а не постоянный опрос.

Webhook должен работать по HTTPS на стандартном порту 443 и быстро возвращать ответ 200. Поэтому до финальной проверки понадобятся домен, VPS, Nginx и сертификат.

1. Создаём бота и получаем токен

  1. Откройте платформу MAX для партнёров.
  2. Перейдите в раздел чат‑ботов и создайте нового.
  3. Заполните имя, описание и изображение.
  4. В расширенных настройках откройте настройку бота и скопируйте токен.

Не публикуйте токен и не отправляйте его в чат. API принимает его в заголовке Authorization.

2. Готовим Python‑проект

mkdir -p ~/max-ai-bot && cd ~/max-ai-bot
python3 -m venv .venv
source .venv/bin/activate
pip install fastapi uvicorn httpx python-dotenv openai
nano .env
MAX_TOKEN=токен_бота
MAX_WEBHOOK_SECRET=придумайте_длинную_строку
AI_API_KEY=ключ_ai_провайдера

Секрет webhook — это отдельная строка от 5 символов. MAX будет присылать её в заголовке, а наше приложение — сравнивать.

3. Создаём обработчик

nano app.py
import os
from fastapi import FastAPI, Header, HTTPException, Request
from dotenv import load_dotenv

load_dotenv()
app = FastAPI()
WEBHOOK_SECRET = os.environ["MAX_WEBHOOK_SECRET"]

@app.get("/health")
async def health():
    return {"status": "ok"}

@app.post("/webhook")
async def webhook(
    request: Request,
    x_max_bot_api_secret: str | None = Header(default=None),
):
    if x_max_bot_api_secret != WEBHOOK_SECRET:
        raise HTTPException(status_code=403)

    update = await request.json()
    print(update) # временно изучаем структуру события
    return {"ok": True}

Сначала сознательно только печатаем событие. Так вы увидите фактическую структуру Update своего типа события и не будете угадывать названия полей.

4. Проверяем локально

uvicorn app:app --host 127.0.0.1 --port 8000

В другом SSH‑окне:

curl http://127.0.0.1:8000/health

Ожидаемый ответ — {"status":"ok"}. Порт 8000 наружу не открываем.

5. Подключаем домен и HTTPS

Настройте Nginx по отдельной инструкции RateHost. Внешний адрес должен выглядеть как https://bot.example.ru/webhook. Самоподписанный сертификат не подойдёт.

6. Регистрируем webhook

curl -X POST "https://platform-api2.max.ru/subscriptions" \
  -H "Authorization: ВАШ_MAX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://bot.example.ru/webhook",
    "update_types": ["message_created", "bot_started"],
    "secret": "ВАШ_WEBHOOK_SECRET"
  }'

После успешной подписки напишите боту. Посмотрите событие в терминале и сопоставьте поля с объектом Update в официальной документации MAX.

7. Добавляем AI‑ответ

Логика состоит из трёх действий: извлечь текст и идентификатор чата из события, отправить текст модели, затем вызвать официальный метод POST /messages с заголовком авторизации. Делайте это после того, как увидели реальный Update: структура платформы меняется, а догадки здесь рождают трудноуловимые ошибки.

Тяжёлую обработку лучше вынести в очередь задач, а webhook вернуть 200 как можно быстрее. MAX повторяет неуспешные доставки и может отключить подписку после продолжительной недоступности.

Типовые ошибки

  • 401 — неверный или отозванный токен;
  • 403 от вашего сервера — не совпал webhook secret;
  • события не приходят — проверьте HTTPS, порт 443 и активную подписку;
  • дубли ответов — обрабатывайте идентификатор события только один раз;
  • долгий ответ — верните 200, а AI‑запрос выполняйте фоновой задачей.
API MAX меняется. Перед продакшен‑запуском всегда сверяйте домен API, формат Update и тело отправки сообщения с официальной документацией.

Что дальше

Закрепим приложение на сервере и настроим автоматический запуск: деплой бота на VPS →