Групповые сообщения (веб-канал WhatsApp)

Цель: позволить Clawd находиться в группах WhatsApp, просыпаться только при упоминании и держать этот тред отдельно от личной DM-сессии.

Примечание: agents.list[].groupChat.mentionPatterns теперь используется также Telegram/Discord/Slack/iMessage; этот документ фокусируется на поведении, специфичном для WhatsApp. Для мультиагентных настроек установите agents.list[].groupChat.mentionPatterns для каждого агента (или используйте messages.groupChat.mentionPatterns как глобальный откат).

Что реализовано (2025-12-03)

  • Режимы активации: mention (по умолчанию) или always. mention требует упоминания (реальные @-упоминания WhatsApp через mentionedJids, паттерны regex или E.164 бота где угодно в тексте). always пробуждает агента на каждом сообщении, но он должен отвечать только когда может добавить значимую ценность; иначе возвращает тихий токен NO_REPLY. Значения по умолчанию можно установить в конфигурации (channels.whatsapp.groups) и переопределить для группы через /activation. Когда установлен channels.whatsapp.groups, он также действует как allowlist групп (включите "*" для разрешения всех).
  • Политика групп: channels.whatsapp.groupPolicy контролирует, принимаются ли групповые сообщения (open|disabled|allowlist). allowlist использует channels.whatsapp.groupAllowFrom (откат: явный channels.whatsapp.allowFrom). По умолчанию allowlist (заблокировано, пока вы не добавите отправителей).
  • Сессии для каждой группы: ключи сессий выглядят как agent:<agentId>:whatsapp:group:<jid>, поэтому команды типа /verbose on или /think high (отправленные как отдельные сообщения) ограничены этой группой; личное DM-состояние не затрагивается. Heartbeat-опросы пропускаются для групповых тредов.
  • Внедрение контекста: групповые сообщения только ожидающие (по умолчанию 50), которые не вызвали запуск, добавляются под префиксом [Chat messages since your last reply - for context], с триггерной строкой под [Current message - respond to this]. Сообщения, уже находящиеся в сессии, не повторно внедряются.
  • Указание отправителя: каждый групповой пакет теперь заканчивается [from: Sender Name (+E164)], чтобы Pi знал, кто говорит.
  • Эфемерные/view-once: мы разворачиваем их перед извлечением текста/упоминаний, поэтому упоминания внутри них все равно срабатывают.
  • Системный промпт группы: на первом ходу групповой сессии (и всякий раз, когда /activation меняет режим) мы внедряем краткий блок в системный промпт типа You are replying inside the WhatsApp group "<subject>". Group members: Alice (+44...), Bob (+43...), … Activation: trigger-only … Address the specific sender noted in the message context. Если метаданные недоступны, мы все равно сообщаем агенту, что это групповой чат.

Пример конфигурации (WhatsApp)

Добавьте блок groupChat в ~/.openclaw/openclaw.json, чтобы упоминания по display-name работали, даже когда WhatsApp удаляет визуальный @ в теле текста:

{
  channels: {
    whatsapp: {
      groups: {
        "*": { requireMention: true }
      }
    }
  },
  agents: {
    list: [
      {
        id: "main",
        groupChat: {
          historyLimit: 50,
          mentionPatterns: [
            "@?openclaw",
            "\\+?15555550123"
          ]
        }
      }
    ]
  }
}

Примечания:

  • Regex нечувствительны к регистру; они покрывают упоминание display-name типа @openclaw и сырой номер с +/пробелами или без них.
  • WhatsApp все еще отправляет канонические упоминания через mentionedJids, когда кто-то нажимает контакт, поэтому резерв с номером редко нужен, но является полезной страховочной сетью.

Команда активации (только для владельца)

Используйте команду группового чата:

  • /activation mention
  • /activation always

Только номер владельца (из channels.whatsapp.allowFrom или собственный E.164 бота, когда не установлен) может изменить это. Отправьте /status как отдельное сообщение в группе, чтобы увидеть текущий режим активации.

Как использовать

  1. Добавьте свой аккаунт WhatsApp (тот, который запускает OpenClaw) в группу.
  2. Скажите @openclaw … (или включите номер). Только allowlist-отправители могут запустить его, если вы не установили groupPolicy: "open".
  3. Промпт агента будет включать недавний контекст группы плюс замыкающий маркер [from: …], чтобы он мог обратиться к нужному человеку.
  4. Директивы уровня сессии (/verbose on, /think high, /new или /reset, /compact) применяются только к сессии этой группы; отправляйте их как отдельные сообщения, чтобы они зарегистрировались. Ваша личная DM-сессия остается независимой.

Тестирование / проверка

  • Ручная проверка:
    • Отправьте упоминание @openclaw в группе и подтвердите ответ, который ссылается на имя отправителя.
    • Отправьте второе упоминание и проверьте, что блок истории включен, затем очищен на следующем ходу.
  • Проверьте логи gateway (запустите с --verbose), чтобы увидеть записи inbound web message, показывающие from: <groupJid> и суффикс [from: …].

Известные соображения

  • Heartbeat-опросы намеренно пропускаются для групп, чтобы избежать шумных трансляций.
  • Подавление эха использует комбинированную строку пакета; если вы отправите идентичный текст дважды без упоминаний, только первый получит ответ.
  • Записи хранилища сессий будут появляться как agent:<agentId>:whatsapp:group:<jid> в хранилище сессий (~/.openclaw/agents/<agentId>/sessions/sessions.json по умолчанию); отсутствующая запись просто означает, что группа еще не запустила запуск.
  • Индикаторы набора в группах следуют agents.defaults.typingMode (по умолчанию: message когда не упомянуты).