# Как активировать 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: ` — токен бота (из .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).