Files
MAX/docs/max-webhook.md

145 lines
7.8 KiB
Markdown
Raw Normal View History

# Как активировать Webhook для бота MAX
## 1. В n8n: воркфлоу с Webhook
1. Открой n8n (https://n8n.clientright.pro).
2. Создай новый воркфлоу или открой существующий для MAX.
3. Добавь ноду **Webhook** (Trigger → Webhook).
4. Настрой Webhook:
- **HTTP Method:** POST
- **Path:** должен совпадать с путём из URL в `.env`. Сейчас в `.env` указано:
- `N8N_MAX_WORKFLOW=https://n8n.clientright.pro/webhook/sprf_max`
- значит в ноде Webhook задай **Path** = `sprf_max` (без `/webhook/`).
- **Authentication:** Optional (проверку секрета можно сделать следующей нодой: сравнить заголовок `X-Max-Bot-Api-Secret` с переменной `MAX_WEBHOOK_SECRET`).
5. Включи воркфлоу (Production mode), чтобы URL был доступен по HTTPS.
Итог: запросы на `https://n8n.clientright.pro/webhook/sprf_max` будут попадать в этот воркфлоу.
## 2. Регистрация URL в MAX
Из каталога проекта выполни:
```bash
python3 register_max_webhook.py
```
Скрипт читает из `.env`:
- `MAX_BOT_TOKEN` — токен бота
- `N8N_MAX_WORKFLOW` — полный URL webhook (HTTPS)
- `MAX_WEBHOOK_SECRET` — секрет (опционально; если задан, MAX будет присылать его в заголовке `X-Max-Bot-Api-Secret`)
После успешного запуска MAX начнёт отправлять события (новые сообщения, нажатия кнопок, старт бота) на этот URL.
## 3. Нормализация входящего (Code node под MAX)
Чтобы не обрабатывать сырой Update, а получать один и тот же формат, что и для Telegram (для общего воркфлоу), используй Code node с содержимым из файла **`n8n-code-node-max-normalize.js`** в корне проекта. Он отдаёт один объект с полями:
- `max_id` — id пользователя MAX (sender)
- `max_chat_id` — id чата/диалога (для лички может совпадать с user_id)
- `answer_text` — текст сообщения, подпись к медиа или данные callback
- `answer_type``text` | `command` | `callback` | `voice` | `audio` | `video` | `file` | `photo`
- `channel``'max'`
- `reply_to_*` — если было ответ/пересланное (из `message.link`)
- `callback_id` — только при `answer_type === 'callback'` (для POST /answers)
- `attachment_token` / `file_id` — при медиа-вложениях
- `raw_update` — исходное тело Webhook
Групповые чаты и каналы отфильтровываются (возвращается пустой массив).
## 4. Отправка ответа пользователю (пушим в MAX)
Чтобы бот написал пользователю, вызывай **MAX Bot API**: отправка сообщения — метод **POST /messages**.
### Параметры
- **URL:** `https://platform-api.max.ru/messages?user_id={user_id}` или `?chat_id={chat_id}`
В личке можно использовать либо `user_id` (id отправителя), либо `chat_id` (id диалога). Из нашей нормализации: `max_id` — это user_id, `max_chat_id` — chat_id; для ответа подойдёт любой из них в query.
- **Метод:** POST
- **Заголовки:**
- `Authorization: <MAX_BOT_TOKEN>` — токен бота (из .env или из credentials в n8n)
- `Content-Type: application/json`
- **Тело (JSON):** объект **NewMessageBody**:
- `text` (string) — текст до 4000 символов, обязателен если нет вложений
- `format` (опц.) — `"markdown"` или `"html"` для форматирования
- `attachments` (опц.) — массив вложений (например inline_keyboard с кнопками)
- `notify` (опц., по умолч. true) — уведомлять ли пользователя
Пример тела:
```json
{
"text": "Привет! Ваше сообщение получено.",
"format": "markdown"
}
```
### В n8n (HTTP Request node)
1. Добавь ноду **HTTP Request** после логики (после Code или ветки, где есть нормализованный объект с `max_id`/`max_chat_id`).
2. Настрой:
- **Method:** POST
- **URL:** `https://platform-api.max.ru/messages?user_id={{ $json.max_id }}`
(или `?chat_id={{ $json.max_chat_id }}`оба варианта для лички рабочие)
- **Authentication:** Generic Credential Type → **Header Auth**
- Name: `Authorization`
- Value: твой `MAX_BOT_TOKEN` (создай в n8n Credentials или подставь через переменную окружения)
- **Body Content Type:** JSON
- **Specify Body:** Using JSON
- **JSON Body:** например `{ "text": "{{ $json.answer_text }}", "format": "markdown" }` или свой текст/поля из предыдущих нод
Токен бота лучше хранить в n8n Credentials (тип Header Auth или просто в переменной workflow/environment), а не в коде.
### Ответ на нажатие кнопки (callback)
Если пользователь нажал кнопку, приходит `message_callback` и в нормализованном объекте есть **`callback_id`**. Чтобы обновить сообщение с кнопкой или показать уведомление:
- **URL:** `https://platform-api.max.ru/answers?callback_id={{ $json.callback_id }}`
- **Method:** POST
- **Headers:** те же (`Authorization`, `Content-Type: application/json`)
- **Body (JSON):**
- `message` (опц.) — объект NewMessageBody (обновить сообщение)
- `notification` (опц.) — строка, одноразовое уведомление пользователю
Подробнее: `docs/max-api/02-methods.md`.
## 5. Проверка
Напиши боту в мессенджере MAX — в n8n во входящих данных Webhook должен появиться объект с полями `update_type`, `message` и т.д.
## Проверка: зарегистрирован ли Webhook
Выполни в каталоге проекта:
```bash
python3 -c "
import os, json, urllib.request
from pathlib import Path
for line in Path('.env').read_text().splitlines():
s = line.strip()
if s and not s.startswith('#') and '=' in s:
k, v = s.split('=', 1)
os.environ[k.strip()] = v.strip()
r = urllib.request.urlopen(urllib.request.Request(
os.environ.get('MAX_API_BASE','https://platform-api.max.ru').rstrip('/') + '/subscriptions',
headers={'Authorization': os.environ['MAX_BOT_TOKEN']}, method='GET'))
print(r.read().decode())
"
```
В ответе должен быть твой URL в списке `subscriptions`. Если список пустой — заново запусти `python3 register_max_webhook.py`.
---
## Отписка от Webhook
Чтобы отключить доставку на этот URL, вызови в MAX API:
```bash
curl -X DELETE "https://platform-api.max.ru/subscriptions" \
-H "Authorization: ВАШ_MAX_BOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url": "https://n8n.clientright.pro/webhook/sprf_max"}'
```
Точный формат отписки см. в документации MAX (DELETE /subscriptions).