A HookMyApp WhatsApp channel plugin for OpenClaw that delivers WhatsApp messages to your agent. Inbound messages are verified using HMAC-256 signatures (X-HookMyApp-Signature-256 header). Outbound replies are sent via the HookMyApp Meta Gateway Proxy for transparent token management and media signing.
openclaw plugins install clawhub:@gethookmyapp/openclaw-
Authenticate the CLI:
hookmyapp login
-
Verify you have at least one WhatsApp channel:
hookmyapp channels list
If none exist, create one at https://docs.hookmyapp.com.
-
Set up the plugin and write configuration:
openclaw hookmyapp-whatsapp setup --channel <ch_...> --write-config \ --allow-from +1234567890
Replace
+1234567890with the WhatsApp number of the person who should use the agent. -
Start the local transport tunnel:
hookmyapp channels listen <ch_...> --port <openclaw-gateway-port> --path /hookmyapp/webhook
Keep this running in a separate terminal. It provisions a Cloudflare Tunnel and pipes inbound webhooks to your OpenClaw gateway.
-
Send a test message from the allowlisted WhatsApp number to the channel's number and confirm the agent replies.
This plugin supports two webhook delivery modes:
Recommended for development and always-on local deployments. The HookMyApp CLI provisions a Cloudflare Tunnel on your behalf:
hookmyapp channels listen <ch_...> --port <openclaw-gateway-port> --path /hookmyapp/webhook- Port: Must match the OpenClaw gateway port (typically
18789or configured in openclaw config). - Path:
/hookmyapp/webhook(or/hookmyapp/webhook/<account-id>for named accounts). - Keep it running: Supported 24/7. The tunnel stays open as long as the command runs.
- HMAC: Signature verification works identically in both modes.
For production deployments or servers with public HTTPS:
openclaw hookmyapp-whatsapp setup --channel <ch_...> --write-config \
--webhook-url https://your-server.example.com/hookmyapp/webhook \
--register-webhook- Registration: The
--register-webhookflag callshookmyapp channels webhook setautomatically. - Manual registration: If you prefer to register separately:
hookmyapp channels webhook set <ch_...> --url https://your-server.example.com/hookmyapp/webhook
- HTTPS required: WebHook URLs must be HTTPS.
- HMAC: Signature verification works identically to the tunnel mode.
The plugin reads credentials from hookmyapp channels env <channel> and caches them in OpenClaw config. The following six environment variable names are pulled from the HookMyApp CLI:
| Name | Purpose | Required |
|---|---|---|
HOOKMYAPP_CHANNEL_ID |
HookMyApp channel public id (ch_...) | Yes |
META_GRAPH_API_URL |
Meta Graph API base URL | Yes |
WHATSAPP_ACCESS_TOKEN |
WhatsApp business account access token | Yes |
WHATSAPP_PHONE_NUMBER_ID |
WhatsApp phone number id (Meta resource) | Yes |
WEBHOOK_HMAC_SECRET |
HMAC signing secret for inbound webhooks | Yes |
VERIFY_TOKEN |
Subscription handshake ownership token (distinct from HMAC secret) | Yes |
Environment fallbacks (default account only):
The default account can also read from env vars if not present in config:
| Name | Purpose |
|---|---|
HOOKMYAPP_ALLOWED_USERS |
Comma-separated E.164 numbers (allowlist fallback) |
HOOKMYAPP_ALLOW_ALL_USERS |
Set to true to permit all senders (dev mode; overrides allowlist) |
HOOKMYAPP_DEFAULT_TO |
Default outbound target if not specified in the turn |
Named accounts (configured via --account <id>) do NOT read these env fallbacks; they must be fully configured in OpenClaw config.
- HMAC is mandatory: Every inbound webhook is verified against the X-HookMyApp-Signature-256 header. If the secret is missing, all deliveries are rejected with a 401.
- Verify Token ≠ HMAC secret: The Verify Token is a subscription ownership value used during webhook registration probes (X-HookMyApp-Probe header). The HMAC secret is the key used to sign delivered messages. They are two distinct values stored separately and never conflated.
- Allowlist is default-closed: Unless you pass
--allow-from <numbers>during setup or enable--dm-security open(development only), no senders are permitted. The agent will answer nobody until senders are explicitly allowlisted. - Secrets are marked sensitive: the three secret fields (
accessToken,webhookHmacSecret,verifyToken) are flagged sensitive in the plugin manifest, so OpenClaw masks them in config displays and exports. Non-secret fields (phone number id, allowlist, channel id) are visible config.
Inbound media (images, audio, video, documents, stickers) are resolved by the HookMyApp Meta Gateway Proxy:
- Inbound resolution: Media IDs in the inbound webhook are transparently resolved to short-lived signed URLs and downloaded immediately by the plugin.
- Download limit: 16 MB per file.
- Download failure: If fetching a media URL fails, the message degrades to text-only (media is dropped) and the failure is logged. The agent receives the text content and can process normally.
- Audio transcription: Not provided by this plugin in v1 — voice notes are attached as audio files; transcription is up to whatever tooling your agent runtime provides.
Run a full health check:
openclaw hookmyapp-whatsapp doctorOr machine-readable output:
openclaw hookmyapp-whatsapp doctor --jsonChecks:
config— whether OpenClaw config is presentaccessToken— whether the WhatsApp access token is availablewebhookHmacSecret— whether the HMAC secret is available (missing = all deliveries rejected)verifyToken— whether the Verify Token is available (missing = webhook registration probes fail)webhookRegistration— whether HookMyApp reports the webhook as registered
- Local transport terminal: Run
hookmyapp channels listen ...in a terminal and watch for delivery logs (check for 401 errors, which indicate HMAC mismatch). - HookMyApp Deliveries panel: Log into HookMyApp and navigate to the channel's Deliveries section to see inbound webhooks, forwarded requests, and app responses.
doctor reports the default account unless you pass --account <id>:
openclaw hookmyapp-whatsapp doctor --account work --json | jq '.checks'main is staging — every push runs CI (build, tests, pack dry-run). Pushing a
v* tag is production: CI re-runs, then the package is published to npm with
provenance. ClawHub publish (clawhub package publish @gethookmyapp/openclaw)
is a separate manual step after the npm release.
- OpenClaw: 2026.7.1-2 or compatible (pluginApi ≥ 2026.7.1-2)
- Node.js: ≥ 20
MIT