Зачем эта инструкция
Если вы ищете как создать простого бота в мессенджере MAX с нуля — эта статья проведёт вас от регистрации в кабинете до первого ответа пользователю через MAX Bot API. Мы опираемся на официальную документацию MAX и даём пошаговый план для начинающих: токен, проверкаGET /me, простой цикл на Python с long polling, затем путь к вебхуку и HTTPS для постоянной работы.
Ключевые термины: чат-бот MAX — программа, которая общается с людьми в MAX; MAX Bot API — HTTP-интерфейс (https://platform-api.max.ru), через который бот отправляет и получает сообщения.
Что такое MAX Bot API простыми словами
MAX Bot API — это набор методов, к которым ваш сервер обращается обычными HTTPS-запросами (как к сайту): отправить текст, получить обновления, добавить кнопки. У каждого бота есть токен — секретный ключ; его передают в заголовкеAuthorization (передача токена в query-параметрах не поддерживается — см. документацию авторизации).
Типичный сценарий для бизнеса: запись на услугу, ответы на частые вопросы, уведомления, переход на сайт по кнопке. Для этого не обязательна сложная архитектура: начните с короткого сценария и одного языка программирования.
Что понадобится до кода
- Аккаунт и кабинет на business.max.ru — там создаётся бот и выдаётся токен (раздел вроде «Чат-боты» → «Интеграция» → «Получить токен» — названия шагов в интерфейсе могут обновляться).
- Компьютер с Python 3.10+ (удобно для примеров) или любой другой стек, умеющий в HTTP.
- Для постоянной работы в интернете — сервер с HTTPS (домен и сертификат от доверенного УЦ). Для первых экспериментов часто используют long polling (см. ниже) или туннель к локальной машине; для продакшена MAX рекомендует вебхук — см. события и подписки.
Шаг 1. Создайте бота в кабинете
- Войдите на business.max.ru/self и пройдите шаги регистрации организации / сервиса, которые требует интерфейс (верификация через провайдеров идентификации встречается на практике часто).
- Откройте раздел чат-ботов и выберите создание нового бота.
- Заполните имя, описание, загрузите аватар — это влияет на доверие пользователей и на модерацию.
- Отправьте бота на модерацию, если кнопка есть в интерфейсе. Сроки проверки зависят от нагрузки поддержки; закладывайте от нескольких часов до пары рабочих дней и следите за уведомлениями в кабинете.
- После одобрения откройте блок интеграции и скопируйте токен в менеджер паролей или в защищённое хранилище секретов на сервере.
Шаг 2. Проверьте токен запросом GET /me
Убедитесь, что ключ рабочий. В терминале:curl -s -X GET "https://platform-api.max.ru/me" \
-H "Authorization: ВАШ_ТОКЕН"user_id, имя, признак is_bot: true и т.д.) — см. метод GET /me. Если видите ошибку 401 — токен неверный или отозван.
Шаг 3. Long polling: расширенный пример с callback, 429 и защитой от дублей
Чтобы не настраивать домен и HTTPS в первый день, удобно получать события методомGET /updates (long polling). Для продакшена MAX рекомендует вебхук; long polling и вебхук нельзя использовать одновременно (справка «События»).
Справочник: update_type и где искать данные
Ниже — ориентир для чтения JSON; точные поля всегда сверяйте с объектом Update и при необходимости выведите print(update) один раз.
message_created— новое сообщение. Текст: обычноupdate["message"]["body"]["text"]. Чат:update["message"]["recipient"]["chat_id"]. Тип чата (если есть):update["message"]["recipient"].get("chat_type")— напримерdialog,chat,channel(названия зависят от версии API).message_callback— нажата inline-кнопка сtype: "callback". Идентификатор для POST /answers:update["callback"]["callback_id"](в документации: «идентификатор кнопки в полеcallback.callback_id»). Данные кнопки: чаще всегоupdate["callback"].get("payload")— сверьте с вашим фактическим JSON.bot_added— бота добавили в чат или канал. См. поля вродеchat_id,user,is_channelв описании Update.user_added— в чат или канал добавился пользователь (удобно для приветствий в группе).
chat_member_updated в официальном перечне Update может не быть — для сценария «бота добавили в группу» ориентируйтесь на bot_added.
Код: сообщения, кнопки, ответ на callback, retry при 429
Установка:pip install requests. Токен — в MAX_BOT_TOKEN.
import os
import time
import logging
from collections import deque
import requests
logging.basicConfig(level=logging.INFO)
log = logging.getLogger("max-bot")
API = "https://platform-api.max.ru"
TOKEN = os.environ["MAX_BOT_TOKEN"]
HEADERS = {"Authorization": TOKEN, "Content-Type": "application/json"}
# Простая защита от повторной обработки одного и того же update (long polling / ретраи)
_SEEN: deque = deque(maxlen=200)
def dedup_key(update: dict) -> tuple:
msg = update.get("message") or {}
body = msg.get("body") or {}
mid = body.get("mid")
cb = update.get("callback") or {}
return (
update.get("update_type"),
update.get("timestamp"),
mid,
cb.get("callback_id"),
)
def poll_updates(marker=None, timeout=30):
params = {"timeout": timeout, "limit": 100}
if marker is not None:
params["marker"] = marker
r = requests.get(f"{API}/updates", headers=HEADERS, params=params, timeout=timeout + 10)
r.raise_for_status()
return r.json()
def send_message_safe(chat_id: int, text: str, retries: int = 3) -> None:
"""POST /messages с обработкой 429 (Retry-After) и повтором."""
url = f"{API}/messages"
body = {"chat_id": chat_id, "text": text}
for attempt in range(retries):
resp = requests.post(url, headers=HEADERS, json=body, timeout=20)
if resp.status_code == 429:
wait = int(resp.headers.get("Retry-After", 5))
log.warning("429 messages, ждём %s с (попытка %s)", wait, attempt + 1)
time.sleep(wait)
continue
if not resp.ok:
log.error("messages: %s %s", resp.status_code, resp.text[:400])
else:
break
def answer_callback(callback_id: str, notification: str = "Готово") -> None:
"""Снимает «часики» с кнопки — см. POST /answers."""
if not callback_id:
return
r = requests.post(
f"{API}/answers",
headers=HEADERS,
params={"callback_id": callback_id},
json={"notification": notification},
timeout=15,
)
if not r.ok:
log.error("answers: %s %s", r.status_code, r.text[:300])
def handle_update(update: dict) -> None:
key = dedup_key(update)
if key in _SEEN:
return
_SEEN.append(key)
ut = update.get("update_type")
if ut == "message_created":
msg = update.get("message") or {}
recipient = msg.get("recipient") or {}
chat_id = recipient.get("chat_id")
body = msg.get("body") or {}
text = (body.get("text") or "").strip()
if chat_id is None:
return
if text.startswith("/start"):
parts = text.split(maxsplit=1)
payload = parts[1] if len(parts) > 1 else ""
if payload:
send_message_safe(int(chat_id), f"Старт с параметром: {payload}")
else:
send_message_safe(int(chat_id), "Привет! Напишите /help.")
elif text == "/help":
send_message_safe(int(chat_id), "Доступно:\n/start [код]\n/help")
else:
send_message_safe(int(chat_id), f"Вы написали: {text}")
elif ut == "message_callback":
cb = update.get("callback") or {}
callback_id = cb.get("callback_id")
payload = cb.get("payload", "")
msg = cb.get("message") or {}
recipient = msg.get("recipient") or {}
chat_id = recipient.get("chat_id")
answer_callback(callback_id, "Принято")
if chat_id is not None:
send_message_safe(int(chat_id), f"Нажата кнопка, payload: {payload}")
elif ut == "bot_added":
log.info("Бот добавлен в чат: %s", update.get("chat_id"))
def main():
marker = None
log.info("Бот запущен (long polling). Остановка: Ctrl+C")
while True:
try:
data = poll_updates(marker)
for u in data.get("updates") or []:
handle_update(u)
if data.get("marker") is not None:
marker = data["marker"]
except requests.RequestException as e:
log.warning("Сеть/API: %s — пауза 5 с", e)
time.sleep(5)
if __name__ == "__main__":
main()mid входящего сообщения или иной стабильный ключ из документации; здесь — упрощённый deque по комбинации полей.
Шаг 4. Отправка сообщений: POST /messages
Исходящий текст —POST https://platform-api.max.ru/messages с JSON (chat_id, text до 4000 символов — POST /messages). Заголовок Authorization — токен бота.
Шаг 5. Inline-кнопки и ссылка под сообщением
Кнопки — вложениеinline_keyboard. Пример одной строки: callback + link (как в прошлой версии статьи). После нажатия callback обязательно вызывайте POST /answers с callback_id, иначе у пользователя долго крутятся «часики» на кнопке.
Шаг 6. Deep link: параметр после /start
Текст вmessage_created часто выглядит как /start promo_2026. Разбор:
if text.startswith("/start"):
parts = text.split(maxsplit=1)
promo = parts[1] if len(parts) > 1 else ""
# promo — условный «код» из рекламной ссылки; сохраните в БД или в состоянии FSMШаг 7. Группы и каналы: чек-лист для владельца чата
- Добавьте бота в группу или канал через интерфейс MAX.
- Выдайте права, достаточные для сценария: как минимум отправка сообщений; для чтения всех сообщений в группе (если платформа это разделяет) — соответствующее право; чтобы пользователи вызывали бота по
/start@username, нужен публичный username бота и понятные команды в описании. - В коде смотрите
recipient.chat_type(если поле приходит): различайте личку, группу и канал — логика ответов может отличаться. - Если бот «молчит» в группе: проверьте права, видимость сообщений (упоминание бота, команды), а также что вы подписаны на нужные
update_typesпри вебхуке.
Шаг 8. Вебхук в бою: проверка X-Max-Bot-Api-Secret
Для публичного URL любой может прислать POST. Задайтеsecret в POST /subscriptions и сверяйте заголовок X-Max-Bot-Api-Secret (лучше через hmac.compare_digest, чтобы не светить секрет в логах и не дать лишних подсказок по времени ответа).
import os
import hmac
from flask import Flask, request, abort, jsonify
app = Flask(__name__)
MY_SECRET = os.environ["MAX_WEBHOOK_SECRET"] # тот же, что в подписке
@app.route("/webhook", methods=["POST"])
def webhook():
got = request.headers.get("X-Max-Bot-Api-Secret", "")
if not MY_SECRET or not hmac.compare_digest(got, MY_SECRET):
abort(403)
update = request.get_json(silent=True) or {}
# handle_update(update) — ту же логику, что и для long polling
return jsonify({"ok": True}), 200Фишки для бизнес-бота (кратко)
- Напоминания и отложенные сообщения — планируйте задачи планировщиком (APScheduler, Celery beat, cron) и в срок вызывайте
POST /messages. - Клавиатура под полем ввода (reply): во многих API она отделена от
inline_keyboard. В MAX для кнопок под сообщением стандартно используютinline_keyboard; отдельный тип «обычной» клавиатуры, если он доступен, ищите в актуальной схеме вложений в документации к POST /messages. - Многошаговые сценарии — храните шаг пользователя в Redis, SQLite или памяти процесса (для одного инстанса); это и есть простейшая FSM.
Быстрая диагностика
- 401 Unauthorized — неверный или отозванный токен; заголовок
Authorization, не query. - 400 Bad Request — проверьте JSON, типы (
chat_idчислом), обязательные поля метода. - 429 Too Many Requests — снизьте частоту запросов, читайте
Retry-After, введите очередь. - Вебхук не вызывается — валидный TLS, порт 443, совпадение
secret, ответ 200 до таймаута (POST /subscriptions). - В группе нет
message_created— права бота, тип чата, упоминание; сверьтесь с Update и логами.
Путь развития: от учебного бота к продакшену
- Заменить
printна логирование в файл или централизованный сбор логов. - Вынести состояние диалога (простая FSM) в Redis/SQLite.
- Перейти на вебхук (FastAPI + uvicorn или Flask за nginx) по гайду на Bothost.
- Подключить БД для заявок и аналитики.
- Добавить мониторинг (ошибки, 429, задержка ответа).
Ограничения и лимиты, о которых стоит помнить
- Частота запросов к
platform-api.max.ruограничена; при перегрузке — 429 (см.send_message_safeвыше). - Длина текста — до 4000 символов (POST /messages).
- Вебхук: повторные доставки — проектируйте идемпотентность (учёт
mid,callback_idи т.д.).
Типичные ошибки начинающих
- Токен в коде вместо переменных окружения.
- Нет разбора 429 и нет паузы — бот «забивает» API.
- После нажатия callback не вызывается
/answers— плохой UX. - Вебхук без проверки
X-Max-Bot-Api-Secret— риск поддельных POST. - Ожидание, что бот сам первым пишет незнакомому пользователю — в типичных сценариях первым пишет человек, по правилам платформы.
Размещение бота на сервере и на Bothost
Учебный скрипт можно запустить на VPS или на хостинге приложений. На Bothost для ботов MAX задают шаблон,MAX_TOKEN / MAX_BOT_TOKEN и WEBHOOK_URL для продакшена.
Частые вопросы (FAQ)
Сколько времени занимает модерация бота в MAX?
Сроки зависят от загрузки модерации и полноты данных. Ориентируйтесь от нескольких часов до нескольких рабочих дней; статус — в business.max.ru.Можно ли разрабатывать бота без публичного домена?
Для long polling публичный входящий адрес не обязателен. Для вебхука нужен HTTPS на 443 (POST /subscriptions).Чем MAX Bot API отличается от Telegram Bot API?
Схожи идеи, но отличаются базовый URL, поля JSON и правила платформы.Где описан вебхук?
POST /subscriptions, FAQ по событиям, наша статья: вебхук с примером.Как проверить токен?
GET /me.Полезные ссылки (официальные)
Если интерфейс кабинета или ответ API разошлись с текстом статьи — ориентируйтесь на официальные страницы MAX и поддержку платформы.
476 просмотров
0 лайков
0 комментариев
Комментарии (0)
Пока нет комментариев. Будьте первым!