- 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>
7.8 KiB
Как активировать Webhook для бота MAX
1. В n8n: воркфлоу с Webhook
- Открой n8n (https://n8n.clientright.pro).
- Создай новый воркфлоу или открой существующий для MAX.
- Добавь ноду Webhook (Trigger → Webhook).
- Настрой 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).
- Включи воркфлоу (Production mode), чтобы URL был доступен по HTTPS.
Итог: запросы на https://n8n.clientright.pro/webhook/sprf_max будут попадать в этот воркфлоу.
2. Регистрация URL в MAX
Из каталога проекта выполни:
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— текст сообщения, подпись к медиа или данные callbackanswer_type—text|command|callback|voice|audio|video|file|photochannel—'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) — уведомлять ли пользователя
Пример тела:
{
"text": "Привет! Ваше сообщение получено.",
"format": "markdown"
}
В n8n (HTTP Request node)
- Добавь ноду HTTP Request после логики (после Code или ветки, где есть нормализованный объект с
max_id/max_chat_id). - Настрой:
- 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 или подставь через переменную окружения)
- Name:
- 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
Выполни в каталоге проекта:
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:
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).