WhatsApp (веб-канал)

Статус: WhatsApp Web через Baileys. Шлюз владеет сессией(ями).

Быстрая настройка (для начинающих)

  1. По возможности используйте отдельный номер телефона (рекомендуется).
  2. Настройте WhatsApp в ~/.openclaw/openclaw.json.
  3. Запустите openclaw channels login для сканирования QR-кода (Связанные устройства).
  4. Запустите шлюз.

Минимальная конфигурация:

{
  channels: {
    whatsapp: {
      dmPolicy: "allowlist",
      allowFrom: ["+15551234567"]
    }
  }
}

Цели

  • Несколько аккаунтов WhatsApp (мульти-аккаунт) в одном процессе шлюза.
  • Детерминированная маршрутизация: ответы возвращаются в WhatsApp, без маршрутизации модели.
  • Модель видит достаточно контекста для понимания цитируемых ответов.

Запись конфигурации

По умолчанию WhatsApp может записывать обновления конфигурации, инициированные /config set|unset (требуется commands.config: true).

Отключить:

{
  channels: { whatsapp: { configWrites: false } }
}

Архитектура (кто чем владеет)

  • Шлюз владеет сокетом Baileys и циклом входящих сообщений.
  • CLI / приложение macOS общаются со шлюзом; прямого использования Baileys нет.
  • Активный слушатель требуется для исходящей отправки; иначе отправка быстро завершается с ошибкой.

Получение номера телефона (два режима)

WhatsApp требует реальный мобильный номер для верификации. VoIP и виртуальные номера обычно блокируются. Есть два поддерживаемых способа запустить OpenClaw на WhatsApp:

Выделенный номер (рекомендуется)

Используйте отдельный номер телефона для OpenClaw. Лучший UX, чистая маршрутизация, без особенностей самостоятельного чата. Идеальная настройка: запасной/старый Android телефон + eSIM. Оставьте его подключенным к Wi‑Fi и питанию, и привяжите через QR.

WhatsApp Business: Вы можете использовать WhatsApp Business на том же устройстве с другим номером. Отлично подходит для разделения личного WhatsApp — установите WhatsApp Business и зарегистрируйте номер OpenClaw там.

Пример конфигурации (выделенный номер, белый список для одного пользователя):

{
  channels: {
    whatsapp: {
      dmPolicy: "allowlist",
      allowFrom: ["+15551234567"]
    }
  }
}

Режим сопряжения (опционально): Если вы хотите сопряжение вместо белого списка, установите channels.whatsapp.dmPolicy в pairing. Неизвестные отправители получают код сопряжения; одобрите с помощью: openclaw pairing approve whatsapp <code>

Личный номер (запасной вариант)

Быстрый запасной вариант: запустите OpenClaw на вашем собственном номере. Отправляйте сообщения себе (WhatsApp "Отправить себе") для тестирования, чтобы не спамить контакты. Ожидайте чтения кодов верификации на вашем основном телефоне во время настройки и экспериментов. Необходимо включить режим самостоятельного чата. Когда мастер запрашивает ваш личный номер WhatsApp, введите телефон, с которого вы будете отправлять сообщения (владелец/отправитель), а не номер ассистента.

Пример конфигурации (личный номер, самостоятельный чат):

{
  "whatsapp": {
    "selfChatMode": true,
    "dmPolicy": "allowlist",
    "allowFrom": ["+15551234567"]
  }
}

Ответы в самостоятельном чате по умолчанию используют [{identity.name}], если установлено (иначе [openclaw]), если messages.responsePrefix не задан. Установите его явно для настройки или отключения префикса (используйте "" для удаления).

Советы по выбору номера

  • Локальная eSIM от оператора мобильной связи вашей страны (наиболее надёжно)
    • Австрия: hot.at
    • Великобритания: giffgaff — бесплатная SIM-карта, без контракта
  • Предоплаченная SIM-карта — дёшево, нужна только для получения одного SMS для верификации

Избегайте: TextNow, Google Voice, большинство сервисов "бесплатных SMS" — WhatsApp агрессивно блокирует их.

Совет: Номер нужен только для получения одного SMS верификации. После этого сессии WhatsApp Web сохраняются через creds.json.

Почему не Twilio?

  • Ранние сборки OpenClaw поддерживали интеграцию Twilio WhatsApp Business.
  • Бизнес-номера WhatsApp плохо подходят для личного ассистента.
  • Meta применяет 24-часовое окно ответа; если вы не ответили за последние 24 часа, бизнес-номер не может инициировать новые сообщения.
  • Высокая активность или "болтливое" использование вызывает агрессивную блокировку, потому что бизнес-аккаунты не предназначены для отправки десятков сообщений личного ассистента.
  • Результат: ненадёжная доставка и частые блокировки, поэтому поддержка была удалена.

Логин + учётные данные

  • Команда логина: openclaw channels login (QR через Связанные устройства).
  • Логин для нескольких аккаунтов: openclaw channels login --account <id> (<id> = accountId).
  • Аккаунт по умолчанию (когда --account опущен): default если присутствует, иначе первый настроенный id аккаунта (отсортированный).
  • Учётные данные хранятся в ~/.openclaw/credentials/whatsapp/<accountId>/creds.json.
  • Резервная копия в creds.json.bak (восстанавливается при повреждении).
  • Совместимость со старыми версиями: более старые установки хранили файлы Baileys непосредственно в ~/.openclaw/credentials/.
  • Выход: openclaw channels logout (или --account <id>) удаляет состояние аутентификации WhatsApp (но сохраняет общий oauth.json).
  • Вышедший из системы сокет => ошибка инструктирует повторно привязать.

Входящий поток (личные сообщения + группы)

  • События WhatsApp приходят из messages.upsert (Baileys).
  • Слушатели входящих сообщений отключаются при остановке, чтобы избежать накопления обработчиков событий в тестах/перезапусках.
  • Статусные/broadcast чаты игнорируются.
  • Прямые чаты используют E.164; группы используют group JID.
  • Политика личных сообщений: channels.whatsapp.dmPolicy контролирует доступ к прямым чатам (по умолчанию: pairing).
    • Сопряжение: неизвестные отправители получают код сопряжения (одобрите через openclaw pairing approve whatsapp <code>; коды истекают через 1 час).
    • Открыто: требуется, чтобы channels.whatsapp.allowFrom включал "*".
    • Ваш привязанный номер WhatsApp неявно доверенный, поэтому сообщения себе пропускают проверки ⁠channels.whatsapp.dmPolicy и channels.whatsapp.allowFrom.

Режим личного номера (запасной)

Если вы запускаете OpenClaw на вашем личном номере WhatsApp, включите channels.whatsapp.selfChatMode (см. пример выше).

Поведение:

  • Исходящие личные сообщения никогда не вызывают ответы сопряжения (предотвращает спам контактам).
  • Входящие неизвестные отправители всё ещё следуют channels.whatsapp.dmPolicy.
  • Режим самостоятельного чата (allowFrom включает ваш номер) избегает авточтения и игнорирует JID упоминаний.
  • Отчёты о прочтении отправляются для личных сообщений не в режиме самостоятельного чата.

Отчёты о прочтении

По умолчанию шлюз отмечает входящие сообщения WhatsApp как прочитанные (синие галочки) после их принятия.

Отключить глобально:

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

Отключить для конкретного аккаунта:

{
  channels: {
    whatsapp: {
      accounts: {
        personal: { sendReadReceipts: false }
      }
    }
  }
}

Примечания:

  • Режим самостоятельного чата всегда пропускает отчёты о прочтении.

FAQ WhatsApp: отправка сообщений + сопряжение

Будет ли OpenClaw отправлять сообщения случайным контактам при привязке WhatsApp?
Нет. Политика личных сообщений по умолчанию — сопряжение, поэтому неизвестные отправители получают только код сопряжения, и их сообщение не обрабатывается. OpenClaw отвечает только на чаты, которые он получает, или на отправки, которые вы явно инициируете (агент/CLI).

Как работает сопряжение в WhatsApp?
Сопряжение — это шлюз для личных сообщений для неизвестных отправителей:

  • Первое личное сообщение от нового отправителя возвращает короткий код (сообщение не обрабатывается).
  • Одобрите с помощью: openclaw pairing approve whatsapp <code> (список с openclaw pairing list whatsapp).
  • Коды истекают через 1 час; ожидающие запросы ограничены 3 на канал.

Могут ли несколько человек использовать разные экземпляры OpenClaw на одном номере WhatsApp?
Да, маршрутизируя каждого отправителя к разному агенту через bindings (peer kind: "dm", отправитель E.164 как +15551234567). Ответы всё ещё приходят от того же аккаунта WhatsApp, и прямые чаты сворачиваются к основной сессии каждого агента, поэтому используйте один агент на человека. Контроль доступа личных сообщений (dmPolicy/allowFrom) глобален для каждого аккаунта WhatsApp. См. Multi-Agent Routing.

Почему вы запрашиваете мой номер телефона в мастере?
Мастер использует его для установки вашего белого списка/владельца, чтобы ваши собственные личные сообщения были разрешены. Он не используется для автоматической отправки. Если вы запускаете на вашем личном номере WhatsApp, используйте тот же номер и включите channels.whatsapp.selfChatMode.

Нормализация сообщений (что видит модель)

  • Body — это текущее тело сообщения с конвертом.
  • Контекст цитируемого ответа всегда добавляется:
    [Replying to +1555 id:ABC123]
    <quoted text or <media:...>>
    [/Replying]
    
  • Метаданные ответа также устанавливаются:
    • ReplyToId = stanzaId
    • ReplyToBody = цитируемое тело или заполнитель медиа
    • ReplyToSender = E.164 когда известен
  • Входящие сообщения только с медиа используют заполнители:
    • <media:image|video|audio|document|sticker>

Группы

  • Группы сопоставляются с сессиями agent:<agentId>:whatsapp:group:<jid>.
  • Политика групп: channels.whatsapp.groupPolicy = open|disabled|allowlist (по умолчанию allowlist).
  • Режимы активации:
    • mention (по умолчанию): требуется @упоминание или совпадение регулярного выражения.
    • always: всегда срабатывает.
  • /activation mention|always только для владельца и должен быть отправлен как отдельное сообщение.
  • Владелец = channels.whatsapp.allowFrom (или self E.164 если не задан).
  • Инъекция истории (только для ожидающих):
    • Последние необработанные сообщения (по умолчанию 50) вставляются под: [Chat messages since your last reply - for context] (сообщения уже в сессии не вставляются повторно)
    • Текущее сообщение под: [Current message - respond to this]
    • Суффикс отправителя добавляется: [from: Name (+E164)]
  • Метаданные группы кэшируются 5 мин (тема + участники).

Доставка ответов (цепочки)

  • WhatsApp Web отправляет стандартные сообщения (нет цитирования ответов в текущем шлюзе).
  • Теги ответов игнорируются на этом канале.

Реакции подтверждения (автоматическая реакция при получении)

WhatsApp может автоматически отправлять эмодзи-реакции на входящие сообщения сразу после получения, до того как бот сгенерирует ответ. Это обеспечивает мгновенную обратную связь пользователям о том, что их сообщение получено.

Конфигурация:

{
  "whatsapp": {
    "ackReaction": {
      "emoji": "👀",
      "direct": true,
      "group": "mentions"
    }
  }
}

Опции:

  • emoji (строка): Эмодзи для подтверждения (например, "👀", "✅", "📨"). Пусто или опущено = функция отключена.
  • direct (логическое, по умолчанию: true): Отправлять реакции в прямых/личных чатах.
  • group (строка, по умолчанию: "mentions"): Поведение в групповых чатах:
    • "always": Реагировать на все групповые сообщения (даже без @упоминания)
    • "mentions": Реагировать только когда бот @упомянут
    • "never": Никогда не реагировать в группах

Переопределение для конкретного аккаунта:

{
  "whatsapp": {
    "accounts": {
      "work": {
        "ackReaction": {
          "emoji": "✅",
          "direct": false,
          "group": "always"
        }
      }
    }
  }
}

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

  • Реакции отправляются немедленно при получении сообщения, до индикаторов печати или ответов бота.
  • В группах с requireMention: false (активация: всегда), group: "mentions" будет реагировать на все сообщения (не только @упоминания).
  • Fire-and-forget: сбои реакций логируются, но не препятствуют боту отвечать.
  • JID участника автоматически включается для групповых реакций.
  • WhatsApp игнорирует messages.ackReaction; используйте channels.whatsapp.ackReaction.

Инструмент агента (реакции)

  • Инструмент: whatsapp с действием react (chatJid, messageId, emoji, опционально remove).
  • Опционально: participant (отправитель группы), fromMe (реагирование на ваше собственное сообщение), accountId (мульти-аккаунт).
  • Семантика удаления реакции: см. /tools/reactions.
  • Управление инструментом: channels.whatsapp.actions.reactions (по умолчанию: включено).

Ограничения

  • Исходящий текст разбивается на channels.whatsapp.textChunkLimit (по умолчанию 4000).
  • Опциональное разбиение по новой строке: установите channels.whatsapp.chunkMode="newline" для разделения по пустым строкам (границы абзацев) перед разбиением по длине.
  • Сохранение входящих медиа ограничено channels.whatsapp.mediaMaxMb (по умолчанию 50 МБ).
  • Элементы исходящих медиа ограничены agents.defaults.mediaMaxMb (по умолчанию 5 МБ).

Исходящая отправка (текст + медиа)

  • Использует активный веб-слушатель; ошибка если шлюз не запущен.
  • Разбиение текста: максимум 4k на сообщение (настраивается через channels.whatsapp.textChunkLimit, опционально channels.whatsapp.chunkMode).
  • Медиа:
    • Поддерживаются изображение/видео/аудио/документ.
    • Аудио отправляется как PTT; audio/ogg => audio/ogg; codecs=opus.
    • Подпись только к первому медиа элементу.
    • Получение медиа поддерживает HTTP(S) и локальные пути.
    • Анимированные GIF: WhatsApp ожидает MP4 с gifPlayback: true для inline зацикливания.
      • CLI: openclaw message send --media <mp4> --gif-playback
      • Шлюз: параметры send включают gifPlayback: true

Голосовые заметки (PTT аудио)

WhatsApp отправляет аудио как голосовые заметки (PTT пузырь).

  • Лучшие результаты: OGG/Opus. OpenClaw переписывает audio/ogg в audio/ogg; codecs=opus.
  • [[audio_as_voice]] игнорируется для WhatsApp (аудио уже отправляется как голосовая заметка).

Ограничения медиа + оптимизация

  • Ограничение исходящих по умолчанию: 5 МБ (на медиа элемент).
  • Переопределение: agents.defaults.mediaMaxMb.
  • Изображения автоматически оптимизируются в JPEG под ограничение (изменение размера + настройка качества).
  • Слишком большие медиа => ошибка; ответ с медиа возвращается к текстовому предупреждению.

Сердцебиения

  • Сердцебиение шлюза логирует здоровье подключения (web.heartbeatSeconds, по умолчанию 60с).
  • Сердцебиение агента может быть настроено для каждого агента (agents.list[].heartbeat) или глобально через agents.defaults.heartbeat (запасной вариант когда нет записей для конкретного агента).
    • Использует настроенную подсказку сердцебиения (по умолчанию: Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.) + поведение пропуска HEARTBEAT_OK.
    • Доставка по умолчанию на последний использованный канал (или настроенную цель).

Поведение переподключения

  • Политика отката: web.reconnect:
    • initialMs, maxMs, factor, jitter, maxAttempts.
  • Если maxAttempts достигнут, веб-мониторинг останавливается (деградировано).
  • Вышли из системы => остановка и требуется повторная привязка.

Быстрая карта конфигурации

  • channels.whatsapp.dmPolicy (политика личных сообщений: pairing/allowlist/open/disabled).
  • channels.whatsapp.selfChatMode (настройка на одном телефоне; бот использует ваш личный номер WhatsApp).
  • channels.whatsapp.allowFrom (белый список личных сообщений). WhatsApp использует телефонные номера E.164 (нет имён пользователей).
  • channels.whatsapp.mediaMaxMb (ограничение сохранения входящих медиа).
  • channels.whatsapp.ackReaction (автоматическая реакция при получении сообщения: {emoji, direct, group}).
  • channels.whatsapp.accounts.<accountId>.* (настройки для конкретного аккаунта + опциональный authDir).
  • channels.whatsapp.accounts.<accountId>.mediaMaxMb (ограничение входящих медиа для конкретного аккаунта).
  • channels.whatsapp.accounts.<accountId>.ackReaction (переопределение реакции подтверждения для конкретного аккаунта).
  • channels.whatsapp.groupAllowFrom (белый список отправителей группы).
  • channels.whatsapp.groupPolicy (политика группы).
  • channels.whatsapp.historyLimit / channels.whatsapp.accounts.<accountId>.historyLimit (контекст истории группы; 0 отключает).
  • channels.whatsapp.dmHistoryLimit (ограничение истории личных сообщений в пользовательских ходах). Переопределения для конкретного пользователя: channels.whatsapp.dms["<phone>"].historyLimit.
  • channels.whatsapp.groups (белый список группы + умолчания для упоминаний; используйте "*" чтобы разрешить все)
  • channels.whatsapp.actions.reactions (управление реакциями инструмента WhatsApp).
  • agents.list[].groupChat.mentionPatterns (или messages.groupChat.mentionPatterns)
  • messages.groupChat.historyLimit
  • channels.whatsapp.messagePrefix (префикс входящих; для конкретного аккаунта: channels.whatsapp.accounts.<accountId>.messagePrefix; устарело: messages.messagePrefix)
  • messages.responsePrefix (префикс исходящих)
  • agents.defaults.mediaMaxMb
  • agents.defaults.heartbeat.every
  • agents.defaults.heartbeat.model (опциональное переопределение)
  • agents.defaults.heartbeat.target
  • agents.defaults.heartbeat.to
  • agents.defaults.heartbeat.session
  • agents.list[].heartbeat.* (переопределения для конкретного агента)
  • session.* (scope, idle, store, mainKey)
  • web.enabled (отключить запуск канала когда false)
  • web.heartbeatSeconds
  • web.reconnect.*

Логи + устранение неполадок

  • Подсистемы: whatsapp/inbound, whatsapp/outbound, web-heartbeat, web-reconnect.
  • Файл логов: /tmp/openclaw/openclaw-YYYY-MM-DD.log (настраивается).
  • Руководство по устранению неполадок: Gateway troubleshooting.

Устранение неполадок (быстро)

Не привязан / требуется QR логин

  • Симптом: channels status показывает linked: false или предупреждает "Not linked".
  • Исправление: запустите openclaw channels login на хосте шлюза и отсканируйте QR (WhatsApp → Настройки → Связанные устройства).

Привязан, но отключен / цикл переподключения

  • Симптом: channels status показывает running, disconnected или предупреждает "Linked but disconnected".
  • Исправление: openclaw doctor (или перезапустите шлюз). Если сохраняется, повторно привяжите через channels login и проверьте openclaw logs --follow.

Среда выполнения Bun

  • Bun не рекомендуется. WhatsApp (Baileys) и Telegram ненадёжны на Bun. Запускайте шлюз с Node. (См. примечание о среде выполнения в Getting Started.)