WhatsApp (Webkanaal)

Status: productieklaar via WhatsApp Web (Baileys). De gateway beheert gekoppelde sessie(s).

Snelle installatie

Stap 1: Configureer WhatsApp-toegangsbeleid

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

Stap 2: Koppel WhatsApp (QR)

openclaw channels login --channel whatsapp
Voor een specifiek account:
openclaw channels login --channel whatsapp --account work

Stap 3: Start de gateway

openclaw gateway

Stap 4: Keur het eerste koppelingsverzoek goed (bij gebruik van koppelingsmodus)

openclaw pairing list whatsapp
openclaw pairing approve whatsapp <CODE>
Koppelingsverzoeken verlopen na 1 uur. Openstaande verzoeken zijn beperkt tot 3 per kanaal.

Opmerking: OpenClaw raadt aan WhatsApp op een apart nummer te draaien wanneer mogelijk. (De kanaalmetadata en onboarding-flow zijn hiervoor geoptimaliseerd, maar persoonlijk-nummer-opstellingen worden ook ondersteund.)

Implementatiepatronen

Toegewijd nummer (aanbevolen)
Dit is de schoonste operationele modus:

- aparte WhatsApp-identiteit voor OpenClaw
- duidelijkere DM-allowlists en routeringsgrenzen
- minder kans op zelfchat-verwarring

Minimaal beleidspatroon:

```json5
{
  channels: {
    whatsapp: {
      dmPolicy: "allowlist",
      allowFrom: ["+15551234567"],
    },
  },
}
```
Persoonlijk-nummer-terugval
Onboarding ondersteunt persoonlijk-nummer-modus en schrijft een zelfchat-vriendelijke basislijn:

- `dmPolicy: "allowlist"`
- `allowFrom` bevat je persoonlijke nummer
- `selfChatMode: true`

Tijdens runtime baseren zelfchat-beveiligingen zich op het gekoppelde eigen nummer en `allowFrom`.
WhatsApp Web-only kanaalbereik
Het berichtenplatformkanaal is WhatsApp Web-gebaseerd (`Baileys`) in de huidige OpenClaw-kanaalarchitectuur.

Er is geen apart Twilio WhatsApp-berichtenkanaal in het ingebouwde chatkanaalregister.

Runtimemodel

  • De gateway beheert de WhatsApp-socket en herverbindingslus.
  • Uitgaande berichten vereisen een actieve WhatsApp-luisteraar voor het doelaccount.
  • Status- en broadcastchats worden genegeerd (@status, @broadcast).
  • Directe chats gebruiken DM-sessieregels (session.dmScope; standaard main voegt DM’s samen in de agent-hoofdsessie).
  • Groepssessies zijn geïsoleerd (agent:<agentId>:whatsapp:group:<jid>).

Toegangscontrole en activering

DM-beleid

`channels.whatsapp.dmPolicy` beheert directe chattoegang:

- `pairing` (standaard)
- `allowlist`
- `open` (vereist dat `allowFrom` `"*"` bevat)
- `disabled`

`allowFrom` accepteert E.164-nummers (intern genormaliseerd).

Multi-account-overschrijving: `channels.whatsapp.accounts.<id>.dmPolicy` (en `allowFrom`) hebben voorrang boven kanaal-standaarden voor dat account.

Runtime-gedragsdetails:

- koppelingen worden opgeslagen in de kanaal-allowstore en samengevoegd met geconfigureerde `allowFrom`
- als er geen allowlist is geconfigureerd, wordt het gekoppelde eigen nummer standaard toegestaan
- uitgaande `fromMe` DM's worden nooit automatisch gekoppeld

Groepsbeleid + allowlists

Groepstoegang heeft twee lagen:

1. **Groepslidmaatschap-allowlist** (`channels.whatsapp.groups`)
   - als `groups` wordt weggelaten, komen alle groepen in aanmerking
   - als `groups` aanwezig is, fungeert het als groeps-allowlist (`"*"` toegestaan)

2. **Groepsafzenderbeleid** (`channels.whatsapp.groupPolicy` + `groupAllowFrom`)
   - `open`: afzender-allowlist overgeslagen
   - `allowlist`: afzender moet overeenkomen met `groupAllowFrom` (of `*`)
   - `disabled`: alle groepsinkomende berichten blokkeren

Afzender-allowlist-terugval:

- als `groupAllowFrom` niet is ingesteld, valt de runtime terug op `allowFrom` wanneer beschikbaar
- afzender-allowlists worden geëvalueerd vóór mention-/antwoordactivering

Opmerking: als er helemaal geen `channels.whatsapp`-blok bestaat, valt het runtime-groepsbeleid terug op `allowlist` (met een logwaarschuwing), zelfs als `channels.defaults.groupPolicy` is ingesteld.

Vermeldingen + /activering

Groepsantwoorden vereisen standaard een vermelding.

Vermeldingsdetectie omvat:

- expliciete WhatsApp-vermeldingen van de bot-identiteit
- geconfigureerde vermeldings-regexpatronen (`agents.list[].groupChat.mentionPatterns`, terugval `messages.groupChat.mentionPatterns`)
- impliciete antwoord-op-bot-detectie (antwoordafzender komt overeen met bot-identiteit)

Beveiligingsopmerking:

- citaat/antwoord voldoet alleen aan mention-gating; het verleent **geen** afzenderautorisatie
- met `groupPolicy: "allowlist"` worden niet-allowlisted afzenders nog steeds geblokkeerd, zelfs als ze antwoorden op het bericht van een allowlisted gebruiker

Sessieniveau-activeringscommando:

- `/activation mention`
- `/activation always`

`activation` werkt de sessiestatus bij (niet de globale configuratie). Het is eigenaarbeveiligd.

Persoonlijk-nummer- en zelfchatgedrag

Wanneer het gekoppelde eigen nummer ook in allowFrom staat, worden WhatsApp-zelfchat-beveiligingen geactiveerd:

  • leesbevestigingen overslaan voor zelfchat-beurten
  • mention-JID-autotrigger-gedrag negeren dat je anders zou pingen
  • als messages.responsePrefix niet is ingesteld, gebruiken zelfchat-antwoorden standaard [{identity.name}] of [openclaw]

Berichtnormalisatie en context

Inkomende envelop + antwoordcontext
Inkomende WhatsApp-berichten worden gewrapped in de gedeelde inkomende envelop.

Als een geciteerd antwoord bestaat, wordt context in deze vorm toegevoegd:

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

Antwoordmetadatavelden worden ook ingevuld wanneer beschikbaar (`ReplyToId`, `ReplyToBody`, `ReplyToSender`, afzender-JID/E.164).
Media-tijdelijke-aanduidingen en locatie-/contactextractie
Inkomende berichten met alleen media worden genormaliseerd met tijdelijke aanduidingen zoals:

- `<media:image>`
- `<media:video>`
- `<media:audio>`
- `<media:document>`
- `<media:sticker>`

Locatie- en contactpayloads worden genormaliseerd naar tekstuele context vóór routering.
Wachtende groepsgeschiedenisinjectie
Voor groepen kunnen onverwerkte berichten worden gebufferd en als context worden geïnjecteerd wanneer de bot uiteindelijk wordt getriggerd.

- standaardlimiet: `50`
- config: `channels.whatsapp.historyLimit`
- terugval: `messages.groupChat.historyLimit`
- `0` schakelt uit

Injectiemarkeringen:

- `[Chat messages since your last reply - for context]`
- `[Current message - respond to this]`
Leesbevestigingen
Leesbevestigingen zijn standaard ingeschakeld voor geaccepteerde inkomende WhatsApp-berichten.

Globaal uitschakelen:

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

Per-account-overschrijving:

```json5
{
  channels: {
    whatsapp: {
      accounts: {
        work: {
          sendReadReceipts: false,
        },
      },
    },
  },
}
```

Zelfchat-beurten slaan leesbevestigingen over, zelfs wanneer globaal ingeschakeld.

Aflevering, opsplitsing en media

Tekstopsplitsing
- standaard chunklimiet: `channels.whatsapp.textChunkLimit = 4000`
- `channels.whatsapp.chunkMode = "length" | "newline"`
- `newline`-modus geeft voorkeur aan alineagrenzen (lege regels), valt dan terug op lengte-veilige opsplitsing
Uitgaand mediagedrag
- ondersteunt beeld-, video-, audio- (PTT-voicenote) en documentpayloads
- `audio/ogg` wordt herschreven naar `audio/ogg; codecs=opus` voor voicenote-compatibiliteit
- geanimeerde GIF-weergave wordt ondersteund via `gifPlayback: true` bij videoverzendingen
- bijschriften worden toegepast op het eerste media-item bij het versturen van multi-media-antwoordpayloads
- mediabron kan HTTP(S), `file://` of lokale paden zijn
Mediagrootte-limieten en terugvalgedrag
- inkomende media-opslaglimiet: `channels.whatsapp.mediaMaxMb` (standaard `50`)
- uitgaande media-verzendlimiet: `channels.whatsapp.mediaMaxMb` (standaard `50`)
- per-account-overschrijvingen gebruiken `channels.whatsapp.accounts.<accountId>.mediaMaxMb`
- afbeeldingen worden automatisch geoptimaliseerd (formaat/kwaliteitsaanpassing) om binnen limieten te passen
- bij mediaverzendingsfout stuurt eerste-item-terugval een tekstwaarschuwing in plaats van het antwoord stilzwijgend te laten vallen

Bevestigingsreacties

WhatsApp ondersteunt onmiddellijke bevestigingsreacties bij inkomende ontvangst via channels.whatsapp.ackReaction.

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

Gedragsopmerkingen:

  • wordt onmiddellijk verzonden nadat inkomend bericht is geaccepteerd (vóór antwoord)
  • fouten worden gelogd maar blokkeren de normale antwoordaflevering niet
  • groepsmodus mentions reageert bij mention-getriggerde beurten; groepsactivering always fungeert als bypass voor deze controle
  • WhatsApp gebruikt channels.whatsapp.ackReaction (verouderd messages.ackReaction wordt hier niet gebruikt)

Multi-account en credentials

Accountselectie en standaarden
- account-ID's komen uit `channels.whatsapp.accounts`
- standaard accountselectie: `default` indien aanwezig, anders eerste geconfigureerde account-ID (gesorteerd)
- account-ID's worden intern genormaliseerd voor opzoeken
Credentialpaden en verouderde compatibiliteit
- huidig auth-pad: `~/.openclaw/credentials/whatsapp/<accountId>/creds.json`
- back-upbestand: `creds.json.bak`
- verouderde standaard auth in `~/.openclaw/credentials/` wordt nog herkend/gemigreerd voor standaard-account-flows
Uitloggedrag
`openclaw channels logout --channel whatsapp [--account <id>]` wist de WhatsApp-authstatus voor dat account.

In verouderde auth-mappen wordt `oauth.json` bewaard terwijl Baileys-authbestanden worden verwijderd.

Tools, acties en configschrijfacties

  • Agent-toolondersteuning omvat WhatsApp-reactieactie (react).
  • Actie-gates:
    • channels.whatsapp.actions.reactions
    • channels.whatsapp.actions.polls
  • Kanaalgeïnitieerde configschrijfacties zijn standaard ingeschakeld (uitschakelen via channels.whatsapp.configWrites=false).

Probleemoplossing

Niet gekoppeld (QR vereist)
Symptoom: kanaalstatus meldt niet gekoppeld.

Oplossing:

```bash
openclaw channels login --channel whatsapp
openclaw channels status
```
Gekoppeld maar niet verbonden / herverbindingslus
Symptoom: gekoppeld account met herhaalde verbroken verbindingen of herverbindingspogingen.

Oplossing:

```bash
openclaw doctor
openclaw logs --follow
```

Indien nodig, opnieuw koppelen met `channels login`.
Geen actieve luisteraar bij verzending
Uitgaande berichten falen snel wanneer er geen actieve gateway-luisteraar bestaat voor het doelaccount.

Zorg ervoor dat de gateway draait en het account is gekoppeld.
Groepsberichten onverwacht genegeerd
Controleer in deze volgorde:

- `groupPolicy`
- `groupAllowFrom` / `allowFrom`
- `groups` allowlist-vermeldingen
- mention-gating (`requireMention` + vermeldingspatronen)
- dubbele sleutels in `openclaw.json` (JSON5): latere vermeldingen overschrijven eerdere, dus houd een enkel `groupPolicy` per bereik
Bun-runtimewaarschuwing
WhatsApp-gateway-runtime moet Node gebruiken. Bun wordt als incompatibel gemarkeerd voor stabiele WhatsApp/Telegram-gatewaywerking.

Configuratiereferentie-verwijzingen

Primaire referentie:

Belangrijkste WhatsApp-velden:

  • toegang: dmPolicy, allowFrom, groupPolicy, groupAllowFrom, groups
  • aflevering: textChunkLimit, chunkMode, mediaMaxMb, sendReadReceipts, ackReaction
  • multi-account: accounts.<id>.enabled, accounts.<id>.authDir, account-niveau-overschrijvingen
  • operaties: configWrites, debounceMs, web.enabled, web.heartbeatSeconds, web.reconnect.*
  • sessiegedrag: session.dmScope, historyLimit, dmHistoryLimit, dms.<id>.historyLimit

Gerelateerd