Files
MAX/docs/max-api/04-formats-and-buttons.md
root 7cd3ccf21c MAX bot + n8n: webhook, нормализация, меню, доки, схемы БД
- register_max_webhook.py, fetch_schema.py
- n8n-code-node-max-normalize.js (max_id, callback из callback.user, contact из vcf_info)
- n8n-code-add-menu-buttons.js (меню с callback, request_contact, Главное меню)
- docs: max-webhook, max-curl-http-request, max-api (форматы, кнопки, контакт), clpr vs sprf
- README, SITUATION, схемы sprf_ и clpr_, .gitignore

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-16 09:23:51 +03:00

8.4 KiB
Raw Permalink Blame History

Форматы текста и кнопки (MAX Bot API)

Форматы текста (поле format в теле сообщения)

В NewMessageBody укажи "format": "markdown" или "format": "html". Тогда текст сообщения будет отформатирован.

Markdown

Как написать Результат
*курсив* или урсив_ курсив
**жирный** или __жирный__ жирный
~~зачёркнутый~~ зачёркнутый
++подчёркнутый++ подчёркнутый
`код` моноширинный (переводы строк внутри — как пробелы)
[текст ссылки](https://example.com) кликабельная ссылка
@упоминание "text": "[Имя Фамилия](max://user/user_id)", "format": "markdown" — полное имя из профиля MAX

HTML

Теги Результат
<i>, <em> курсив
<b>, <strong> жирный
<del>, <s> зачёркнутый
<ins>, <u> подчёркнутый
<pre>, <code> моноширинный
<a href="https://example.com">Текст</a> ссылка
@упоминание "text": "<a href=\"max://user/user_id\">Имя Фамилия</a>", "format": "html"

Пример тела с markdown:

{
  "text": "**Внимание!** Вы отправили *голосовое*. Обрабатываем.",
  "format": "markdown"
}

Кнопки (inline_keyboard)

Кнопки добавляются через attachments: один элемент с type: "inline_keyboard" и payload.buttons — массив рядов, каждый ряд — массив кнопок.

Ограничения:

  • до 210 кнопок всего;
  • до 30 рядов;
  • до 7 кнопок в ряду (для типов link, open_app, request_geo_location, request_contact — до 3 в ряду);
  • для кнопки типа link ссылка до 2048 символов.

Структура

{
  "text": "Текст сообщения над кнопками",
  "format": "markdown",
  "attachments": [
    {
      "type": "inline_keyboard",
      "payload": {
        "buttons": [
          [
            { "type": "callback", "text": "Надпись кнопки", "payload": "значение при нажатии" }
          ],
          [
            { "type": "link", "text": "Открыть сайт", "url": "https://example.com" }
          ]
        ]
      }
    }
  ]
}

buttons — массив рядов. Каждый ряд — массив кнопок. Одна кнопка — объект с полями в зависимости от типа.

Типы кнопок

type Описание Поля кнопки
callback При нажатии в Webhook приходит message_callback с callback_id и payload. Нужен для ответа через POST /answers. text, payload (строка или объект — то, что придёт в бот)
link Открывает ссылку в браузере. text, url (до 2048 символов)
message Отправляет боту текстовое сообщение (как будто пользователь написал это). text
request_contact Запрос контакта (номер телефона). Пользователь нажимает → клиент MAX предлагает отправить контакт → в Webhook приходит message_created с данными контакта (телефон и т.д.) в теле сообщения. text (подпись на кнопке)
request_geo_location Запрос геолокации. Пользователь нажимает → отправляет геолокацию → в Webhook приходит сообщение с координатами. text
open_app Открывает мини-приложение. уточнять в доках

Пример: кнопка «Поделиться контактом»

У кнопки тип request_contact, поле text — подпись (например «📱 Отправить номер телефона»). В одном ряду с такими кнопками MAX разрешает до 3 кнопок.

{
  "text": "Чтобы мы могли связаться, поделитесь номером телефона:",
  "format": "markdown",
  "attachments": [
    {
      "type": "inline_keyboard",
      "payload": {
        "buttons": [
          [
            { "type": "request_contact", "text": "📱 Отправить номер телефона" }
          ]
        ]
      }
    }
  ]
}

После нажатия пользователь подтверждает отправку контакта в клиенте MAX. В Webhook придёт message_created с вложением attachments[0].type === "contact". Структура:

  • attachments[0].payload.vcf_info — строка VCARD (например TEL;TYPE=cell:79262306381, FN:Имя Фамилия). Телефон достаётся из строки TEL...:номер.
  • attachments[0].payload.max_info — объект пользователя MAX: user_id, first_name, last_name, name, is_bot, last_activity_time.

В нормализаторе для такого сообщения: answer_type: 'contact', answer_text — извлечённый номер, contact_payload — весь payload, contact_name — из max_info.name.

Пример: одна callback-кнопка

{
  "text": "Выберите действие:",
  "format": "markdown",
  "attachments": [
    {
      "type": "inline_keyboard",
      "payload": {
        "buttons": [
          [
            { "type": "callback", "text": "Подтвердить", "payload": "confirm" },
            { "type": "callback", "text": "Отмена", "payload": "cancel" }
          ]
        ]
      }
    }
  ]
}

При нажатии «Подтвердить» в Webhook придёт update_type: "message_callback", в нормализованном объекте будет answer_text: "confirm" и callback_id для POST /answers (уведомление или обновление сообщения).

Пример: кнопка-ссылка и callback в одном сообщении

{
  "text": "Официальный сайт и обратная связь:",
  "format": "markdown",
  "attachments": [
    {
      "type": "inline_keyboard",
      "payload": {
        "buttons": [
          [
            { "type": "link", "text": "Перейти на сайт", "url": "https://example.com" }
          ],
          [
            { "type": "callback", "text": "Написать в поддержку", "payload": "support" }
          ]
        ]
      }
    }
  ]
}

В n8n (HTTP Request — тело с кнопками)

В JSON Body ноды можно задать статичное тело или собрать через выражение. Пример статичного тела с кнопками:

{
  "text": "Выберите действие:",
  "format": "markdown",
  "attachments": [
    {
      "type": "inline_keyboard",
      "payload": {
        "buttons": [
          [
            { "type": "callback", "text": "Да", "payload": "yes" },
            { "type": "callback", "text": "Нет", "payload": "no" }
          ]
        ]
      }
    }
  ]
}

URL и заголовки — как раньше: POST https://platform-api.max.ru/messages?user_id={{ $json.max_id }}, Authorization: <token>, Content-Type: application/json.

После нажатия callback-кнопки пользователем обрабатывай событие в воркфлоу (по answer_type === 'callback' и answer_text / callback_id) и при необходимости вызывай POST /answers?callback_id=... для уведомления или обновления сообщения (см. 02-methods.md).