Установка (по требованию)
- Онбординг (
openclaw onboard) иopenclaw channels add --channel whatsappпредлагают установить WhatsApp Plugin при первом выборе. openclaw channels login --channel whatsappтакже предлагает поток установки, когда Plugin еще не установлен.- Dev-канал + git checkout: по умолчанию используется локальный путь Plugin.
- Stable/Beta: сначала устанавливает официальный Plugin
@openclaw/whatsappиз ClawHub, с npm как резервным вариантом. - Среда выполнения WhatsApp распространяется вне основного npm-пакета OpenClaw, чтобы специфичные для WhatsApp зависимости среды выполнения оставались во внешнем Plugin.
@openclaw/whatsapp) только когда нужен резервный вариант
через registry. Фиксируйте точную версию только когда нужна воспроизводимая установка.
Pairing
Channel troubleshooting
Gateway configuration
Быстрая настройка
Link WhatsApp (QR)
Шаблоны развертывания
Dedicated number (recommended)
Dedicated number (recommended)
- отдельная идентичность WhatsApp для OpenClaw
- более понятные DM allowlist и границы маршрутизации
- меньше вероятность путаницы с чатом с самим собой
Personal-number fallback
Personal-number fallback
dmPolicy: "allowlist"allowFromвключает ваш личный номерselfChatMode: true
allowFrom.WhatsApp Web-only channel scope
WhatsApp Web-only channel scope
Baileys) в текущей архитектуре каналов OpenClaw.В встроенном registry чат-каналов нет отдельного канала обмена сообщениями Twilio WhatsApp.Модель среды выполнения
- Gateway владеет сокетом WhatsApp и циклом переподключения.
- Watchdog переподключения использует активность транспорта WhatsApp Web, а не только объем входящих сообщений приложения, поэтому тихая сессия связанного устройства не перезапускается только потому, что никто недавно не отправлял сообщения. Более длинный лимит тишины приложения все равно принудительно выполняет переподключение, если транспортные frames продолжают поступать, но сообщения приложения не обрабатываются в течение окна watchdog; после временного переподключения для недавно активной сессии эта проверка тишины приложения использует обычный тайм-аут сообщений для первого окна восстановления.
- Тайминги сокета Baileys явно задаются в
web.whatsapp.*:keepAliveIntervalMsуправляет application ping WhatsApp Web,connectTimeoutMsуправляет тайм-аутом начального handshake, аdefaultQueryTimeoutMsуправляет ожиданиями запросов Baileys, а также локальными границами OpenClaw для исходящей отправки/presence и операций входящих read receipt. - Для исходящих отправок требуется активный слушатель WhatsApp для целевой учетной записи.
- Групповые отправки добавляют нативные метаданные упоминаний для токенов
@+<digits>и@<digits>в тексте и подписях к медиа, когда токен соответствует текущим метаданным участников WhatsApp, включая группы на базе LID. - Статусы и broadcast-чаты игнорируются (
@status,@broadcast). - Watchdog переподключения следует активности транспорта WhatsApp Web, а не только объему входящих сообщений приложения: тихие сессии связанного устройства остаются активными, пока транспортные frames продолжаются, но остановка транспорта принудительно вызывает переподключение задолго до более позднего пути удаленного отключения.
- Прямые чаты используют правила DM-сессий (
session.dmScope; значение по умолчаниюmainсворачивает DM в основную сессию агента). - Групповые сессии изолированы (
agent:<agentId>:whatsapp:group:<jid>). - WhatsApp Channels/Newsletters могут быть явными исходящими целями со своим нативным JID
@newsletter. Исходящие отправки newsletter используют метаданные сессии канала (agent:<agentId>:whatsapp:channel:<jid>), а не семантику DM-сессий. - Транспорт WhatsApp Web учитывает стандартные переменные окружения proxy на хосте Gateway (
HTTPS_PROXY,HTTP_PROXY,NO_PROXY/ варианты в нижнем регистре). Предпочитайте конфигурацию proxy на уровне хоста настройкам proxy, специфичным для канала WhatsApp. - Когда
messages.removeAckAfterReplyвключен, OpenClaw очищает ack-реакцию WhatsApp после доставки видимого ответа.
Запросы подтверждения
WhatsApp может отображать запросы подтверждения exec и Plugin с реакциями👍 / 👎. Доставка
управляется конфигурацией пересылки подтверждений верхнего уровня:
approvals.exec и approvals.plugin независимы. Включение WhatsApp как канала только связывает
транспорт; оно не отправляет запросы подтверждения, если соответствующее семейство подтверждений не включено
и не маршрутизируется в WhatsApp. Режим session доставляет нативные emoji-подтверждения только для подтверждений,
которые исходят из WhatsApp. Режим target использует общий pipeline пересылки для явных целей WhatsApp
и не создает отдельную рассылку approver-DM.
Реакции подтверждения WhatsApp требуют явных approvers WhatsApp из allowFrom или "*".
defaultTo управляет обычными целями сообщений по умолчанию; это не approver подтверждений. Ручные
команды /approve все равно проходят через обычный путь авторизации отправителя WhatsApp перед
разрешением подтверждения.
Хуки Plugin и приватность
Входящие сообщения WhatsApp могут содержать личное содержимое сообщений, номера телефонов, идентификаторы групп, имена отправителей и поля корреляции сессий. Поэтому WhatsApp не транслирует входящие payload хуковmessage_received в Plugins,
если вы явно не включите это:
Контроль доступа и активация
- DM policy
- Group policy + allowlists
- Mentions + /activation
channels.whatsapp.dmPolicy управляет доступом к прямым чатам:pairing(по умолчанию)allowlistopen(требует, чтобыallowFromвключал"*")disabled
allowFrom принимает номера в стиле E.164 (нормализуются внутри).allowFrom — это список контроля доступа отправителей DM. Он не ограничивает явные исходящие отправки в JID групп WhatsApp или JID каналов @newsletter.Переопределение для нескольких учетных записей: channels.whatsapp.accounts.<id>.dmPolicy (и allowFrom) имеют приоритет над значениями по умолчанию на уровне канала для этой учетной записи.Подробности поведения во время выполнения:- pairings сохраняются в allow-store канала и объединяются с настроенным
allowFrom - запланированная автоматизация и резервный выбор получателей Heartbeat используют явные цели доставки или настроенный
allowFrom; DM pairing approvals не являются неявными получателями Cron или Heartbeat - если allowlist не настроен, связанный собственный номер разрешен по умолчанию
- OpenClaw никогда автоматически не выполняет pairing исходящих DM
fromMe(сообщений, которые вы отправляете самому себе со связанного устройства)
Настроенные привязки ACP
WhatsApp поддерживает постоянные привязки ACP с записями верхнего уровняbindings[]:
- Прямые чаты сопоставляются с номерами E.164, такими как
+15555550123. - Группы сопоставляются с JID групп WhatsApp, такими как
120363424282127706@g.us. - Списки разрешённых групп, политика отправителей и шлюзы упоминаний или активации выполняются до того, как OpenClaw проверяет наличие настроенной сессии ACP.
- Совпавшая настроенная привязка ACP владеет маршрутом. Группы рассылки WhatsApp не рассылают этот ход обычным сессиям WhatsApp.
Поведение личного номера и чата с собой
Когда связанный собственный номер также присутствует вallowFrom, включаются защитные механизмы WhatsApp для чата с собой:
- пропускать уведомления о прочтении для ходов в чате с собой
- игнорировать поведение автозапуска по mention-JID, которое иначе отправило бы пинг самому себе
- если
messages.responsePrefixне задан, ответы в чате с собой по умолчанию используют[{identity.name}]или[openclaw]
Нормализация сообщений и контекст
Входящий конверт + контекст ответа
Входящий конверт + контекст ответа
ReplyToId, ReplyToBody, ReplyToSender, JID/E.164 отправителя).
Когда цель цитируемого ответа является скачиваемым медиа, OpenClaw сохраняет её через
обычное хранилище входящих медиа и предоставляет как MediaPath/MediaType, чтобы
агент мог изучить указанное изображение, а не видеть только
<media:image>.Медиа-плейсхолдеры и извлечение местоположения/контактов
Медиа-плейсхолдеры и извлечение местоположения/контактов
<media:image><media:video><media:audio><media:document><media:sticker>
<media:audio>, поэтому произнесённое упоминание бота в голосовой заметке может
запустить ответ. Если транскрипт всё равно не упоминает бота,
транскрипт сохраняется в ожидающей истории группы вместо сырого плейсхолдера.Тела местоположений используют краткий текст координат. Метки/комментарии местоположения и сведения контакта/vCard отображаются как ограждённые недоверенные метаданные, а не как встроенный текст промпта.Внедрение ожидающей истории группы
Внедрение ожидающей истории группы
- лимит по умолчанию:
50 - конфигурация:
channels.whatsapp.historyLimit - fallback:
messages.groupChat.historyLimit 0отключает
[Chat messages since your last reply - for context][Current message - respond to this]
Уведомления о прочтении
Уведомления о прочтении
Доставка, разбиение на части и медиа
Разбиение текста на части
Разбиение текста на части
- лимит части по умолчанию:
channels.whatsapp.textChunkLimit = 4000 channels.whatsapp.chunkMode = "length" | "newline"- режим
newlineпредпочитает границы абзацев (пустые строки), затем возвращается к безопасному по длине разбиению
Поведение исходящих медиа
Поведение исходящих медиа
- поддерживает полезные нагрузки изображений, видео, аудио (голосовая заметка PTT) и документов
- аудиомедиа отправляется через полезную нагрузку Baileys
audioсptt: true, поэтому клиенты WhatsApp отображают его как голосовую заметку push-to-talk - полезные нагрузки ответов сохраняют
audioAsVoice; вывод голосовой заметки TTS для WhatsApp остаётся на этом пути PTT, даже когда провайдер возвращает MP3 или WebM - нативное аудио Ogg/Opus отправляется как
audio/ogg; codecs=opusдля совместимости с голосовыми заметками - аудио не в Ogg, включая вывод Microsoft Edge TTS MP3/WebM, транскодируется с помощью
ffmpegв моно Ogg/Opus 48 кГц перед доставкой PTT /tts latestотправляет последний ответ ассистента как одну голосовую заметку и подавляет повторные отправки того же ответа;/tts chat on|off|defaultуправляет авто-TTS для текущего чата WhatsApp- воспроизведение анимированных GIF поддерживается через
gifPlayback: trueпри отправке видео forceDocument/asDocumentотправляет исходящие изображения, GIF и видео через полезную нагрузку документа Baileys, чтобы избежать сжатия медиа WhatsApp, сохраняя разрешённое имя файла и MIME-тип- подписи применяются к первому медиаэлементу при отправке полезных нагрузок ответов с несколькими медиа, кроме голосовых заметок PTT: они отправляют аудио первым, а видимый текст отдельно, потому что клиенты WhatsApp не всегда стабильно отображают подписи голосовых заметок
- источник медиа может быть HTTP(S),
file://или локальными путями
Ограничения размера медиа и поведение fallback
Ограничения размера медиа и поведение fallback
- лимит сохранения входящих медиа:
channels.whatsapp.mediaMaxMb(по умолчанию50) - лимит отправки исходящих медиа:
channels.whatsapp.mediaMaxMb(по умолчанию50) - переопределения для отдельных аккаунтов используют
channels.whatsapp.accounts.<accountId>.mediaMaxMb - изображения автоматически оптимизируются (изменение размера/перебор качества), чтобы уложиться в лимиты, если
forceDocument/asDocumentне запрашивает доставку как документа - при сбое отправки медиа fallback для первого элемента отправляет текстовое предупреждение вместо молчаливого отбрасывания ответа
Цитирование ответов
WhatsApp поддерживает нативное цитирование ответов, когда исходящие ответы видимо цитируют входящее сообщение. Управляйте этим с помощьюchannels.whatsapp.replyToMode.
| Значение | Поведение |
|---|---|
"off" | Никогда не цитировать; отправлять как обычное сообщение |
"first" | Цитировать только первую часть исходящего ответа |
"all" | Цитировать каждую часть исходящего ответа |
"batched" | Цитировать поставленные в очередь пакетные ответы, оставляя немедленные ответы без цитирования |
"off". Переопределения для отдельных аккаунтов используют channels.whatsapp.accounts.<id>.replyToMode.
Уровень реакций
channels.whatsapp.reactionLevel управляет тем, насколько широко агент использует emoji-реакции в WhatsApp:
| Уровень | Реакции ack | Реакции, инициированные агентом | Описание |
|---|---|---|---|
"off" | Нет | Нет | Реакций нет вообще |
"ack" | Да | Нет | Только реакции ack (подтверждение до ответа) |
"minimal" | Да | Да (консервативно) | Ack + реакции агента с консервативными указаниями |
"extensive" | Да | Да (поощряются) | Ack + реакции агента с поощряющими указаниями |
"minimal".
Переопределения для отдельных аккаунтов используют channels.whatsapp.accounts.<id>.reactionLevel.
Реакции подтверждения
WhatsApp поддерживает немедленные реакции ack при получении входящего сообщения черезchannels.whatsapp.ackReaction.
Реакции ack ограничиваются reactionLevel — они подавляются, когда reactionLevel равен "off".
- отправляется немедленно после принятия входящего сообщения (до ответа)
- если
ackReactionприсутствует безemoji, WhatsApp использует emoji идентичности маршрутизированного агента, возвращаясь к ”👀”; опуститеackReactionили задайтеemoji: "", чтобы не отправлять реакцию ack - сбои журналируются, но не блокируют обычную доставку ответа
- режим группы
mentionsреагирует на ходы, запущенные упоминанием; групповая активацияalwaysдействует как обход этой проверки - WhatsApp использует
channels.whatsapp.ackReaction(устаревшийmessages.ackReactionздесь не используется)
Реакции статуса жизненного цикла
Задайтеmessages.statusReactions.enabled: true, чтобы WhatsApp заменял реакцию ack во время хода вместо сохранения статичного emoji подтверждения. Когда включено, OpenClaw использует тот же слот реакции входящего сообщения для состояний жизненного цикла, таких как очередь, размышление, активность инструментов, Compaction, завершено и ошибка.
channels.whatsapp.ackReactionпо-прежнему управляет тем, доступны ли реакции статуса для прямых сообщений и групп.- Реакция статуса в очереди использует тот же эффективный emoji ack, что и обычные реакции ack.
- У WhatsApp есть один слот реакции бота на сообщение, поэтому обновления жизненного цикла заменяют текущую реакцию на месте.
messages.removeAckAfterReply: trueочищает финальную реакцию статуса после настроенной задержки done/error.- Категории emoji инструментов включают
tool,coding,web,deploy,buildиconcierge.
Несколько аккаунтов и учётные данные
Выбор аккаунта и значения по умолчанию
Выбор аккаунта и значения по умолчанию
- идентификаторы аккаунтов берутся из
channels.whatsapp.accounts - выбор аккаунта по умолчанию:
default, если присутствует, иначе первый настроенный идентификатор аккаунта (по сортировке) - идентификаторы аккаунтов нормализуются внутри для поиска
Пути учётных данных и совместимость с устаревшим форматом
Пути учётных данных и совместимость с устаревшим форматом
- текущий путь авторизации:
~/.openclaw/credentials/whatsapp/<accountId>/creds.json - файл резервной копии:
creds.json.bak - устаревшая авторизация по умолчанию в
~/.openclaw/credentials/всё ещё распознаётся/мигрируется для потоков аккаунта по умолчанию
Поведение выхода
Поведение выхода
openclaw channels logout --channel whatsapp [--account <id>] очищает состояние авторизации WhatsApp для этого аккаунта.Когда Gateway доступен, выход сначала останавливает активный слушатель WhatsApp для выбранного аккаунта, чтобы связанная сессия не продолжала получать сообщения до следующего перезапуска. openclaw channels remove --channel whatsapp также останавливает активный слушатель перед отключением или удалением конфигурации аккаунта.В устаревших каталогах авторизации oauth.json сохраняется, а файлы авторизации Baileys удаляются.Инструменты, действия и записи конфигурации
- Поддержка инструментов агента включает действие реакции WhatsApp (
react). - Шлюзы действий:
channels.whatsapp.actions.reactionschannels.whatsapp.actions.polls
- Записи конфигурации, инициированные каналом, включены по умолчанию (отключение через
channels.whatsapp.configWrites=false).
Устранение неполадок
Не связано (требуется QR)
Не связано (требуется QR)
Связано, но отключено / цикл повторного подключения
Связано, но отключено / цикл повторного подключения
status=408 Request Time-out Connection was lost, настройте
тайминги сокета Baileys в web.whatsapp. Начните с уменьшения
keepAliveIntervalMs ниже тайм-аута простоя вашей сети и увеличения
connectTimeoutMs на медленных каналах или каналах с потерями:~/.openclaw/logs/whatsapp-health.log сообщает Gateway inactive, но
openclaw gateway status и openclaw channels status --probe показывают, что
Gateway и WhatsApp исправны, выполните openclaw doctor. В Linux doctor
предупреждает об устаревших записях crontab, которые все еще вызывают
~/.openclaw/bin/ensure-whatsapp.sh; удалите эти устаревшие записи с помощью
crontab -e, потому что cron может не иметь окружения пользовательской шины systemd и
из-за этого старый скрипт может неверно сообщать о состоянии Gateway.При необходимости выполните повторную привязку с помощью channels login.Вход по QR-коду завершается тайм-аутом за прокси
Вход по QR-коду завершается тайм-аутом за прокси
openclaw channels login --channel whatsapp завершается ошибкой до показа пригодного QR-кода с status=408 Request Time-out или разрывом TLS-сокета.Вход в WhatsApp Web использует стандартное прокси-окружение хоста Gateway (HTTPS_PROXY, HTTP_PROXY, варианты в нижнем регистре и NO_PROXY). Убедитесь, что процесс Gateway наследует переменные окружения прокси и что NO_PROXY не совпадает с mmg.whatsapp.net.Нет активного слушателя при отправке
Нет активного слушателя при отправке
Ответ появляется в стенограмме, но не в WhatsApp
Ответ появляется в стенограмме, но не в WhatsApp
auto-reply delivery failed или auto-reply was not accepted by WhatsApp provider.Сообщения группы неожиданно игнорируются
Сообщения группы неожиданно игнорируются
groupPolicygroupAllowFrom/allowFrom- записи списка разрешенных
groups - фильтрация по упоминаниям (
requireMention+ шаблоны упоминаний) - повторяющиеся ключи в
openclaw.json(JSON5): более поздние записи переопределяют более ранние, поэтому оставляйте одинgroupPolicyна область
channels.whatsapp.groups присутствует, WhatsApp все еще может наблюдать сообщения из других групп, но OpenClaw отбрасывает их до маршрутизации сессии. Добавьте JID группы в channels.whatsapp.groups или добавьте groups["*"], чтобы допустить все группы, сохраняя авторизацию отправителей в groupPolicy и groupAllowFrom.Предупреждение среды выполнения Bun
Предупреждение среды выполнения Bun
Системные промпты
WhatsApp поддерживает системные промпты в стиле Telegram для групп и прямых чатов через картыgroups и direct.
Иерархия разрешения для групповых сообщений:
Эффективная карта groups определяется первой: если учетная запись определяет собственные groups, она полностью заменяет корневую карту groups (без глубокого слияния). Затем поиск промпта выполняется в получившейся единственной карте:
- Системный промпт для конкретной группы (
groups["<groupId>"].systemPrompt): используется, когда запись конкретной группы существует в карте и ее ключsystemPromptопределен. ЕслиsystemPromptявляется пустой строкой (""), подстановочный вариант подавляется и системный промпт не применяется. - Подстановочный системный промпт для групп (
groups["*"].systemPrompt): используется, когда запись конкретной группы полностью отсутствует в карте или когда она существует, но не определяет ключsystemPrompt.
direct определяется первой: если учетная запись определяет собственный direct, он полностью заменяет корневую карту direct (без глубокого слияния). Затем поиск промпта выполняется в получившейся единственной карте:
- Системный промпт для конкретного прямого чата (
direct["<peerId>"].systemPrompt): используется, когда запись конкретного собеседника существует в карте и ее ключsystemPromptопределен. ЕслиsystemPromptявляется пустой строкой (""), подстановочный вариант подавляется и системный промпт не применяется. - Подстановочный системный промпт для прямых чатов (
direct["*"].systemPrompt): используется, когда запись конкретного собеседника полностью отсутствует в карте или когда она существует, но не определяет ключsystemPrompt.
dms остается легковесным контейнером переопределения истории для отдельных DM (dms.<id>.historyLimit). Переопределения промптов находятся в direct.groups намеренно подавляются для всех учетных записей в конфигурации с несколькими учетными записями — даже для учетных записей, которые не определяют собственные groups, — чтобы бот не получал сообщения групп, к которым он не принадлежит. WhatsApp не применяет эту защиту: корневые groups и корневой direct всегда наследуются учетными записями, которые не определяют переопределение на уровне учетной записи, независимо от количества настроенных учетных записей. В конфигурации WhatsApp с несколькими учетными записями, если вам нужны групповые или прямые промпты для каждой учетной записи, явно определяйте полную карту в каждой учетной записи, а не полагайтесь на корневые значения по умолчанию.
Важное поведение:
channels.whatsapp.groupsявляется и картой конфигурации для отдельных групп, и списком разрешенных групп на уровне чата. На корневом уровне или уровне учетной записиgroups["*"]означает «допускаются все группы» для этой области.- Добавляйте подстановочный
systemPromptгруппы только тогда, когда вы уже хотите, чтобы эта область допускала все группы. Если вы по-прежнему хотите, чтобы подходящим был только фиксированный набор идентификаторов групп, не используйтеgroups["*"]как значение промпта по умолчанию. Вместо этого повторите промпт в каждой явно разрешенной записи группы. - Допуск группы и авторизация отправителя являются отдельными проверками.
groups["*"]расширяет набор групп, которые могут попасть в обработку групп, но само по себе не авторизует каждого отправителя в этих группах. Доступ отправителей по-прежнему отдельно контролируетсяchannels.whatsapp.groupPolicyиchannels.whatsapp.groupAllowFrom. channels.whatsapp.directне имеет такого же побочного эффекта для DM.direct["*"]только предоставляет конфигурацию прямого чата по умолчанию после того, как DM уже допущен черезdmPolicyплюсallowFromили правила хранилища привязок.
Указатели на справочник конфигурации
Основной справочник: Наиболее важные поля WhatsApp:- доступ:
dmPolicy,allowFrom,groupPolicy,groupAllowFrom,groups - доставка:
textChunkLimit,chunkMode,mediaMaxMb,sendReadReceipts,ackReaction,reactionLevel - несколько учетных записей:
accounts.<id>.enabled,accounts.<id>.authDir, переопределения на уровне учетной записи - операции:
configWrites,debounceMs,web.enabled,web.heartbeatSeconds,web.reconnect.*,web.whatsapp.* - поведение сессии:
session.dmScope,historyLimit,dmHistoryLimit,dms.<id>.historyLimit - промпты:
groups.<id>.systemPrompt,groups["*"].systemPrompt,direct.<id>.systemPrompt,direct["*"].systemPrompt