Claude
Skills
Sign in
Back

twilio-conversations

Included with Lifetime
$97 forever

Unified: omnichannel SMS+WhatsApp+chat, conversation/participant/message management, webhooks

Generalconversationsomnichanneltwilio

What this skill does


# twilio-conversations

## Purpose

Enable OpenClaw to implement and operate Twilio Conversations in production: create/manage conversations, participants, and messages across SMS/WhatsApp/chat; integrate webhooks for delivery/read/failure; enforce opt-out and compliance; and compose with Twilio Programmable Messaging/Voice/Verify/Studio/SendGrid patterns.

Concrete engineer value:

- Build a unified “thread” abstraction across channels (SMS, WhatsApp, in-app chat) with consistent participant/message APIs.
- Implement reliable webhook-driven state (delivery/read/failure) with idempotency, retries, and backpressure.
- Operate at scale: rate limits, pagination, cost controls (Messaging Services, geo-matching), and compliance (STOP, 10DLC, toll-free).
- Provide production-grade observability and incident response playbooks for Twilio error codes and webhook failures.

---

## Prerequisites

### Accounts & Twilio setup

- Twilio account with Conversations enabled.
- At least one of:
  - SMS-capable phone number (10DLC registered for US A2P where applicable)
  - WhatsApp sender (WhatsApp Business API via Twilio)
  - Messaging Service (recommended for scale/cost controls)
- Webhook endpoint reachable from Twilio (public HTTPS). For local dev: `ngrok` or `cloudflared`.

### Runtime versions (tested)

- Node.js: **20.11.1** (LTS)
- Python: **3.11.7**
- Twilio Node SDK: **4.23.0**
- Twilio Python SDK: **9.4.1**
- OpenSSL: **1.1.1w** or **3.0.13** (platform dependent)
- Docker: **25.0.3** (optional)
- PostgreSQL: **15.5** (optional, for webhook/event persistence)
- Redis: **7.2.4** (optional, for idempotency keys / rate limiting)

### OS support

- Ubuntu 22.04 LTS (x86_64, arm64)
- Fedora 39 (x86_64)
- macOS 14 Sonoma (Intel + Apple Silicon)

### Auth setup

Use Twilio API Key (recommended) instead of Account SID + Auth Token for production services.

1. Create API Key:
   - Twilio Console → Account → API keys & tokens → Create API key
2. Store:
   - `TWILIO_ACCOUNT_SID` (starts with `AC...`)
   - `TWILIO_API_KEY_SID` (starts with `SK...`)
   - `TWILIO_API_KEY_SECRET`

Environment variables (example):

```bash
export TWILIO_ACCOUNT_SID="YOUR_ACCOUNT_SID"
export TWILIO_API_KEY_SID="YOUR_API_KEY_SID"
export TWILIO_API_KEY_SECRET="YOUR_API_KEY_SECRET"
```

If you must use Auth Token (legacy):

```bash
export TWILIO_AUTH_TOKEN="your_auth_token"
```

### Network & firewall

- Allow outbound HTTPS to `api.twilio.com` and `conversations.twilio.com`.
- Inbound webhook endpoint must accept Twilio IP ranges (or validate signatures; prefer signature validation over IP allowlists).

---

## Core Concepts

### Conversations mental model

- **Conversation**: a thread container. Has a `sid` (`CH...`), `uniqueName`, attributes, timers, and state.
- **Participant**: an entity in a conversation. Types:
  - **Chat participant** (identity-based): `identity="user-123"`
  - **Messaging participant** (phone-based): `messagingBinding.address="+14155550100"` and `proxyAddress` (Twilio number or Messaging Service sender)
  - **WhatsApp participant**: address like `whatsapp:+14155550100`
- **Message**: content sent within a conversation. Has author, body, media, attributes, and delivery receipts (channel dependent).
- **Webhook events**: Twilio sends HTTP callbacks for conversation/message/participant lifecycle and delivery status.

### Architecture overview (production)

1. **Ingress**:
   - Inbound SMS/WhatsApp hits Programmable Messaging webhook.
   - In-app chat uses Conversations SDK (web/mobile) or REST API.
2. **Routing**:
   - Map inbound message to a Conversation (by phone number, identity, or business key).
   - Add/ensure participants.
3. **Egress**:
   - Send messages via Conversations API (preferred for unified thread) or Messaging API (for non-threaded blasts).
4. **State & observability**:
   - Persist webhook events (append-only) and derive state (delivery, read, failed).
   - Idempotency keys to handle Twilio retries.
5. **Compliance**:
   - STOP/START/HELP handling (Messaging compliance) and participant removal/blacklist.
   - 10DLC/toll-free verification for US traffic; WhatsApp template rules.

### Key identifiers

- Account SID: `AC...`
- Conversation SID: `CH...`
- Participant SID: `MB...` (varies)
- Message SID: `IM...`
- Service SID (Conversations Service): `IS...` (if using Services)
- Messaging Service SID: `MG...`

### Webhook signature validation

Twilio signs webhook requests with `X-Twilio-Signature`. Validate using the exact URL Twilio called (including query string) and the POST params.

---

## Installation & Setup

### Official Python SDK — Conversations

**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()

# Create conversation
conv = client.conversations.v1.conversations.create(
    friendly_name="Support Chat #123"
)

# Add participant (SMS)
p = client.conversations.v1.conversations(conv.sid) \
    .participants.create(
        messaging_binding_address="+15558675309",
        messaging_binding_proxy_address="+15017250604"
    )

# Send message
client.conversations.v1.conversations(conv.sid) \
    .messages.create(body="Welcome to support chat!", author="system")
```

Source: [twilio/twilio-python — conversations](https://github.com/twilio/twilio-python/blob/main/twilio/rest/conversations/)

### 1) System dependencies

#### Ubuntu 22.04

```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  # v20.11.1 (or newer 20.x)
npm -v
```

Python 3.11:

```bash
sudo apt-get install -y python3.11 python3.11-venv python3-pip
python3.11 --version
```

#### Fedora 39

```bash
sudo dnf install -y jq curl ca-certificates
sudo dnf module install -y nodejs:20
node -v
sudo dnf install -y python3.11 python3.11-pip
python3.11 --version
```

#### macOS 14 (Intel/Apple Silicon)

Homebrew:

```bash
brew update
brew install jq node@20 [email protected]
node -v
python3.11 --version
```

### 2) Project dependencies

#### Node (recommended for webhook services)

```bash
mkdir -p twilio-conversations-service && cd twilio-conversations-service
npm init -y
npm install [email protected] [email protected] [email protected] [email protected] [email protected]
npm install --save-dev [email protected] [email protected] @types/[email protected] @types/[email protected]
```

#### Python (batch jobs / admin tooling)

```bash
python3.11 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip==24.0
pip install twilio==9.4.1 requests==2.31.0
```

### 3) Webhook endpoint (Express) with signature validation

Create `src/server.ts`:

```ts
import express from "express";
import bodyParser from "body-parser";
import pinoHttp from "pino-http";
import twilio from "twilio";

const app = express();
app.use(pinoHttp());

// Twilio signature validation requires the raw body for some frameworks.
// For Express with urlencoded, Twilio helper can validate using parsed params.
// Ensure you use the exact URL configured in Twilio Console.
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

const {
  TWILIO_AUTH_TOKEN,
  PUBLIC_WEBHOOK_BASE_URL,
} = process.env;

if (!TWILIO_AUTH_TOKEN) throw new Error("TWILIO_AUTH_TOKEN is required for webhook signature validation");
if (!PUBLIC_WEBHOOK_BASE_URL) throw new Error("PUBLIC_WEBHOOK_BASE_URL is required (e.g., https://example.com)");

app.post("/twilio/conversations/webhook", (req, res) => {
  const signature = req.header("X-Twilio-Signature") || "";
  const url = `${PUBLIC_WEBHOOK_BASE_URL}/twilio/conversations/webhook`;

  const isValid = twilio.validateRequest(
    TWILIO_AUTH_TOKEN,
    signature,
    url,
    req.body
  );

  if (!isValid) {
    req.log.warn({ signature }, "Invalid Twilio signature");
    return res.status(403).send("Forbidd

Related in General