Claude
Skills
Sign in
Back

twilio-voice

Included with Lifetime
$97 forever

Voice: outbound/inbound, TwiML, conferencing, recording, transcription, IVR Gather, SIP, BYOC

Image & Videovoicecallstwimlivrtwilio

What this skill does


# twilio-voice

## Purpose

Enable OpenClaw to design, implement, and operate Twilio Programmable Voice in production:

- Build inbound/outbound call flows using TwiML (`<Dial>`, `<Conference>`, `<Gather>`, `<Record>`, `<Say>` with Amazon Polly voices).
- Implement IVR state machines with deterministic transitions, retries, and idempotency.
- Operate call recording + transcription pipelines with retention controls and compliance guardrails.
- Integrate SIP Trunking / SIP Interfaces, BYOC (Bring Your Own Carrier), and edge routing.
- Run conferencing at scale (participant management, moderation, recording, events).
- Diagnose and remediate common Twilio Voice failures (auth, invalid numbers, rate limits, carrier issues, webhook retries).

This skill is written for engineers shipping and maintaining production voice systems with strict reliability, observability, and security requirements.

---

## Prerequisites

### Accounts & Twilio Console setup

- Twilio account with:
  - **Account SID** (`AC...`)
  - **Auth Token** (treat as secret)
  - At least one **Voice-capable phone number** (E.164) or SIP domain
- Configure a Voice webhook for your Twilio number:
  - Console → Phone Numbers → Manage → Active numbers → (number) → **Voice configuration**
  - Set **A CALL COMES IN** to your webhook URL (HTTPS) and method (POST recommended)
  - Set **Status Callback** for call progress events (optional but recommended)

### Runtime versions (tested)

Pick one backend stack; examples cover Node and Python.

- **Node.js**: 20.11.1 LTS (or 18.19.1 LTS)
- **Python**: 3.11.8 (or 3.10.13)
- **Twilio helper libraries**
  - Node: `[email protected]`
  - Python: `twilio==9.0.5`
- **ngrok** (for local webhook dev): 3.14.2
- **Docker** (optional): 25.0.3
- **OpenSSL**: 3.0.x (Linux), 3.2.x (macOS via Homebrew)

### OS support

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

### Network & DNS

- Public HTTPS endpoint for Twilio webhooks (TLS 1.2+).
- If using SIP:
  - Publicly reachable SIP infrastructure or Twilio SIP Domains.
  - Firewall rules for SIP signaling/media (or use Twilio Elastic SIP Trunking with secure signaling).

### Secrets management

- Store `TWILIO_ACCOUNT_SID` and `TWILIO_AUTH_TOKEN` in a secret manager:
  - AWS Secrets Manager / GCP Secret Manager / Vault / 1Password CLI
- Never commit credentials to git.
- Rotate Auth Token on incident response or staff changes.

---

## Core Concepts

### TwiML execution model

- Twilio requests your webhook when a call arrives (or when you initiate an outbound call with a TwiML URL).
- Your server returns **TwiML** (XML) instructions.
- Twilio executes TwiML sequentially; some verbs (e.g., `<Dial>`) block until completion.
- TwiML is **stateless**; state must be stored externally (DB/Redis) and referenced via parameters.

### Call legs, SIDs, and correlation

- `CallSid` identifies a call leg (inbound leg, outbound leg, child calls).
- For `<Dial>`, Twilio often creates a **child call** for the dialed party; correlate via:
  - `ParentCallSid` (in status callbacks / call logs)
- Use `CallSid` as the primary correlation key in logs and traces.

### Webhooks and retries

- Twilio webhooks are HTTP requests to your infrastructure.
- Twilio retries on certain failures (timeouts, 5xx). You must implement:
  - Idempotency (dedupe by `CallSid` + event type + timestamp)
  - Fast responses (< 2s typical target) and async work offloaded to queues

### Status callbacks (events)

- Voice status callback events include:
  - `initiated`, `ringing`, `answered`, `completed`
- For conferences and recordings, additional callbacks exist.
- Treat callbacks as **at-least-once** delivery.

### IVR state machines

- Use `<Gather>` to collect DTMF or speech.
- Model IVR as a state machine:
  - State stored server-side (Redis/DB)
  - Transition on input + timeout + retries
  - Always handle invalid input and no-input paths

### Recording and transcription

- Recording can be enabled on `<Dial>`, `<Conference>`, or via `<Record>`.
- Transcription can be:
  - Twilio’s transcription features (where available)
  - External transcription pipeline (recommended for control/quality)
- Define retention and access controls; recordings are sensitive.

### SIP, BYOC, and edge

- SIP Domains: Twilio-hosted SIP endpoints for your clients.
- Elastic SIP Trunking: connect your PBX/carrier to Twilio.
- BYOC: bring your own carrier and use Twilio for apps/features.
- Use Twilio **Edge Locations** to reduce latency (e.g., `ashburn`, `dublin`, `singapore`).

---

## Installation & Setup

### Official Python SDK — Voice

**Repository:** https://github.com/twilio/twilio-python  
**PyPI:** `pip install twilio` · **Supported:** Python 3.7–3.13

```python
from twilio.rest import Client
from twilio.twiml.voice_response import VoiceResponse

client = Client()

# Outbound call
call = client.calls.create(
    url="https://demo.twilio.com/docs/voice.xml",
    to="+15558675309",
    from_="+15017250604"
)
print(call.sid)

# TwiML response (in webhook handler)
resp = VoiceResponse()
resp.say("Hello from Twilio Python!")
resp.record(transcribe=True, transcribe_callback="/transcription")
```

Source: [twilio/twilio-python — calls](https://github.com/twilio/twilio-python/blob/main/twilio/rest/api/v2010/account/call/__init__.py)

### 1) Install dependencies (Ubuntu 22.04)

```bash
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg jq
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
node -v   # v20.11.1
npm -v    # 10.x
```

Python option:

```bash
sudo apt-get update
sudo apt-get install -y python3.11 python3.11-venv python3-pip
python3.11 -V  # Python 3.11.8
```

ngrok:

```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  # 3.14.2
```

### 2) Install dependencies (Fedora 39/40)

```bash
sudo dnf install -y nodejs20 jq python3.11 python3.11-pip
node -v
python3.11 -V
```

ngrok (manual):

```bash
curl -L -o /tmp/ngrok.tgz https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz
sudo tar -C /usr/local/bin -xzf /tmp/ngrok.tgz ngrok
ngrok version
```

### 3) Install dependencies (macOS 14, Intel + Apple Silicon)

Homebrew:

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

Ensure PATH includes Homebrew Node:

```bash
echo 'export PATH="/opt/homebrew/opt/node@20/bin:$PATH"' >> ~/.zshrc  # Apple Silicon
echo 'export PATH="/usr/local/opt/node@20/bin:$PATH"' >> ~/.zshrc     # Intel
source ~/.zshrc
```

### 4) Create a minimal Voice webhook service (Node.js)

Project layout:

- `/srv/twilio-voice/` (Linux) or `~/src/twilio-voice/` (macOS)
- Config at `/etc/twilio/voice.env` (Linux) or `./.env` (local dev)

```bash
mkdir -p ~/src/twilio-voice && cd ~/src/twilio-voice
npm init -y
npm install [email protected] [email protected] [email protected] [email protected]
```

Create `server.js`:

```javascript
const express = require("express");
const bodyParser = require("body-parser");
const twilio = require("twilio");
const pino = require("pino");

const log = pino({ level: process.env.LOG_LEVEL || "info" });

const app = express();

// Twilio sends application/x-www-form-urlencoded by default
app.use(bodyParser.urlencoded({ extended: false }));

// Optional: validate Twilio signature (recommended in production)
const validateTwilio = (req, res, next) => {
  const authToken = process.env.TWILIO_AUTH_TOKEN;
  const signature = req.header("X-Twilio-Signature");
  const url = `${process.env.PUBLIC_BASE_URL}${req.originalUrl}`;
  const isValid = twilio.validateRequest(authToken, signature, url, req.body);
  if (!isValid) return res.status(403).send("Invalid Twilio signature");
  n

Related in Image & Video