Как отправлять сообщения через MAX Bot API без лишней боли
Пошаговый разбор отправки сообщений через MAX Bot API: авторизация, тексты, кнопки, файлы, callback и обработка ошибок.
Что нужно до отправки
Чтобы отправить первое сообщение через MAX Bot API, не нужно поднимать полпродукта. Но и магии тут нет: сначала должен быть создан и одобрен бот, у вас должен быть токен, а у сценария должен появиться понятный адресат, то есть chat_id.
- Создайте бота и получите токен в официальной платформе MAX для разработчиков.
- Определите, откуда у вас появится
chat_id: из webhook, через deep link или после первого диалога. - Договоритесь внутри команды, что в примерах и SDK вы используете только домен
platform-api.max.ru.
Если сейчас вы только разбираетесь с базой Bot API, начните с общего обзора MAX Bot API. Если уже понятно, что нужен не бот, а личный номер и более прямой self-serve сценарий, тогда полезнее посмотреть MAX через Relaya.
Для Relaya-пути не обязательно писать клиент вручную. Есть готовые quickstart-материалы по Node.js SDK, Python SDK и PHP SDK.
Текстовое сообщение
В официальной документации для отправки сообщения используется POST /messages и заголовокAuthorization: Bearer .... Самое удобное в этом методе то, что стартовый пример реально короткий.
const response = await fetch(
"https://platform-api.max.ru/messages?chat_id=1234567890",
{
method: "POST",
headers: {
Authorization: "Bearer YOUR_MAX_BOT_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({
text: "Привет! Это тестовое сообщение из MAX Bot API.",
}),
}
);
const result = await response.json();Документация MAX указывает лимит до 4000 символов на текст. Этого хватает для большинства сервисных сценариев. Если сообщение длиннее, обычно лучше не упираться в предел, а разделить его на несколько коротких сообщений с понятной структурой.
Если этот raw-пример вам нужен только для первого запуска продукта, а не для изучения Bot API как такового, быстрее стартовать через SDK Relaya и потом уже спускаться на HTTP-уровень только там, где это действительно оправдано.
Кнопки и callback
Кнопки в MAX Bot API годятся не только для красивого интерфейса. Они убирают лишний ввод и делают первый сценарий понятнее: подтвердить заказ, открыть ссылку, передать контакт, запустить mini app.
Официальная документация подтверждает довольно щедрые лимиты: до 210 кнопок в клавиатуре, не более 30 рядов и обычно не более 7 кнопок в ряду. Но в реальном продукте так делать почти никогда не нужно. Для первого сценария лучше держаться в пределах 2-4 кнопок.
await fetch(
"https://platform-api.max.ru/messages?chat_id=1234567890",
{
method: "POST",
headers: {
Authorization: "Bearer YOUR_MAX_BOT_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({
text: "Что хотите сделать дальше?",
inline_keyboard: [
[
{ type: "callback", text: "Подтвердить", payload: "confirm" },
{ type: "callback", text: "Отменить", payload: "cancel" }
],
[
{ type: "link", text: "Открыть заказ", url: "https://example.com/orders/1001" }
]
],
}),
}
);После нажатия callback-кнопки MAX присылает событие, а ваш сервер может ответить через POST /answers. Подробно этот контур разобран в статье про webhook и события MAX.
Файлы и медиа
Для файлов важно помнить главное: сначала файл загружается через POST /uploads, а уже потом используется в сообщении. В документации MAX указан подтверждённый лимит загрузки до 4 ГБ, что намного полезнее старых статей с придуманными 50 или 100 МБ.
const formData = new FormData();
formData.append("file", selectedFile);
const uploadResponse = await fetch("https://platform-api.max.ru/uploads", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_MAX_BOT_TOKEN",
},
body: formData,
});
const uploadResult = await uploadResponse.json();
await fetch("https://platform-api.max.ru/messages?chat_id=1234567890", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_MAX_BOT_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({
text: "Отправляю документ",
attachments: [
{
type: "file",
payload: {
token: uploadResult.token,
},
},
],
}),
});Если у вас в продукте много файлов, отдельно посмотрите материал про файлы и медиа в MAX Bot API. Там без лишней теории разобрана именно схема загрузки и отправки.
Ошибки и повторы
На старте полезно различать два типа проблем. Первый тип это ошибки запроса: невалидные поля, неправильный токен, отсутствие прав. Второй это перегрузка или временная проблема канала, когда лучше повторить запрос позже.
| Ситуация | Что делать |
|---|---|
| 400 / 401 / 403 | Исправлять запрос, токен или права. Автоматический retry тут только мешает. |
| 429 | Сбавить темп, поставить отправку в очередь, повторять с backoff. |
| 5xx или сетевой сбой | Повторять аккуратно и только с idempotency-ключом на своей стороне. |
async function sendWithBackoff(sendFn, attempt = 0) {
try {
return await sendFn();
} catch (error) {
if (![429, 500, 502, 503, 504].includes(error.status)) {
throw error;
}
const delayMs = Math.min(1000 * 2 ** attempt, 30000);
await new Promise((resolve) => setTimeout(resolve, delayMs));
return sendWithBackoff(sendFn, attempt + 1);
}
}Если ваш главный KPI это first_message_sent, фиксируйте его после успешного ответа канала или после статуса отправки, а не в момент постановки сообщения в очередь.
Что важно в продакшене
Чтобы интеграция не развалилась после первого клиента, достаточно держать в голове несколько правил:
- Не храните токен бота в коде или фронтенде. Только сервер и секретное хранилище.
- Начинайте с понятного RPS-ограничения ниже официального потолка и поднимайте его по данным.
- Не делайте тяжёлую бизнес-логику прямо внутри webhook handler.
- Все отправки, которые важны для денег или SLA, лучше вести через очередь и с idempotency.
Если хотите идти дальше, логичная следующая пара материалов это разбор лимитов и что делать с 429 в MAX Bot API.
Удобный старт в MAX Bot API это не “изучить всё”, а научиться стабильно делать три вещи: отправить текст, принять событие и безопасно пережить ошибку без дублей.
Создайте бесплатный MAX-профиль
Если хочется не просто читать, а сразу проверить сценарий руками: подключите MAX, отправьте себе тестовое сообщение и уже потом решайте, нужны ли другие каналы.