Mainstream messaging

WhatsApp

Статус: готово к промышленной эксплуатации через WhatsApp Web (Baileys). Gateway управляет связанными сеансами; отдельного канала Twilio WhatsApp нет.

Установка

openclaw onboard и openclaw channels add --channel whatsapp предлагают установить плагин при его первом выборе; openclaw channels login --channel whatsapp предлагает тот же процесс установки, если плагин отсутствует. В рабочих копиях для разработки используется локальный путь к плагину; при стабильной или бета-установке сначала устанавливается @openclaw/whatsapp из ClawHub, а при неудаче используется npm. Среда выполнения WhatsApp поставляется вне основного npm-пакета OpenClaw, поэтому её зависимости среды выполнения остаются во внешнем плагине. Установка вручную:

bash
openclaw plugins install clawhub:@openclaw/whatsapp

Используйте пакет npm без префикса (@openclaw/whatsapp) только как резервный вариант для реестра; закрепляйте точную версию только для воспроизводимой установки.

Быстрая настройка

  • Настройте политику доступа

    json5
    {channels: {whatsapp: {  dmPolicy: "pairing",  allowFrom: ["+15551234567"],  groupPolicy: "allowlist",  groupAllowFrom: ["+15551234567"],},},}
  • Свяжите WhatsApp (QR-код)

    bash
    openclaw channels login --channel whatsapp

    Вход выполняется только по QR-коду. На удалённых серверах или узлах без графического интерфейса перед началом входа подготовьте надёжный способ передачи актуального QR-кода на телефон; QR-коды, отображаемые в терминале, снимки экрана и вложения в чатах могут устареть во время передачи.

    Для конкретной учётной записи:

    bash
    openclaw channels login --channel whatsapp --account work

    Чтобы подключить существующий или пользовательский каталог аутентификации перед входом:

    bash
    openclaw channels add --channel whatsapp --account work --auth-dir /path/to/wa-authopenclaw channels login --channel whatsapp --account work
  • Запустите Gateway

    bash
    openclaw gateway
  • Одобрите первый запрос на связывание (режим связывания)

    bash
    openclaw pairing list whatsappopenclaw pairing approve whatsapp <CODE>

    Срок действия запросов на связывание истекает через 1 час; для каждой учётной записи допускается не более 3 ожидающих запросов.

  • Схемы развёртывания

    Выделенный номер (рекомендуется)
    • отдельная идентичность WhatsApp для OpenClaw
    • более чёткие списки разрешённых отправителей личных сообщений и границы маршрутизации
    • меньше вероятность путаницы с чатом с самим собой
    json5
    {  channels: {    whatsapp: {      dmPolicy: "allowlist",      allowFrom: ["+15551234567"],    },  },}
    Резервный вариант с личным номером

    Первоначальная настройка поддерживает режим личного номера и записывает базовую конфигурацию, подходящую для чата с самим собой: dmPolicy: "allowlist", allowFrom, включая ваш собственный номер, selfChatMode: true. Защита среды выполнения для чата с самим собой опирается на связанный собственный номер и allowFrom.

    Модель среды выполнения

    • Gateway управляет сокетом WhatsApp и циклом повторного подключения.
    • Сторожевой механизм независимо отслеживает два сигнала: активность транспорта WhatsApp Web на низком уровне и активность сообщений приложения. Тихий, но подключённый сеанс не перезапускается только из-за того, что в последнее время не поступали сообщения; принудительное повторное подключение происходит, только если транспортные кадры перестают поступать в течение фиксированного внутреннего интервала (не настраивается пользователем) или сообщения приложения отсутствуют дольше четырёхкратного обычного тайм-аута сообщений. Сразу после повторного подключения недавно активного сеанса для первого интервала используется более короткий обычный тайм-аут сообщений вместо четырёхкратного интервала. OpenClaw может автоматически отвечать на офлайн-сообщения, которые Baileys доставляет в начале такого повторного подключения, в пределах срока дедупликации идентификаторов входящих сообщений; при первоначальном запуске сохраняется короткая защита от устаревшей истории.
    • Временные параметры сокета Baileys явно задаются в web.whatsapp.*: keepAliveIntervalMs (интервал проверки связи приложения), connectTimeoutMs (тайм-аут начального рукопожатия), defaultQueryTimeoutMs (ожидание запросов Baileys, а также тайм-ауты OpenClaw для исходящей отправки, статуса присутствия и входящих подтверждений прочтения).
    • Для исходящей отправки требуется активный слушатель WhatsApp для целевой учётной записи; в противном случае отправка немедленно завершается ошибкой.
    • При отправке в группы добавляются собственные метаданные упоминаний для токенов @+<digits> и @<digits> (в тексте и подписях к медиафайлам), если токен соответствует текущим метаданным участника, включая группы на основе LID.
    • Чаты статусов и рассылок (@status, @broadcast) игнорируются.
    • В личных чатах применяются правила сеансов личных сообщений (session.dmScope; значение по умолчанию main объединяет личные сообщения в основном сеансе агента). Групповые сеансы изолируются по JID (agent:<agentId>:whatsapp:group:<jid>).
    • Каналы и рассылки WhatsApp могут быть явно указаны в качестве целей исходящей отправки через их собственный JID @newsletter, при этом используются метаданные сеанса канала (agent:<agentId>:whatsapp:channel:<jid>), а не семантика личных сообщений.
    • Транспорт WhatsApp Web учитывает стандартные переменные среды прокси на узле Gateway (HTTPS_PROXY, HTTP_PROXY, NO_PROXY и варианты в нижнем регистре). Предпочитайте настройку прокси на уровне узла параметрам отдельных каналов.
    • Если включён messages.removeAckAfterReply, OpenClaw удаляет реакцию подтверждения после доставки видимого ответа.

    Вызов текущего отправителя с помощью MeowCaller (экспериментальная функция)

    Плагин может предоставлять whatsapp_call в запусках агента, инициированных из WhatsApp. Он использует MeowCaller, чтобы совершить голосовой вызов WhatsApp текущему авторизованному отправителю и воспроизвести сообщение OpenClaw, синтезированное посредством TTS, после ответа. У инструмента нет параметра номера назначения, поэтому запрос не может перенаправить вызов. По умолчанию отключено.

  • Включите экспериментальные вызовы

    Добавьте actions.calls: true в конфигурацию канала WhatsApp и перезапустите Gateway:

    json
    {"channels": {"whatsapp": {  "actions": {    "calls": true  }}}}

    Если параметр отсутствует или равен false, OpenClaw не предоставляет инструмент whatsapp_call.

  • Установите проверенный CLI MeowCaller

    Адаптер ожидает исполняемый файл meowcaller в PATH на узле Gateway. До слияния PR MeowCaller № 7 соберите проверенную ветку:

    bash
    git clone --branch feat/send-only-notify https://github.com/steipete/meowcaller.gitcd meowcallergit checkout 752050471fc2bf7a8cdfbf7dbd3cd4e865d85d3fmkdir -p "$HOME/.local/bin"go build -o "$HOME/.local/bin/meowcaller" ./cmd/meowcaller

    Убедитесь, что $HOME/.local/bin входит в PATH службы Gateway. В этой редакции явно предусмотрены команды pair и notify только для отправки; notify не открывает микрофон, динамик, видеоустройство или диагностический захват. Не заменяйте её командой play из примера CLI вышестоящего проекта.

  • Свяжите подключённое устройство MeowCaller

    Попросите агента WhatsApp проверить настройку вызовов (действие состояния whatsapp_call сообщает каталог состояния для конкретной учётной записи и команду связывания). Для учётной записи по умолчанию:

    bash
    state_dir="$HOME/.openclaw/credentials/whatsapp-calls/default"mkdir -p "$state_dir"chmod 700 "$state_dir"meowcaller pair --store "$state_dir/wa-voip.db"

    Запустите команду интерактивно, отсканируйте QR-код через WhatsApp > Linked devices и дождитесь MeowCaller linked device ready. Храните wa-voip.db в тайне — это сеанс MeowCaller. Для учётных записей не по умолчанию действие состояния предоставляет отдельный путь к хранилищу; в Windows выполните соответствующую команду PowerShell.

  • Настройте TTS и совершите вызов из WhatsApp

    Настройте поставщика TTS с поддержкой телефонии, перезапустите Gateway, затем отправьте запрос, например Call me and say the build finished.. Инструмент определяет отправителя из доверенного входящего контекста, синтезирует временный закрытый WAV-файл, запускает MeowCaller на ограниченное время вызова и после этого удаляет аудиофайл. OpenClaw явно передаёт хранилище учётной записи, ожидает нулевой код завершения после ответа, воспроизведения и завершения вызова и считает тайм-аут или ненулевой код завершения неудачным вызовом инструмента.

  • Ограничения: только исходящие аудиовызовы один на один, без произвольных номеров назначения, без общей аутентификации с подключением чата, без вызовов самому себе в режиме личного номера или чата с самим собой, длительность синтезированного аудио ограничена 60 секундами, подтверждение слышимости на стороне телефона отсутствует помимо завершения этапов ответа, воспроизведения и завершения вызова в MeowCaller, а OpenClaw останавливает сопутствующий процесс по истечении ограниченного интервала в 115–175 секунд (охватывающего этапы подключения, ответа, воспроизведения и завершения работы MeowCaller).

    Запросы на одобрение

    WhatsApp может отображать запросы на одобрение выполнения команд и действий плагинов в виде реакций 👍/👎, управляемых конфигурацией пересылки одобрений верхнего уровня:

    json5
    {  approvals: {    exec: {      enabled: true,      mode: "session",    },    plugin: {      enabled: true,      mode: "targets",      targets: [{ channel: "whatsapp", to: "+15551234567" }],    },  },}

    approvals.exec и approvals.plugin независимы друг от друга; включение WhatsApp в качестве канала только подключает транспорт и ничего не отправляет, если соответствующий тип одобрений не включён и не направлен туда. Режим сеанса доставляет собственные одобрения с помощью эмодзи только для запросов на одобрение, поступивших из WhatsApp. Режим целей использует общий конвейер пересылки для явно заданных целей и не создаёт отдельную рассылку личных сообщений утверждающим лицам.

    Для реакций одобрения WhatsApp требуется явно указать утверждающих лиц в allowFrom (или "*"). defaultTo задаёт обычные цели сообщений по умолчанию, а не список утверждающих лиц. Команды /approve, введённые вручную, по-прежнему проходят обычную проверку авторизации отправителя WhatsApp перед обработкой одобрения.

    Хуки плагинов и конфиденциальность

    Входящие сообщения WhatsApp могут содержать личные сведения, номера телефонов, идентификаторы групп, имена отправителей и поля корреляции сеансов. WhatsApp не рассылает входящие полезные нагрузки хука message_received плагинам, если вы явно не разрешите это:

    json5
    {  channels: {    whatsapp: {      pluginHooks: {        messageReceived: true,      },    },  },}

    Ограничьте разрешение одной учётной записью в channels.whatsapp.accounts.<id>.pluginHooks.messageReceived. Включайте его только для плагинов, которым вы доверяете содержимое и идентификаторы входящих сообщений WhatsApp.

    Управление доступом и активация

    Политика личных сообщений

    channels.whatsapp.dmPolicy:

    Значение Поведение
    pairing (по умолчанию) Неизвестные отправители запрашивают связывание; владелец одобряет запрос
    allowlist Допускаются только отправители из allowFrom
    open Требует, чтобы allowFrom включал "*"
    disabled Блокировать все личные сообщения

    allowFrom принимает номера в формате E.164 (с внутренней нормализацией). Это только список управления доступом отправителей личных сообщений — он не ограничивает явную исходящую отправку в групповые JID или JID каналов @newsletter.

    Переопределение для нескольких учётных записей: channels.whatsapp.accounts.<id>.dmPolicy.allowFrom) имеют приоритет над значениями канала по умолчанию для соответствующей учётной записи.

    Примечания о среде выполнения:

    • сопряжения сохраняются в хранилище разрешений канала и объединяются с настроенными allowFrom
    • запланированная автоматизация и резервный выбор получателя Heartbeat используют явные цели доставки или настроенные allowFrom; одобрения сопряжения в личных сообщениях не становятся неявными получателями Cron/Heartbeat
    • если список разрешений не настроен, привязанный собственный номер разрешён по умолчанию
    • OpenClaw никогда автоматически не сопрягает исходящие личные сообщения fromMe (сообщения, которые вы отправляете себе с привязанного устройства)

    Политика групп и списки разрешений

    Доступ к группам имеет два уровня:

    1. Список разрешённых участников групп (channels.whatsapp.groups): если groups не указан, допускаются все группы; если указан, он действует как список разрешённых групп ("*" разрешает все).
    2. Политика отправителей в группах (channels.whatsapp.groupPolicy + groupAllowFrom): open обходит список разрешённых отправителей, allowlist требует совпадения с groupAllowFrom (или *), disabled блокирует все входящие сообщения из групп.

    Если groupAllowFrom не задан, при наличии записей проверки отправителей используют allowFrom как резервный вариант. Списки разрешённых отправителей проверяются до активации по упоминанию или ответу.

    Если блок channels.whatsapp отсутствует полностью, среда выполнения использует groupPolicy: "allowlist" как резервный вариант (с предупреждением в журнале), даже если channels.defaults.groupPolicy имеет другое значение.

    Упоминания и /activation

    По умолчанию для ответов в группах требуется упоминание. Обнаружение упоминаний включает:

    • явные упоминания идентификатора бота в WhatsApp
    • настроенные регулярные выражения упоминаний (agents.list[].groupChat.mentionPatterns, резервный вариант — messages.groupChat.mentionPatterns)
    • расшифровки входящих голосовых сообщений для авторизованных групповых сообщений
    • неявное обнаружение ответа боту (отправитель исходного сообщения совпадает с идентификатором бота)

    Безопасность: цитирование или ответ удовлетворяет только условию упоминания — оно не предоставляет отправителю авторизацию. При groupPolicy: "allowlist" отправители вне списка разрешений остаются заблокированными, даже если отвечают на сообщение разрешённого пользователя.

    Команда активации на уровне сеанса: /activation mention или /activation always. Она обновляет состояние сеанса (а не глобальную конфигурацию) и доступна только владельцу.

    Настроенные привязки ACP

    WhatsApp поддерживает постоянные привязки ACP через bindings[] верхнего уровня:

    json5
    {  bindings: [    {      type: "acp",      agentId: "codex",      match: {        channel: "whatsapp",        accountId: "work",        peer: { kind: "direct", id: "+15555550123" },      },    },    {      type: "acp",      agentId: "codex",      match: {        channel: "whatsapp",        accountId: "work",        peer: { kind: "group", id: "120363424282127706@g.us" },      },    },  ],}

    Личные чаты сопоставляются по номерам E.164, а группы — по групповым JID WhatsApp. Списки разрешённых групп, политика отправителей и условия активации по упоминанию выполняются до того, как OpenClaw обеспечит существование привязанного сеанса ACP. Совпавшая привязка становится владельцем маршрута — широковещательные группы не направляют этот ход в обычные сеансы WhatsApp.

    Поведение личного номера и чата с собой

    Когда привязанный собственный номер также присутствует в allowFrom, активируются защитные меры для чата с собой: отключаются уведомления о прочтении для сообщений в чате с собой, игнорируется автоматический запуск по JID упоминания, который привёл бы к упоминанию самого себя, а ответы по умолчанию направляются в [{identity.name}] (или [openclaw]), если messages.responsePrefix не задан.

    Нормализация сообщений и контекст

    Оболочка входящего сообщения и контекст ответа

    Входящие сообщения помещаются в общую оболочку входящих сообщений. Ответ с цитированием добавляет контекст в следующем виде:

    text
    [Replying to <sender> id:<stanzaId>]<quoted body or media placeholder>[/Replying]

    Метаданные ответа (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, резервный вариант — messages.groupChat.historyLimit
    • 0 отключает эту функцию

    Маркеры добавления: [Chat messages since your last reply - for context] и [Current message - respond to this].

    Уведомления о прочтении

    По умолчанию включены для принятых входящих сообщений. Чтобы отключить глобально:

    json5
    { channels: { whatsapp: { sendReadReceipts: false } } }

    Переопределение для отдельной учётной записи: channels.whatsapp.accounts.<id>.sendReadReceipts. Для сообщений в чате с собой уведомления о прочтении пропускаются, даже если они включены глобально.

    Доставка, разбиение на части и медиафайлы

    Разбиение текста на части
    • ограничение размера части по умолчанию: channels.whatsapp.textChunkLimit = 4000
    • channels.whatsapp.streaming.chunkMode = "length" | "newline"; newline предпочитает границы абзацев (пустые строки), а затем использует безопасное разбиение по длине
    Поведение исходящих медиафайлов
    • поддерживаются изображения, видео, аудио (голосовые сообщения PTT) и документы
    • аудио отправляется как полезная нагрузка Baileys audio с ptt: true и отображается как голосовое сообщение push-to-talk; audioAsVoice сохраняется в полезной нагрузке ответа, поэтому голосовой вывод TTS остаётся на этом пути независимо от исходного формата провайдера
    • аудио в собственном формате Ogg/Opus отправляется как audio/ogg; codecs=opus; всё остальное (включая вывод Microsoft Edge TTS в MP3/WebM) перед доставкой PTT перекодируется с помощью ffmpeg в монофонический Ogg/Opus с частотой 48 кГц
    • /tts latest отправляет последний ответ ассистента как одно голосовое сообщение и предотвращает повторную отправку того же ответа; /tts chat on|off|default управляет автоматическим TTS для текущего чата
    • включение gifPlayback: true для видео активирует воспроизведение анимированных GIF
    • forceDocument/asDocument направляет исходящие изображения, GIF и видео через полезную нагрузку документа Baileys, чтобы избежать сжатия медиафайлов в WhatsApp и сохранить определённые имя файла и MIME-тип
    • подписи применяются к первому медиафайлу в ответе с несколькими медиафайлами, кроме голосовых сообщений PTT: аудио отправляется первым без подписи, затем подпись отправляется отдельным текстовым сообщением (клиенты WhatsApp отображают подписи к голосовым сообщениям непоследовательно)
    • источником медиафайла может быть HTTP(S), file:// или локальный путь
    Ограничения размера медиафайлов и резервное поведение
    • ограничение сохранения входящих и отправки исходящих медиафайлов: channels.whatsapp.mediaMaxMb (по умолчанию 50)
    • переопределение для отдельной учётной записи: channels.whatsapp.accounts.<id>.mediaMaxMb
    • изображения автоматически оптимизируются (изменение размера и перебор качества) для соответствия ограничениям, если forceDocument/asDocument не запрашивает доставку в виде документа
    • при ошибке отправки медиафайла резервный вариант для первого элемента отправляет текстовое предупреждение вместо молчаливого удаления ответа

    Цитирование при ответе

    channels.whatsapp.replyToMode управляет встроенным цитированием ответов (исходящие ответы визуально цитируют входящее сообщение):

    Значение Поведение
    "off" (по умолчанию) Никогда не цитировать; отправлять как обычное сообщение
    "first" Цитировать только первую часть исходящего ответа
    "all" Цитировать каждую часть исходящего ответа
    "batched" Цитировать пакетные ответы из очереди; немедленные ответы оставлять без цитирования

    Переопределение для отдельной учётной записи: channels.whatsapp.accounts.<id>.replyToMode.

    json5
    { channels: { whatsapp: { replyToMode: "first" } } }

    Уровень реакций

    channels.whatsapp.reactionLevel определяет, насколько широко агент использует реакции с эмодзи:

    Уровень Реакции подтверждения Реакции по инициативе агента
    "off" Нет Нет
    "ack" Да Нет
    "minimal" (по умолчанию) Да Да, консервативные рекомендации
    "extensive" Да Да, рекомендуется активное использование

    Переопределение для отдельной учётной записи: channels.whatsapp.accounts.<id>.reactionLevel.

    json5
    { channels: { whatsapp: { reactionLevel: "ack" } } }

    Реакции подтверждения

    channels.whatsapp.ackReaction отправляет немедленную реакцию при получении входящего сообщения с учётом reactionLevel (подавляется при "off"):

    json5
    {  channels: {    whatsapp: {      ackReaction: {        emoji: "👀",        direct: true,        group: "mentions", // always | mentions | never      },    },  },}

    Примечания: отправляется сразу после принятия входящего сообщения (до ответа); если ackReaction присутствует без emoji, WhatsApp использует эмодзи идентификатора назначенного агента, а при его отсутствии — "👀" (не указывайте ackReaction или задайте emoji: "", чтобы отключить подтверждение); ошибки регистрируются в журнале, но не блокируют доставку ответа; групповой режим mentions реагирует только на ходы, запущенные упоминанием, а групповая активация always обходит эту проверку; WhatsApp использует только channels.whatsapp.ackReaction (устаревший messages.ackReaction здесь не применяется).

    Реакции состояния жизненного цикла

    Задайте messages.statusReactions.enabled: true, чтобы WhatsApp во время хода заменял реакцию подтверждения вместо сохранения статичного эмодзи получения, последовательно переключаясь между такими состояниями, как ожидание в очереди, размышление, активность инструментов, Compaction, завершение и ошибка:

    json5
    {  messages: {    statusReactions: {      enabled: true,      emojis: {        deploy: "🛫",        build: "🏗️",        concierge: "💁",      },    },  },}

    Примечания: channels.whatsapp.ackReaction по-прежнему определяет доступность для личных сообщений и групп; состояние ожидания в очереди использует тот же фактический эмодзи, что и обычные реакции подтверждения; WhatsApp предоставляет один слот реакции бота на сообщение, поэтому обновления жизненного цикла заменяют текущую реакцию на месте; messages.removeAckAfterReply: true удаляет финальную реакцию состояния после настроенного периода удержания состояния завершения или ошибки; категории эмодзи инструментов включают 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 доступен, при выходе сначала останавливается активный слушатель этой учётной записи, поэтому связанный сеанс перестаёт получать сообщения ещё до следующего перезапуска. openclaw channels remove --channel whatsapp также останавливает активный слушатель перед отключением или удалением конфигурации учётной записи.

    В устаревших каталогах аутентификации oauth.json сохраняется, а файлы аутентификации Baileys удаляются.

    Инструменты, действия и запись конфигурации

    • Инструменты агента поддерживают действие реакции WhatsApp (react).
    • Ограничители действий: channels.whatsapp.actions.reactions, channels.whatsapp.actions.polls (для существующих действий по умолчанию используется true), channels.whatsapp.actions.calls (по умолчанию false, см. MeowCaller выше).
    • Запись конфигурации, инициированная каналом, по умолчанию включена; отключите её через channels.whatsapp.configWrites: false.

    Устранение неполадок

    Связь не установлена (требуется QR-код)

    Симптом: состояние канала сообщает, что связь не установлена.

    bash
    openclaw channels login --channel whatsappopenclaw channels status
    Связь установлена, но соединение разорвано / цикл переподключения

    Симптом: связанная учётная запись постоянно отключается или пытается переподключиться.

    Неактивные учётные записи могут оставаться подключёнными дольше обычного тайм-аута сообщений; механизм наблюдения выполняет перезапуск, только если прекращается активность транспорта WhatsApp Web, закрывается сокет или активность на уровне приложения отсутствует дольше увеличенного защитного интервала (см. раздел «Модель выполнения» выше).

    Если в журналах многократно появляется status=408 Request Time-out Connection was lost, настройте временные параметры сокета Baileys в web.whatsapp. Сначала уменьшите keepAliveIntervalMs до значения ниже тайм-аута простоя вашей сети и увеличьте connectTimeoutMs для медленных соединений или соединений с потерями:

    json5
    {  web: {    whatsapp: {      keepAliveIntervalMs: 15000,      connectTimeoutMs: 60000,      defaultQueryTimeoutMs: 60000,    },  },}

    Исправление:

    bash
    openclaw channels status --probeopenclaw doctoropenclaw logs --followopenclaw gateway status

    Если цикл сохраняется после устранения проблем с подключением хоста и временными параметрами, создайте резервную копию каталога аутентификации учётной записи и установите связь заново:

    bash
    cp -a ~/.openclaw/credentials/whatsapp/<accountId> \  ~/.openclaw/credentials/whatsapp/<accountId>.bakopenclaw channels logout --channel whatsapp --account <accountId>openclaw channels login --channel whatsapp --account <accountId>

    Если ~/.openclaw/logs/whatsapp-health.log сообщает Gateway inactive, но openclaw gateway status и openclaw channels status --probe показывают исправное состояние, выполните openclaw doctor. В Linux doctor предупреждает об устаревших записях crontab, вызывающих выведенный из эксплуатации скрипт ~/.openclaw/bin/ensure-whatsapp.sh; удалите эти записи с помощью crontab -e — в окружении Cron может отсутствовать пользовательская шина systemd, из-за чего старый скрипт неверно сообщает о состоянии Gateway.

    Вход по 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.

    При отправке отсутствует активный слушатель

    Исходящая отправка немедленно завершается ошибкой, если для целевой учётной записи отсутствует активный слушатель Gateway. Убедитесь, что Gateway запущен и учётная запись связана.

    Ответ отображается в расшифровке, но отсутствует в WhatsApp

    Строки расшифровки фиксируют то, что сгенерировал агент; доставка в WhatsApp проверяется отдельно. OpenClaw считает автоматический ответ отправленным, только когда Baileys возвращает идентификатор исходящего сообщения хотя бы для одной видимой отправки текста или медиафайла.

    Реакции-подтверждения представляют собой независимые квитанции перед ответом — успешная реакция не доказывает, что последующий текстовый или мультимедийный ответ был принят. Проверьте журналы Gateway на наличие auto-reply delivery failed или auto-reply was not accepted by WhatsApp provider.

    Сообщения группы неожиданно игнорируются

    Проверьте в следующем порядке: groupPolicy, groupAllowFrom/allowFrom, записи списка разрешений groups, фильтрацию по упоминаниям (requireMention + шаблоны упоминаний) и повторяющиеся ключи в openclaw.json (в JSON5 более поздние записи переопределяют предыдущие — оставляйте только один groupPolicy для каждой области).

    Если присутствует channels.whatsapp.groups, WhatsApp по-прежнему может видеть сообщения из других групп, но OpenClaw отбрасывает их до маршрутизации сеанса. Добавьте JID группы в channels.whatsapp.groups или добавьте groups["*"], чтобы разрешить все группы, сохранив авторизацию отправителей через groupPolicy/groupAllowFrom.

    Предупреждение среды выполнения Bun

    Для Gateway OpenClaw требуется Node. Bun не предоставляет API node:sqlite, используемый каноническим хранилищем состояния, а doctor переносит устаревшие службы Bun на Node.

    Системные промпты

    WhatsApp поддерживает системные промпты в стиле Telegram для групп и личных чатов через карты groups и direct.

    Разрешение для групповых сообщений: сначала определяется действующая карта groups — если в учётной записи вообще определён собственный ключ groups, он полностью заменяет корневую карту groups (без глубокого слияния). Затем поиск промпта выполняется в единственной результирующей карте:

    1. Промпт для конкретной группы (groups["<groupId>"].systemPrompt): используется, когда запись группы существует и в ней определён ключ systemPrompt. Пустая строка ("") подавляет подстановочный знак, и промпт не применяется.
    2. Промпт с подстановочным знаком для групп (groups["*"].systemPrompt): используется, когда запись конкретной группы отсутствует или существует без ключа systemPrompt.

    Разрешение для личных сообщений выполняется по идентичной схеме для карты direct и direct["*"].

    Отличие от Telegram: Telegram подавляет корневой groups для каждой учётной записи в конфигурации с несколькими учётными записями (даже если у учётной записи нет собственного groups), чтобы бот не получал сообщения из групп, в которых он не состоит. WhatsApp не применяет эту защиту — корневые groups/direct наследуются любой учётной записью без собственного переопределения независимо от количества учётных записей. Если в конфигурации WhatsApp с несколькими учётными записями нужны отдельные промпты для каждой учётной записи, явно определите полную карту в каждой из них.

    Важные особенности поведения:

    • channels.whatsapp.groups одновременно является картой конфигурации для отдельных групп и списком разрешений групп на уровне чата. Как в корневой области, так и в области учётной записи groups["*"] означает «разрешены все группы» для этой области.
    • Добавляйте подстановочный знак systemPrompt, только если вы уже хотите разрешить все группы в этой области. Чтобы оставить доступным только фиксированный набор идентификаторов групп, повторите промпт в каждой явно разрешённой записи вместо использования groups["*"].
    • Допуск группы и авторизация отправителя проверяются отдельно. groups["*"] расширяет перечень групп, сообщения из которых передаются в обработку групп; это не авторизует всех отправителей в этих группах — их авторизация по-прежнему управляется через groupPolicy/groupAllowFrom.
    • channels.whatsapp.direct не имеет аналогичного побочного эффекта для личных сообщений: direct["*"] лишь предоставляет конфигурацию по умолчанию после того, как личное сообщение уже допущено согласно dmPolicy совместно с allowFrom или правилами хранилища сопряжений.

    Пример:

    json5
    {  channels: {    whatsapp: {      groups: {        // Используйте, только если в корневой области должны быть разрешены все группы.        // Применяется ко всем учётным записям без собственной карты groups.        "*": { systemPrompt: "Промпт по умолчанию для всех групп." },      },      direct: {        // Применяется ко всем учётным записям без собственной карты direct.        "*": { systemPrompt: "Промпт по умолчанию для всех личных чатов." },      },      accounts: {        work: {          groups: {            // Эта учётная запись определяет собственную карту groups, поэтому корневая            // карта groups полностью заменяется. Чтобы сохранить подстановочный знак, явно определите "*" и здесь.            "120363406415684625@g.us": {              requireMention: false,              systemPrompt: "Сосредоточьтесь на управлении проектом.",            },            // Используйте, только если в этой учётной записи должны быть разрешены все группы.            "*": { systemPrompt: "Промпт по умолчанию для рабочих групп." },          },          direct: {            // Эта учётная запись определяет собственную карту direct, поэтому корневые записи direct            // полностью заменяются. Чтобы сохранить подстановочный знак, явно определите "*" и здесь.            "+15551234567": { systemPrompt: "Промпт для конкретного рабочего личного чата." },            "*": { systemPrompt: "Промпт по умолчанию для рабочих личных чатов." },          },        },      },    },  },}

    Указатели на справочник по конфигурации

    Основной справочник: Справочник по конфигурации — WhatsApp

    Область Поля
    Доступ dmPolicy, allowFrom, groupPolicy, groupAllowFrom, groups
    Доставка textChunkLimit, streaming.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

    Связанные разделы

    Was this useful?
    On this page

    On this page