twilio-whatsapp
WhatsApp Business: template messages, session messages, media, webhooks, opt-in management
What this skill does
# twilio-whatsapp
## Purpose
Enable OpenClaw to implement and operate Twilio WhatsApp Business messaging in production:
- Send **template messages** (pre-approved) and **session messages** (24-hour customer care window).
- Attach **media** (images/docs/audio) with correct MIME types and size constraints.
- Receive and validate **webhooks** (incoming messages + message status callbacks).
- Implement **opt-in/opt-out** and compliance controls (STOP handling, consent logging, regional constraints).
- Operate reliably under Twilio production constraints: rate limits, retries, idempotency, error codes, and cost controls via Messaging Services.
Concrete value to an engineer: ship a WhatsApp messaging subsystem that is observable, compliant, resilient to webhook retries, and safe to run at scale with predictable failure modes.
---
## Prerequisites
### Accounts & Twilio-side setup
- Twilio account with WhatsApp sender enabled:
- Either **Twilio Sandbox for WhatsApp** (dev only) or a **WhatsApp Business Profile** connected to Twilio (prod).
- A Twilio **Messaging Service** (recommended for production) with:
- WhatsApp sender(s) attached (e.g., `whatsapp:+14155238886` or your approved WA number).
- Status callback URL configured (optional but recommended).
- WhatsApp templates approved in Meta Business Manager (via Twilio Console template manager).
### Local tooling versions (pinned)
- Node.js **20.11.1** (LTS) or **18.19.1** (LTS)
- Python **3.11.8** or **3.12.2**
- Twilio helper libraries:
- `twilio` (Node) **4.23.0**
- `twilio` (Python) **9.0.5**
- Twilio CLI **5.16.0** (for diagnostics; not required at runtime)
- ngrok **3.13.1** (local webhook testing)
### Auth & secrets
Use one of:
1. **API Key (recommended)**:
- `TWILIO_API_KEY_SID` (starts with `SK...`)
- `TWILIO_API_KEY_SECRET`
- `TWILIO_ACCOUNT_SID` (starts with `AC...`)
2. **Account SID + Auth Token**:
- `TWILIO_ACCOUNT_SID`
- `TWILIO_AUTH_TOKEN`
Store secrets in:
- Kubernetes: `Secret` + mounted env vars
- AWS: Secrets Manager + IRSA
- GCP: Secret Manager + Workload Identity
- Local dev: `.env` (never commit)
### Network & webhook requirements
- Public HTTPS endpoint for webhooks (Twilio requires HTTPS in most production contexts).
- Allow inbound from Twilio webhook IPs is not stable; validate using **X-Twilio-Signature** instead of IP allowlists.
- Ensure your endpoint can handle retries and out-of-order delivery.
---
## Core Concepts
### WhatsApp message types (Twilio perspective)
1. **Template message** (outside 24-hour window):
- Must use a pre-approved template.
- Used for notifications, OTP, shipping updates, etc.
- In Twilio, templates are typically sent via the **Content API** (preferred) or via template integration depending on account configuration.
2. **Session message** (inside 24-hour window):
- Free-form text/media allowed (subject to WhatsApp policies).
- The 24-hour window starts when the user messages you.
3. **Media message**:
- WhatsApp supports images, documents, audio, video with constraints.
- Twilio sends media via `MediaUrl` (publicly accessible URL) or via Twilio-hosted media in some flows.
### Identifiers and addressing
- WhatsApp addresses in Twilio use `whatsapp:` prefix:
- `From`: `whatsapp:+14155238886`
- `To`: `whatsapp:+14155550123`
- Messaging Service SID: `MGxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`
- Message SID: `SMxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`
### Webhooks
Two primary webhook categories:
1. **Incoming message webhook** (when user sends you a message):
- Twilio sends an HTTP request with form-encoded parameters like `From`, `To`, `Body`, `NumMedia`, `MediaUrl0`, etc.
2. **Message status callback** (delivery lifecycle):
- Status values: `queued`, `sent`, `delivered`, `read`, `failed`, `undelivered`
- Twilio retries on non-2xx responses with backoff.
### Idempotency and retries
- Twilio may retry webhooks; your handler must be idempotent.
- Status callbacks can arrive out of order (e.g., `delivered` then `read`, or `failed` after transient states).
- Use `MessageSid` + `MessageStatus` + timestamp to dedupe.
### Compliance: opt-in/opt-out
- WhatsApp requires user opt-in; you must store consent evidence.
- STOP handling:
- For SMS, Twilio has built-in STOP.
- For WhatsApp, you must implement opt-out keywords and respect them (e.g., “STOP”, “UNSUBSCRIBE”).
- Maintain a suppression list keyed by E.164 phone number.
---
## Installation & Setup
### Official Python SDK — WhatsApp
**Repository:** https://github.com/twilio/twilio-python
**PyPI:** `pip install twilio` · **Supported:** Python 3.7–3.13
```python
from twilio.rest import Client
client = Client()
# Send WhatsApp message (Sandbox: from_ = 'whatsapp:+14155238886')
msg = client.messages.create(
body="Your order is confirmed!",
from_="whatsapp:+14155238886",
to="whatsapp:+15558675309"
)
# Send template message (approved HSM)
msg = client.messages.create(
from_="whatsapp:+14155238886",
to="whatsapp:+15558675309",
content_sid="HX...", # pre-approved template SID
content_variables='{"1":"Alice","2":"12345"}'
)
```
Source: [twilio/twilio-python — messages](https://github.com/twilio/twilio-python/blob/main/twilio/rest/api/v2010/account/message/__init__.py)
### Ubuntu 22.04 LTS (x86_64)
```bash
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg jq
```
Node.js 20.11.1 via NodeSource:
```bash
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
node -v
npm -v
```
Python 3.11:
```bash
sudo apt-get install -y python3.11 python3.11-venv python3-pip
python3.11 --version
```
Twilio CLI 5.16.0:
```bash
npm install -g [email protected]
twilio --version
```
ngrok 3.13.1:
```bash
curl -s https://ngrok-agent.s3.amazonaws.com/ngrok.asc \
| sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null
echo "deb https://ngrok-agent.s3.amazonaws.com buster main" \
| sudo tee /etc/apt/sources.list.d/ngrok.list
sudo apt-get update && sudo apt-get install -y ngrok
ngrok version
```
### Fedora 39 (x86_64)
```bash
sudo dnf install -y curl jq nodejs python3 python3-virtualenv
node -v
python3 --version
```
Twilio CLI:
```bash
sudo npm install -g [email protected]
twilio --version
```
ngrok:
```bash
sudo dnf install -y ngrok
ngrok version
```
### macOS 14 (Sonoma) — Intel + Apple Silicon
Homebrew:
```bash
brew update
brew install node@20 [email protected] jq ngrok/ngrok/ngrok
node -v
python3 --version
ngrok version
```
Twilio CLI:
```bash
npm install -g [email protected]
twilio --version
```
### Auth setup (CLI + env)
Twilio CLI login (writes to `~/.twilio-cli/config.json`):
```bash
twilio login
```
Runtime env vars (recommended: API Key):
```bash
export TWILIO_ACCOUNT_SID="AC2f7b9c2b0f1d2e3a4b5c6d7e8f9a0b1"
export TWILIO_API_KEY_SID="SK3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8"
export TWILIO_API_KEY_SECRET="a_very_long_secret_value"
export TWILIO_MESSAGING_SERVICE_SID="MG0c3d2e1f4a5b6c7d8e9f0a1b2c3d4e5"
```
Local `.env` (example path: `/srv/whatsapp/.env`):
```dotenv
TWILIO_ACCOUNT_SID=AC2f7b9c2b0f1d2e3a4b5c6d7e8f9a0b1
TWILIO_API_KEY_SID=SK3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8
TWILIO_API_KEY_SECRET=a_very_long_secret_value
TWILIO_MESSAGING_SERVICE_SID=MG0c3d2e1f4a5b6c7d8e9f0a1b2c3d4e5
PUBLIC_BASE_URL=https://wa.example.com
```
---
## Key Capabilities
### Send session messages (text + media)
- Use Twilio Programmable Messaging `Messages` API.
- Ensure `To` and `From` include `whatsapp:` prefix.
- Prefer `MessagingServiceSid` over hardcoding `From` for routing and future sender expansion.
Node (twilio 4.23.0):
```javascript
import twilio from "twilio";
const client = twilio(
process.env.TWILIO_API_KEY_SID,
process.env.TWILIO_API_KEY_SECRET,
{ accountSid: process.env.TWILIO_ACCOUNT_SID }
);
export async function sendSessionText(toE164, body) {
const msg = await client.messages.create({
to: `whatsapp:${toE164}`,
messagingRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.