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

194 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Форматы текста и кнопки (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:
```json
{
"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** символов.
### Структура
```json
{
"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** | Открывает мини-приложение. | уточнять в [доках](https://dev.max.ru/docs-api) |
### Пример: кнопка «Поделиться контактом»
У кнопки тип **request_contact**, поле **text** — подпись (например «📱 Отправить номер телефона»). В одном ряду с такими кнопками MAX разрешает до 3 кнопок.
```json
{
"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-кнопка
```json
{
"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 в одном сообщении
```json
{
"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** ноды можно задать статичное тело или собрать через выражение. Пример статичного тела с кнопками:
```json
{
"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`).