Important
Для распознавания голосовых настройте Webhook.
При Long Polling (GET /updates) нативные голосовые, записанные микрофоном в MAX, могут приходить как пустой message_created: без message, аудиофайла и идентификатора чата. Плагину нечего передать на распознавание. Обсуждение ограничения и перехода на вебхуки.
Укажите channels.max.webhookUrl — публичный HTTPS-адрес на порту 443 с доверенным сертификатом — и channels.max.webhookSecret, затем перезапустите Gateway. Для расшифровки также нужен настроенный движок распознавания OpenClaw (tools.media.audio), например локальный Whisper. Сам вебхук обеспечивает доставку аудио.
Проверено 9 сентября 2026 года: голосовое из приложения MAX дошло через вебхук, Whisper распознал речь, бот ответил. В плагине 0.6.2 также исправлено дублирование черновика и готового ответа при streamMode: "partial"; повторная проверка в MAX подтвердила исправление.
Канал-плагин для подключения AI-ассистента OpenClaw к мессенджеру MAX (max.ru Bot API).
English:
openclaw-max-plusconnects OpenClaw to MAX using the Bot API. Supports text, media, inline buttons, response streaming, polling, webhooks, multiple accounts, and sender-based agent routing. Requires OpenClaw 2026.9.3+, Node.js 24.16+ on the 24.x branch or 26.1+. Full setup guide below is in Russian.
Плагин позволяет общаться с OpenClaw-ботом через мессенджер MAX — так же, как через Telegram. Поддерживает:
- Приём и отправку текстовых сообщений (markdown)
- Вложения: фото, видео, файлы, стикеры, контакт, локация (в т.ч. inline-base64 — напр. сгенерированные картинки)
- Длинные подписи к медиа (>4000 — остаток уходит follow-up-сообщениями)
- Inline-кнопки:
callback(+цвет intent),link,request_contact,request_geo_location,message,clipboard,open_app; выбор модели - Reply, forward (приём с атрибуцией автора/канала), edit, delete
- Pin/unpin сообщений (admin-only, группы/каналы)
- Стриминг ответа (
streamMode: partial / block), typing-индикатор - Long polling и Webhook (с валидацией secret/url)
- Мультиаккаунт, DM-security, pairing, групповые политики
Реакции и опросы MAX Bot API не поддерживает (платформенное ограничение).
openclaw-max-plus/
├── openclaw.plugin.json # Манифест плагина
├── package.json
├── index.ts # Точка входа плагина (register → channel)
├── tsconfig.json
├── README.md
├── src/
│ ├── types.ts # TypeScript-типы MAX Bot API
│ ├── api.ts # HTTP-клиент MAX API (send/edit/delete/upload/actions)
│ ├── monitor.ts # Long polling + webhook (приём обновлений, dispatch)
│ ├── webhook.ts # Обработчик webhook-запросов
│ ├── send.ts # Высокоуровневые send-хелперы (текст/медиа/edit)
│ ├── channel.ts # OpenClaw channel adapter
│ ├── config-schema.ts # Zod-схема конфига канала
│ ├── accounts.ts # Резолвинг аккаунтов из конфига
│ ├── runtime.ts # Доступ к OpenClaw runtime
│ ├── actions.ts # Действия/команды
│ ├── model-buttons.ts # Кнопки выбора модели
│ ├── onboarding.ts # Онбординг/настройка аккаунта
│ ├── format.ts # Форматирование текста
│ └── sticker-cache.ts # Кэш стикеров
└── scripts/
├── test-api.mjs # Проверка токена и API (GET /me + GET /updates)
└── test-send.mjs # Тест send + edit + delete
Пошаговый runbook (выполнять по порядку, проверяя результат каждого шага).
0. Предусловия
- OpenClaw 2026.9.3 или новее; версия 0.6.1 проверена с SDK 2026.9.3.
- Node.js 24.16+ (ветка 24) или 26.1+, согласно требованиям OpenClaw 2026.9.3. Для авто-доверия CA Минцифры используется
tls.setDefaultCACertificates. Проверка:node -e "const t=require('node:tls');console.log(typeof t.setDefaultCACertificates)"→ должно бытьfunction. - Установлен
openclaw(CLI/gateway). Проверка:openclaw --version. - Есть токен бота MAX (см. «Установка → Создать бота в MAX» ниже). Никогда не печатать токен в логи/коммиты.
1. Собрать плагин (entry — dist/index.js; build кладёт и dist/certs/ с CA):
cd /путь/к/openclaw-max-plus
npm install
npm run typecheck && npm run lint && npm test # должно быть зелёным
npm run build2. Подключить плагин к OpenClaw. Способ А — через CLI:
openclaw plugins install --link /путь/к/openclaw-max-plus # симлинк (live-разработка)Способ Б — прописать путь в ~/.openclaw/openclaw.json (gateway грузит из рабочей папки):
3. Настроить канал в ~/.openclaw/openclaw.json (минимум — токен + кто может писать):
{ "channels": { "max": {
"enabled": true,
"botToken": "ТОКЕН_БОТА", // или "tokenFile": "/path/to/token", или env MAX_BOT_TOKEN
"dmPolicy": "allowlist", // pairing | allowlist | open
"allowFrom": ["ВАШ_USER_ID"], // см. шаг 6, как узнать user_id
"streamMode": "partial"
}}}Держать
src/config-schema.ts↔openclaw.plugin.jsonв синхроне при добавлении полей.
Для разных агентов в личных диалогах задавайте bindings[].match.peer как
{ "kind": "direct", "id": "USER_ID" }. Начиная с 0.6.1 маршрут и ключ сессии
используют sender.user_id; ответы по-прежнему уходят в реальный recipient.chat_id.
После обновления старые сессии, названные по ID чата, остаются в истории; новый
входящий диалог получает ключ по ID пользователя. Для групп маршрут использует ID чата.
При нескольких агентах задайте также владельца канала: например,
{ "agentId": "main", "match": { "channel": "max", "accountId": "default" } }.
Привязка конкретного пользователя имеет приоритет над владельцем канала.
4. Индикатор «печатает…» — ОБЯЗАТЕЛЬНО задать глобально (иначе индикатор будет мигать и обрываться, в MAX одиночный typing_on живёт ~5–6с):
openclaw config set agents.defaults.typingIntervalSeconds 45. Перезапустить gateway — зависит от того, как он запущен:
- launchd-сервис (
launchctl list | grep openclawпоказываетai.openclaw.gateway):launchctl kickstart -k "gui/$(id -u)/ai.openclaw.gateway" - вручную: остановить и
openclaw gateway --port 18789(илиopenclaw gateway restart, если поддерживается).
После ЛЮБОЙ правки кода:
npm run build→ перезапуск gateway (плагин держится в памяти, на лету не подхватывается).
6. Проверить и найти свой user_id:
openclaw plugins inspect openclaw-max-plus --runtime # канал max зарегистрирован?
# Живой лог gateway (stdout). Путь зависит от запуска:
tail -f ~/Library/Logs/openclaw/gateway.log # macOS launchd
# Написать боту в MAX любой текст → в логе появится "Starting MAX provider (@bot)" и обработка;
# user_id отправителя виден в логах или: MAX_BOT_TOKEN=xxx node scripts/test-api.mjs (раздел updates)Подставить найденный user_id в allowFrom (шаг 3) и перезапустить gateway. Бот должен ответить.
7. Диагностика «бот не отвечает» (по приоритету):
getUpdates/TLS падает → проверь домен:curl -I -H "Authorization: ТОКЕН" https://platform-api2.max.ru/me(200/401 = TLS ок;TLS:20/UNABLE_TO_GET_ISSUER= нет CA → Node < 22.15 илиnpm run buildне клалcerts/→ обнови Node и пересобери плагин сcerts/).- Сообщение приходит, но ответа нет → смотри
~/.openclaw/agents/main/sessions/*.jsonl(последние записи): дошёл ли inbound, не упал лиtoolResultотправки (напр.POST /messages → 404= неверный chat_id;ENAMETOOLONG= inline-медиа; LLM-биллинг = квота). dmPolicy/allowFromблокируют отправителя → проверь user_id вallowFrom.
- Зайти на business.max.ru (нужно юрлицо/ИП)
- Создать профиль организации и пройти верификацию
- Раздел Чат-боты → Создать (название, лого 500x500, описание)
- Дождаться модерации (до 48ч по рабочим дням)
- После модерации: Чат-боты → Интеграция → Получить токен
cd openclaw-max-plus
npm install
npm run build # собирает dist/ (entry: dist/index.js)
# Подключить плагин к OpenClaw из локальной папки
openclaw plugins install ./. # или абсолютный путь к папке плагинаАльтернатива для разработки — указать путь к плагину прямо в конфиге
~/.openclaw/openclaw.json, тогда gateway грузит его из рабочей папки:
{
"plugins": {
"entries": { "openclaw-max-plus": { "enabled": true } },
"load": { "paths": ["/путь/к/openclaw-max-plus"] }
}
}Добавить секцию в ~/.openclaw/openclaw.json:
{
"channels": {
"max": {
"enabled": true,
// Токен бота из business.max.ru → Чат-боты → Интеграция
"botToken": "ваш_токен_бота",
// Политика личных сообщений (по умолчанию "pairing"):
// "pairing" — новый контакт проходит pairing-код
// "allowlist" — только user_id из allowFrom
// "open" — любой (требует allowFrom: ["*"])
"dmPolicy": "allowlist",
// Список user_id, которым разрешено писать боту
// Узнать свой user_id: написать боту и посмотреть в логах
"allowFrom": ["12345678"],
// Режим стриминга ответа: "off" | "partial" | "block"
"streamMode": "partial"
}
}
}openclaw gateway restartМожно проверить регистрацию канала:
openclaw plugins inspect openclaw-max-plus --runtime.
MAX гасит индикатор «печатает…» через несколько секунд, поэтому плагин
переотправляет его весь ход ответа через keepalive хоста. Частота
переотправки задаётся глобальным параметром agents.defaults.typingIntervalSeconds
(по умолчанию 6с). Одиночный typing_on в MAX живёт ~5–6с, поэтому значение по
умолчанию (6с) даёт разрывы. Обязательно выставьте 4 — иначе индикатор
будет мигать и обрываться:
openclaw config set agents.defaults.typingIntervalSeconds 4
openclaw gateway restartПараметр общий для всех каналов (затронет и Telegram — для него 4с тоже безопасно). Индикатор «печатает…» бота отображается в мобильном клиенте MAX; веб-версия его показывает ненадёжно — это особенность клиента MAX.
Начиная с версии 0.6.3, плагин регистрирует меню через
PATCH /me/commands.
Команды отображаются в MAX как подсказки при вводе / и отправляются боту
обычным текстом. Выполнение команд и проверка прав остаются на стороне OpenClaw.
Чтобы показывать встроенные команды OpenClaw, включите автоматическое меню:
{
"channels": {
"max": {
"commands": "auto"
}
}
}Плагин берёт список из реестра установленной версии OpenClaw. MAX принимает
не более 32 команд, поэтому /help, /commands, /new, /stop, /status,
/models, /model и другие основные команды идут первыми. Остальные команды
доступны через /commands и ручной ввод. Отдельные команды навыков в меню
автоматически не добавляются; для них есть /skill. Описания берутся из реестра
OpenClaw: русские при наличии перевода, иначе исходные.
При commands.native: false или commands.text: false в глобальной конфигурации
режим auto очищает меню.
Можно задать собственный список с русскими описаниями:
{
"channels": {
"max": {
"commands": [
{ "name": "status", "description": "Статус и лимиты подписки" },
{ "name": "new", "description": "Начать новую сессию" },
{ "name": "stop", "description": "Прервать текущую задачу" },
{ "name": "models", "description": "Выбрать модель" }
]
}
}
}name задаётся без / (1–64 символа), description — до 128 символов.
Ручной список полностью задаёт меню; он не создаёт новые обработчики команд.
commands: [] удаляет все команды из меню. Если поле отсутствует, плагин
не меняет меню, настроенное через MAX API или другой инструмент.
Для нескольких ботов можно задать channels.max.accounts.<id>.commands.
Настройка аккаунта имеет приоритет над общей; пустой массив также считается
явным переопределением и очищает меню только этого бота.
После изменения перезапустите Gateway. В логах появится
Registered N bot commands via PATCH /me/commands; список можно сверить через
GET /me. Ошибка регистрации меню записывается в лог и не останавливает канал.
| Поле | Тип | Описание |
|---|---|---|
enabled |
boolean | Включить канал |
botToken |
string | API-токен бота (или tokenFile — путь к файлу с токеном) |
dmPolicy |
string | pairing (по умолч.) / allowlist / open |
allowFrom |
string[] | Разрешённые user_id (для open — ["*"]) |
groupPolicy |
string | Политика групп, по умолч. allowlist |
groupAllowFrom |
string[] | Разрешённые user_id в группах |
groups |
object | Пер-групповые настройки (requireMention, allowFrom, tools, skills, …) |
streamMode |
string | off / partial / block |
webhookUrl |
string | URL webhook (если не используется long polling) |
webhookSecret |
string | Секрет для валидации webhook (рекомендуется в webhook-режиме) |
webhookPath |
string | Путь webhook-эндпоинта (по умолч. из webhookUrl или /max) |
responsePrefix |
string | Префикс к ответам бота |
mediaMaxMb |
number | Лимит размера медиа |
commands |
"auto" или object[] |
Встроенные команды OpenClaw либо ручное меню; [] очищает меню — см. «Команды бота» |
accounts |
object | Дополнительные аккаунты (мультиаккаунт) |
Полный список — в src/config-schema.ts.
- Найти бота в MAX по нику
- Нажать Старт или отправить любое сообщение
- Бот ответит, если ваш
user_idразрешён политикой (dmPolicy/allowFrom)
Написать боту, затем посмотреть в логах OpenClaw:
openclaw logs --follow
# В логах будет sender.user_id входящего сообщенияИли запустить тест-скрипт:
MAX_BOT_TOKEN=xxx node scripts/test-api.mjs
# В разделе updates будет виден ваш user_idМожно подключить несколько ботов MAX — например, рабочий и личный:
{
"channels": {
"max": {
// Аккаунт по умолчанию
"botToken": "токен_основного_бота",
"allowFrom": ["12345678"],
// Дополнительные аккаунты
"accounts": {
"zaya": {
"botToken": "токен_второго_бота",
"allowFrom": ["87654321"],
"dmPolicy": "open"
}
}
}
}
}- Node.js 20+ (встроенный fetch)
- TypeScript 6
npm install
npm run build # сборка dist/
npm run typecheck # tsc --noEmit
npm run lint # eslint (lint:fix — с автофиксом)
npm run format # prettier --write (format:check — проверка)
npm test # vitest (test:watch — watch-режим)Перед коммитом: npm run typecheck && npm run lint && npm test.
# Проверить бота: GET /me + GET /updates
MAX_BOT_TOKEN=xxx node scripts/test-api.mjs
# С отправкой тестового сообщения в чат
MAX_BOT_TOKEN=xxx node scripts/test-api.mjs <chat_id>MAX_BOT_TOKEN=xxx node scripts/test-send.mjs <chat_id> "Текст сообщения"| Метод | Endpoint | Описание |
|---|---|---|
| GET | /me |
Информация о боте (user_id, name, username) |
| PATCH | /me/commands |
Задать меню команд; commands: [] удаляет команды |
| GET | /updates |
Long polling (marker, timeout, types) |
| POST | /messages |
Отправить (?chat_id или ?user_id) |
| PUT | /messages |
Редактировать (?message_id) |
| DELETE | /messages |
Удалить (?message_id) |
| POST | /chats/{chatId}/actions |
Действия (typing_on, mark_seen, …) |
| POST | /answers |
Ответ на callback (?callback_id) |
| POST · GET · DELETE | /subscriptions |
Webhook: подписка / список / отписка |
| POST | /uploads |
Загрузка медиа |
- Авторизация: заголовок
Authorization: <token>(query-параметрaccess_tokenустарел). - Документация: dev.max.ru/docs-api
⚠️ GET /chats(список чатов) помечен устаревшим с июня 2026; одиночныйGET /chats/{chatId}работает.- Команды бота задаются через
PATCH /me/commands; тело{ "commands": [...] }, ответ{ "commands": [...] }, максимум 32 команды. - ✅ Домен: по умолчанию
platform-api2.max.ru(legacyplatform-api.max.ruотключается 19.07.2026). Этот домен подписан корневым CA Минцифры — плагин бандлит CA и авто-доверяет ему в рамках процесса (certs/,src/ca-trust.ts), без установки сертификата в систему. Требует Node ≥ 22.15. Откат/override:apiBaseUrlв конфиге канала или envMAX_API_BASE_URL.
См. LICENSE.
{ "plugins": { "entries": { "openclaw-max-plus": { "enabled": true } }, "load": { "paths": ["/путь/к/openclaw-max-plus"] } } }