Group messages (web provider)
Goal: let Clawd sit in WhatsApp groups, wake up only when pinged, and keep that thread separate from the personal DM session. Note:routing.groupChat.mentionPatterns is now used by Telegram/Discord/Slack/iMessage as well; this doc focuses on WhatsApp-specific behavior. For multi-agent setups, you can override per agent with routing.agents.<agentId>.mentionPatterns.
What’s implemented (2025-12-03)
- Activation modes:
mention(default) oralways.mentionrequires a ping (real WhatsApp @-mentions viamentionedJids, regex patterns, or the bot’s E.164 anywhere in the text).alwayswakes the agent on every message but it should reply only when it can add meaningful value; otherwise it returns the silent tokenNO_REPLY. Defaults can be set in config (whatsapp.groups) and overridden per group via/activation. Whenwhatsapp.groupsis set, it also acts as a group allowlist (include"*"to allow all). - Group policy:
whatsapp.groupPolicycontrols whether group messages are accepted (open|disabled|allowlist).allowlistuseswhatsapp.groupAllowFrom(fallback: explicitwhatsapp.allowFrom). - Per-group sessions: session keys look like
whatsapp:group:<jid>so commands such as/verbose onor/think high(sent as standalone messages) are scoped to that group; personal DM state is untouched. Heartbeats are skipped for group threads. - Context injection: last N (default 50) group messages are prefixed under
[Chat messages since your last reply - for context], with the triggering line under[Current message - respond to this]. - Sender surfacing: every group batch now ends with
[from: Sender Name (+E164)]so Pi knows who is speaking. - Ephemeral/view-once: we unwrap those before extracting text/mentions, so pings inside them still trigger.
- Group system prompt: on the first turn of a group session (and whenever
/activationchanges the mode) we inject a short blurb into the system prompt likeYou 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.If metadata isn’t available we still tell the agent it’s a group chat.
Config for Clawd UK (+447700900123)
Add agroupChat block to ~/.clawdbot/clawdbot.json so display-name pings work even when WhatsApp strips the visual @ in the text body:
- The regexes are case-insensitive; they cover
@clawd,@clawd uk,clawdbot, and the raw number with or without+/spaces. - WhatsApp still sends canonical mentions via
mentionedJidswhen someone taps the contact, so the number fallback is rarely needed but is a good safety net.
Activation command (owner-only)
Use the group chat command:/activation mention/activation always
whatsapp.allowFrom, or the bot’s own E.164 when unset) can change this. Send /status as a standalone message in the group to see the current activation mode.
How to use
- Add Clawd UK (
+447700900123) to the group. - Say
@clawd …(or@clawd uk,@clawdbot, or include the number). Anyone in the group can trigger it. - The agent prompt will include recent group context plus the trailing
[from: …]marker so it can address the right person. - Session-level directives (
/verbose on,/think high,/newor/reset,/compact) apply only to that group’s session; send them as standalone messages so they register. Your personal DM session remains independent.
Testing / verification
- Manual smoke:
- Send an
@clawdping in the group and confirm a reply that references the sender name. - Send a second ping and verify the history block is included then cleared on the next turn.
- Send an
- Check gateway logs (run with
--verbose) to seeinbound web messageentries showingfrom: <groupJid>and the[from: …]suffix.
Known considerations
- Heartbeats are intentionally skipped for groups to avoid noisy broadcasts.
- Echo suppression uses the combined batch string; if you send identical text twice without mentions, only the first will get a response.
- Session store entries will appear as
agent:<agentId>:whatsapp:group:<jid>in the session store (~/.clawdbot/agents/<agentId>/sessions/sessions.jsonby default); a missing entry just means the group hasn’t triggered a run yet. - Typing indicators in groups follow
agent.typingMode(default:messagewhen unmentioned).