Messaggi di gruppo (canale web WhatsApp)

Obiettivo: far sedere Clawd nei gruppi WhatsApp, svegliarlo solo quando viene chiamato, e mantenere quel thread separato dalla sessione DM personale.

Nota: agents.list[].groupChat.mentionPatterns e ora usato anche da Telegram/Discord/Slack/iMessage; questo documento si concentra sul comportamento specifico di WhatsApp. Per configurazioni multi-agent, imposta agents.list[].groupChat.mentionPatterns per agent (o usa messages.groupChat.mentionPatterns come fallback globale).

Cosa e implementato (2025-12-03)

  • Modalita di attivazione: mention (predefinita) o always. mention richiede un ping (menzioni WhatsApp reali tramite mentionedJids, pattern regex, o l’E.164 del bot ovunque nel testo). always sveglia l’agent a ogni messaggio ma dovrebbe rispondere solo quando puo aggiungere valore; altrimenti restituisce il token silenzioso NO_REPLY. I valori predefiniti si impostano nel config (channels.whatsapp.groups) e si possono sovrascrivere per gruppo tramite /activation. Quando channels.whatsapp.groups e impostato, funge anche da allowlist dei gruppi (includi "*" per consentire tutti).
  • Policy gruppi: channels.whatsapp.groupPolicy controlla se i messaggi di gruppo vengono accettati (open|disabled|allowlist). allowlist usa channels.whatsapp.groupAllowFrom (fallback: channels.whatsapp.allowFrom esplicito). Il valore predefinito e allowlist (bloccato finche non aggiungi mittenti).
  • Sessioni per gruppo: le chiavi di sessione hanno la forma agent:<agentId>:whatsapp:group:<jid> cosi comandi come /verbose on o /think high (inviati come messaggi autonomi) hanno scope limitato a quel gruppo; lo stato DM personale resta intatto. Gli heartbeat sono saltati per i thread di gruppo.
  • Iniezione di contesto: i messaggi di gruppo solo in sospeso (50 predefiniti) che non hanno attivato un’esecuzione vengono prefissati sotto [Chat messages since your last reply - for context], con la riga che ha attivato sotto [Current message - respond to this]. I messaggi gia nella sessione non vengono reiniettati.
  • Identificazione mittente: ogni batch di gruppo termina con [from: Nome Mittente (+E164)] cosi Pi sa chi sta parlando.
  • Effimeri/visualizza una volta: li scompattiamo prima di estrarre testo/menzioni, cosi i ping al loro interno attivano comunque.
  • System prompt di gruppo: al primo turno di una sessione di gruppo (e ogni volta che /activation cambia la modalita) iniettiamo un breve testo nel system prompt come 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. Se i metadati non sono disponibili diciamo comunque all’agent che e una chat di gruppo.

Esempio di configurazione (WhatsApp)

Aggiungi un blocco groupChat a ~/.openclaw/openclaw.json cosi i ping per nome visualizzato funzionano anche quando WhatsApp rimuove la @ visiva nel corpo del testo:

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

Note:

  • Le regex sono case-insensitive; coprono un ping con nome visualizzato come @openclaw e il numero grezzo con o senza +/spazi.
  • WhatsApp invia comunque menzioni canoniche tramite mentionedJids quando qualcuno tocca il contatto, quindi il fallback sul numero e raramente necessario ma e una rete di sicurezza utile.

Comando di attivazione (solo proprietario)

Usa il comando nella chat di gruppo:

  • /activation mention
  • /activation always

Solo il numero del proprietario (da channels.whatsapp.allowFrom, o l’E.164 del bot quando non impostato) puo cambiare questo. Invia /status come messaggio autonomo nel gruppo per vedere la modalita di attivazione corrente.

Come usarlo

  1. Aggiungi il tuo account WhatsApp (quello che esegue OpenClaw) al gruppo.
  2. Scrivi @openclaw ... (o includi il numero). Solo i mittenti in allowlist possono attivarlo a meno che tu non imposti groupPolicy: "open".
  3. Il prompt dell’agent includera il contesto recente del gruppo piu il marker finale [from: ...] cosi puo indirizzarsi alla persona giusta.
  4. Le direttive a livello di sessione (/verbose on, /think high, /new o /reset, /compact) si applicano solo alla sessione di quel gruppo; inviale come messaggi autonomi affinche vengano registrate. La tua sessione DM personale resta indipendente.

Test / verifica

  • Test manuale:
    • Invia un ping @openclaw nel gruppo e conferma una risposta che faccia riferimento al nome del mittente.
    • Invia un secondo ping e verifica che il blocco storico sia incluso e poi cancellato al turno successivo.
  • Controlla i log del gateway (esegui con --verbose) per vedere le voci inbound web message che mostrano from: <groupJid> e il suffisso [from: ...].

Considerazioni note

  • Gli heartbeat sono intenzionalmente saltati per i gruppi per evitare broadcast rumorosi.
  • La soppressione dell’eco usa la stringa batch combinata; se invii testo identico due volte senza menzioni, solo il primo otterra una risposta.
  • Le voci dello store di sessione appariranno come agent:<agentId>:whatsapp:group:<jid> nello store di sessione (~/.openclaw/agents/<agentId>/sessions/sessions.json per impostazione predefinita); una voce mancante significa solo che il gruppo non ha ancora attivato un’esecuzione.
  • Gli indicatori di digitazione nei gruppi seguono agents.defaults.typingMode (predefinito: message quando non menzionato).