---
name: "whatsapp_agent_automation"
description: "Run business messaging on WhatsApp for an agent: send via Meta's Cloud API, manage approved message templates, track the 24h customer service window, keep an opt-in ledger, and run compliant campaigns. Triggers when the user needs WhatsApp business messaging, templates, opt-in/opt-out handling, or campaign deliverability."
metadata: { "includeInPrompt": true }
---

# WhatsApp Agent Automation

## Purpose
Operate WhatsApp Business Platform messaging from an agent without a BSP middleman: direct Cloud API sends, pre-approved templates, a per-contact opt-in ledger, automatic 24-hour window tracking, and throttled campaign sends that keep the number's quality rating green. Covers setup through campaign ops and deliverability.

## Workflow
1. **Decide the route.** Meta's Cloud API (self-serve, free platform, you build the UI) vs a BSP (Wati, Interakt, AiSensy: managed inbox + builders, platform fees). Agents that automate usually take direct Cloud API: a Meta app of type Business with the WhatsApp product, then a Phone Number ID and access token from WhatsApp > API Setup. Production uses a permanent System User token, never the temp setup token. A number already on the WhatsApp mobile app must be permanently deleted there before migrating to the API.
2. **Wire the webhook.** Callback URL + your own verify token in WhatsApp > Configuration, subscribe to the `messages` field. GET answers the `hub.challenge` handshake; POST checks `X-Hub-Signature-256` HMAC against the app secret, acks 200 immediately, then processes. Parse inbound messages and status updates (`sent` -> `delivered` -> `read` / `failed`) from the payload; dedupe by message id. See `references/webhooks.md`.
3. **Register opt-ins before any outbound.** There is no consent field in the API: Meta enforces consent after the fact through quality rating and bans. Record every contact's opt-in with `wapp optin`: exact consent wording, timestamp, source channel, message-type permission. Never import a cold list; re-permission old lists with one confirmation request and keep only the yes replies. Wire inbound webhooks to `wapp inbound` so STOP/UNSUBSCRIBE/CANCEL keywords auto-withdraw consent.
4. **Get templates approved.** Every business-initiated message outside the 24h window must be a pre-approved template, categorized Marketing / Utility / Authentication. Submit from WhatsApp Manager; review runs minutes to a day or two. Rules in `references/templates.md`. Until approval, the flow cannot start cold.
5. **Send with window awareness.** A user message opens a 24-hour customer service window: free-form replies allowed, each new user message resets it. Check `wapp can-send --wa-id` before choosing free-form vs template. For campaigns, use `wapp campaign` with a CSV of opted-in contacts; it skips non-opted-in rows and throttles to the rate you set. Keep interactive buttons in templates: quick-reply buttons reopen the free window faster than waiting on free text.
6. **Watch quality and cost.** The number carries a green/yellow/red quality rating from block and report rates; low ratings cut the messaging ladder (250 -> 2,000 -> 10,000 -> 100,000 -> unlimited unique recipients per 24h, per business portfolio since Oct 2025). Billing is per delivered template message by category and country since July 1, 2025; service replies have 1,000 free per number per month, then bill at utility rate from Oct 1, 2026. Details in `references/billing.md`.

## Output Contract
- A send is either delivered via `POST https://graph.facebook.com/{api-version}/{phone-number-id}/messages` with a returned `wamid`, or a dry-run payload the caller can inspect.
- Every outbound contact has an opt-in record (source + timestamp + consent copy) in the ledger; opt-outs stay on the record as proof of stopping.
- Every campaign logs rows sent, rows skipped (with reason), template name, and timestamp.
- No contact is ever messaged without a valid opt-in, and no free-form text goes out when the 24h window is closed.

## Operating Rules
1. Consent first, always. If a contact has no opt-in record, do not send: build the opt-in, then the message.
2. Template-only outside the window. Free-form only when `can-send` says the window is open.
3. One topic and one CTA per template; never hide promotional copy in template variables; classify marketing as marketing.
4. Honor opt-outs on the same interaction they arrive: keyword match, withdraw consent, confirm back, stop all templates to that contact.
5. Keep sends spaced: stay far under the 80 msg/sec per-number ceiling; per-campaign throttling defaults to 2/sec.
6. Live sends require `WAPP_TOKEN` and `WAPP_PHONE_NUMBER_ID` env vars and explicit `--live`; credentials never go in files or the ledger.
7. Meta's policies and rates change: verify pricing and policy against Meta's WhatsApp docs before committing to a high-volume plan.
