WhatsApp (Web-канал)
Статус: готов к продуктивному использованию через WhatsApp Web (Baileys). Шлюз владеет привязанными сессиями.
- Спаривание — Политика ЛС по умолчанию — спаривание для неизвестных отправителей.
- Устранение неполадок каналов — Кросс-канальная диагностика и инструкции по восстановлению.
- Конфигурация шлюза — Полные паттерны и примеры конфигурации каналов.
Быстрая настройка
Шаг 1: Настройте политику доступа WhatsApp
{
channels: {
whatsapp: {
dmPolicy: "pairing",
allowFrom: ["+15551234567"],
groupPolicy: "allowlist",
groupAllowFrom: ["+15551234567"],
},
},
}
Шаг 2: Привяжите WhatsApp (QR)
openclaw channels login --channel whatsapp
Для конкретного аккаунта:
openclaw channels login --channel whatsapp --account work
Шаг 3: Запустите шлюз
openclaw gateway
Шаг 4: Подтвердите первый запрос спаривания (при использовании режима спаривания)
openclaw pairing list whatsapp
openclaw pairing approve whatsapp <CODE>
Запросы спаривания истекают через 1 час. Максимум 3 ожидающих запроса на канал.
Примечание: OpenClaw рекомендует запускать WhatsApp на отдельном номере, когда это возможно. (Метаданные канала и процесс настройки оптимизированы для такой конфигурации, но использование личного номера тоже поддерживается.)
Паттерны развёртывания
Выделенный номер (рекомендуется)
Наиболее чистый режим работы:
- отдельная идентичность WhatsApp для OpenClaw
- более ясные списки доступа ЛС и границы маршрутизации
- меньше шансов на путаницу с самочатом
Минимальный паттерн политики:
```json5
{
channels: {
whatsapp: {
dmPolicy: "allowlist",
allowFrom: ["+15551234567"],
},
},
}
```
Запасной вариант с личным номером
Настройка поддерживает режим личного номера и записывает базовую конфигурацию для самочата:
- `dmPolicy: "allowlist"`
- `allowFrom` включает ваш личный номер
- `selfChatMode: true`
В runtime защита самочата привязана к привязанному номеру и `allowFrom`.
Область действия канала WhatsApp Web
Канал мессенджера реализован через WhatsApp Web (`Baileys`) в текущей архитектуре каналов OpenClaw.
Отдельного канала Twilio WhatsApp во встроенном реестре каналов нет.
Модель выполнения
- Шлюз владеет сокетом WhatsApp и циклом переподключения.
- Исходящая отправка требует активного слушателя WhatsApp для целевого аккаунта.
- Статусные и широковещательные чаты игнорируются (
@status,@broadcast). - Прямые чаты используют правила ЛС-сессий (
session.dmScope; по умолчаниюmainобъединяет ЛС в основную сессию агента). - Групповые сессии изолированы (
agent:<agentId>:whatsapp:group:<jid>).
Контроль доступа и активация
Политика ЛС
`channels.whatsapp.dmPolicy` управляет доступом к прямым чатам:
- `pairing` (по умолчанию)
- `allowlist`
- `open` (требуется `allowFrom` с `"*"`)
- `disabled`
`allowFrom` принимает номера в формате E.164 (нормализуются внутренне).
Переопределение для мульти-аккаунтов: `channels.whatsapp.accounts.<id>.dmPolicy` (и `allowFrom`) имеют приоритет над значениями по умолчанию на уровне канала для данного аккаунта.
Детали поведения в runtime:
- спаривания сохраняются в хранилище разрешений канала и объединяются с настроенным `allowFrom`
- если список доступа не настроен, привязанный собственный номер разрешён по умолчанию
- исходящие ЛС `fromMe` никогда не спариваются автоматически
Групповая политика + списки доступа
Доступ к группам имеет два уровня:
1. **Список доступа по членству в группе** (`channels.whatsapp.groups`)
- если `groups` не задан, все группы допускаются
- если `groups` задан, действует как список доступа групп (`"*"` допускается)
2. **Политика отправителей в группах** (`channels.whatsapp.groupPolicy` + `groupAllowFrom`)
- `open`: список доступа отправителей обходится
- `allowlist`: отправитель должен совпадать с `groupAllowFrom` (или `*`)
- `disabled`: блокировать все входящие от групп
Fallback списка доступа отправителей:
- если `groupAllowFrom` не задан, runtime использует fallback к `allowFrom` при наличии
- списки доступа отправителей проверяются до проверки активации по упоминанию/ответу
Примечание: если блок `channels.whatsapp` вообще отсутствует, runtime-fallback для групповой политики — `allowlist` (с предупреждением в логах), даже если задан `channels.defaults.groupPolicy`.
Упоминания + /activation
Ответы в группах требуют упоминания по умолчанию.
Обнаружение упоминания включает:
- явные упоминания WhatsApp с идентичностью бота
- настроенные regex-паттерны упоминания (`agents.list[].groupChat.mentionPatterns`, fallback `messages.groupChat.mentionPatterns`)
- неявное обнаружение ответа боту (отправитель ответа совпадает с идентичностью бота)
Примечание по безопасности:
- цитата/ответ удовлетворяет только гейтинг по упоминанию; это **не** даёт авторизацию отправителя
- при `groupPolicy: "allowlist"` неавторизованные отправители всё равно блокируются, даже если они отвечают на сообщение авторизованного пользователя
Команда активации на уровне сессии:
- `/activation mention`
- `/activation always`
`activation` обновляет состояние сессии (не глобальную конфигурацию). Ограничена для владельца.
Поведение самочата с личным номером
Когда привязанный собственный номер присутствует в allowFrom, активируются защиты самочата WhatsApp:
- пропуск подтверждений прочтения для поворотов самочата
- игнорирование автосрабатывания по mention-JID, которое иначе пингует вас самих
- если
messages.responsePrefixне задан, ответы в самочате по умолчанию используют[{identity.name}]или[openclaw]
Нормализация сообщений и контекст
Входящий конверт + контекст ответа
Входящие сообщения WhatsApp оборачиваются в общий входящий конверт.
Если существует цитированный ответ, контекст добавляется в следующей форме:
```text
[Replying to <sender> id:<stanzaId>]
<quoted body or media placeholder>
[/Replying]
```
Поля метаданных ответа также заполняются при наличии (`ReplyToId`, `ReplyToBody`, `ReplyToSender`, JID/E.164 отправителя).
Плейсхолдеры медиа, извлечение геолокации и контактов
Входящие сообщения только с медиа нормализуются с плейсхолдерами:
- `<media:image>`
- `<media:video>`
- `<media:audio>`
- `<media:document>`
- `<media:sticker>`
Данные геолокации и контактов нормализуются в текстовый контекст перед маршрутизацией.
Инъекция ожидающей групповой истории
Для групп необработанные сообщения могут буферизоваться и инъецироваться как контекст при активации бота.
- лимит по умолчанию: `50`
- конфиг: `channels.whatsapp.historyLimit`
- fallback: `messages.groupChat.historyLimit`
- `0` отключает
Маркеры инъекции:
- `[Chat messages since your last reply - for context]`
- `[Current message - respond to this]`
Подтверждения прочтения
Подтверждения прочтения включены по умолчанию для принятых входящих сообщений WhatsApp.
Глобальное отключение:
```json5
{
channels: {
whatsapp: {
sendReadReceipts: false,
},
},
}
```
Переопределение для аккаунта:
```json5
{
channels: {
whatsapp: {
accounts: {
work: {
sendReadReceipts: false,
},
},
},
},
}
```
Повороты самочата пропускают подтверждения прочтения, даже если они включены глобально.
Доставка, разбивка и медиа
Разбивка текста
- лимит чанка по умолчанию: `channels.whatsapp.textChunkLimit = 4000`
- `channels.whatsapp.chunkMode = "length" | "newline"`
- режим `newline` предпочитает границы абзацев (пустые строки), затем использует fallback к разбивке по длине
Исходящее поведение медиа
- поддерживаются изображения, видео, аудио (PTT-голосовая заметка) и документы
- `audio/ogg` переписывается на `audio/ogg; codecs=opus` для совместимости с голосовыми заметками
- воспроизведение анимированных GIF поддерживается через `gifPlayback: true` при отправке видео
- подписи применяются к первому медиа-элементу при отправке мульти-медийных ответов
- источник медиа: HTTP(S), `file://` или локальные пути
Ограничения размера медиа и поведение при ошибке
- лимит входящего медиа: `channels.whatsapp.mediaMaxMb` (по умолчанию `50`)
- лимит исходящего медиа: `channels.whatsapp.mediaMaxMb` (по умолчанию `50`)
- переопределение для аккаунтов: `channels.whatsapp.accounts.<accountId>.mediaMaxMb`
- изображения автоматически оптимизируются (перебор размера/качества) для соответствия лимитам
- при ошибке отправки медиа, fallback первого элемента отправляет текстовое предупреждение вместо беззвучного отбрасывания ответа
Реакции подтверждения
WhatsApp поддерживает мгновенные реакции подтверждения при получении входящего сообщения через channels.whatsapp.ackReaction.
{
channels: {
whatsapp: {
ackReaction: {
emoji: "👀",
direct: true,
group: "mentions", // always | mentions | never
},
},
},
}
Заметки о поведении:
- отправляется сразу после принятия входящего (до ответа)
- ошибки логируются, но не блокируют нормальную доставку ответа
- групповой режим
mentionsреагирует на повороты с упоминанием; групповая активацияalwaysобходит эту проверку - WhatsApp использует
channels.whatsapp.ackReaction(устаревшийmessages.ackReactionздесь не используется)
Мульти-аккаунт и учётные данные
Выбор аккаунта и значения по умолчанию
- идентификаторы аккаунтов берутся из `channels.whatsapp.accounts`
- выбор аккаунта по умолчанию: `default`, если присутствует, иначе первый настроенный ID аккаунта (отсортировано)
- идентификаторы аккаунтов нормализуются внутренне для поиска
Пути учётных данных и совместимость с устаревшими версиями
- текущий путь аутентификации: `~/.openclaw/credentials/whatsapp/<accountId>/creds.json`
- файл резервной копии: `creds.json.bak`
- устаревшая аутентификация по умолчанию в `~/.openclaw/credentials/` по-прежнему распознаётся/мигрируется для потоков аккаунта по умолчанию
Поведение выхода
`openclaw channels logout --channel whatsapp [--account <id>]` очищает состояние аутентификации WhatsApp для данного аккаунта.
В устаревших каталогах аутентификации `oauth.json` сохраняется, а файлы аутентификации Baileys удаляются.
Инструменты, действия и запись конфигурации
- Инструменты агента включают действие реакции WhatsApp (
react). - Шлюзы действий:
channels.whatsapp.actions.reactionschannels.whatsapp.actions.polls
- Запись конфигурации из канала включена по умолчанию (отключение через
channels.whatsapp.configWrites=false).
Устранение неполадок
Не привязан (требуется QR)
Симптом: статус канала сообщает, что не привязан.
Решение:
```bash
openclaw channels login --channel whatsapp
openclaw channels status
```
Привязан, но отключён / цикл переподключения
Симптом: привязанный аккаунт с повторяющимися отключениями или попытками переподключения.
Решение:
```bash
openclaw doctor
openclaw logs --follow
```
При необходимости повторно привяжите через `channels login`.
Нет активного слушателя при отправке
Исходящие отправки завершаются ошибкой, если нет активного слушателя шлюза для целевого аккаунта.
Убедитесь, что шлюз запущен и аккаунт привязан.
Групповые сообщения неожиданно игнорируются
Проверьте в следующем порядке:
- `groupPolicy`
- `groupAllowFrom` / `allowFrom`
- записи списка доступа `groups`
- гейтинг по упоминанию (`requireMention` + паттерны упоминания)
- дублирующиеся ключи в `openclaw.json` (JSON5): поздние записи переопределяют ранние, поэтому держите один `groupPolicy` на область видимости
Предупреждение о среде выполнения Bun
Среда выполнения шлюза WhatsApp должна использовать Node. Bun отмечен как несовместимый для стабильной работы шлюза WhatsApp/Telegram.
Указатели на справочник конфигурации
Основной справочник:
Ключевые поля WhatsApp:
- доступ:
dmPolicy,allowFrom,groupPolicy,groupAllowFrom,groups - доставка:
textChunkLimit,chunkMode,mediaMaxMb,sendReadReceipts,ackReaction - мульти-аккаунт:
accounts.<id>.enabled,accounts.<id>.authDir, переопределения на уровне аккаунта - эксплуатация:
configWrites,debounceMs,web.enabled,web.heartbeatSeconds,web.reconnect.* - поведение сессий:
session.dmScope,historyLimit,dmHistoryLimit,dms.<id>.historyLimit