AI-powered voice agent system using Twilio and OpenAI Realtime API. This system enables phone-based conversations with AI agents that can handle tasks like appointment reminders, surveys, notifications, and custom interactions.
The system consists of two main components:
-
Twilio Server (Port 5050) - Fastify-based WebSocket server that handles:
- Outbound and incoming phone calls
- Real-time audio streaming between Twilio and OpenAI
- Call state management
- Server-Sent Events for UI updates
-
Next.js UI (Port 3000) - Web interface for:
- Initiating and monitoring calls
- Viewing live transcripts
- Tracking tool calls
- "Listen In" feature for live call audio
See docs/ARCHITECTURE.md for detailed architecture documentation.
- Node.js 18+ and npm
- OpenAI API key with Realtime API access
- Twilio account with:
- Account SID
- Auth Token
- Phone number
- Public domain with HTTPS (for Twilio webhooks)
- Clone this repository:
git clone <your-repo-url>
cd twilio-voice-agent- Install dependencies:
npm install- Configure environment variables:
cp .env.sample .envEdit .env and add your credentials:
OPENAI_API_KEY=sk-...
TWILIO_ACCOUNT_SID=ACxxx...
TWILIO_AUTH_TOKEN=xxx...
TWILIO_PHONE_NUMBER=+1234567890
PUBLIC_DOMAIN=your-domain.com
- Start both servers:
npm run devOr start them separately:
# Terminal 1: UI
npm run ui:dev
# Terminal 2: Twilio Server
npm run server:devFor production deployment with public HTTPS access:
- Install Cloudflare Tunnel (cloudflared)
- Configure tunnel with ingress rules:
/*βlocalhost:3000(Next.js UI)/twilio/*βlocalhost:5050(Twilio Server)
See docs/CLOUDFLARE_TUNNEL_SETUP.md for detailed setup.
- Open the UI at
http://localhost:3000 - Configure call settings:
- Phone number
- Task type (custom, appointment reminder, survey, notification)
- Voice (alloy, ash, ballad, coral, echo, sage, verse)
- Temperature (0.0-1.0)
- Noise reduction (far_field, near_field, off)
- OpenAI model
- Task prompt
- Click "Initiate Call"
- Monitor the live transcript and tool calls
- Optionally click "π§ Listen In" to hear the call audio
The UI includes pre-configured presets:
- π Transit Booking (Caregiver)
- π Appointment Reminder
- π Quick Survey
Twilio Server (Port 5050)
POST /twilio/outbound-call- Initiate outbound callPOST /twilio/incoming-call- Handle incoming calls (TwiML)WS /twilio/media-stream- WebSocket audio streamingPOST /twilio/end-call/:callSid- End active callWS /twilio/events- Server-Sent Events for UIWS /twilio/audio-stream/:callSid- Live audio broadcastGET /twilio/health- Health check
Next.js Server (Port 3000)
GET /api/models- List available OpenAI Realtime models
See docs/twilio-integration.md for full API documentation.
Agents are created per-call with task-specific instructions:
{
to: "+1234567890",
task: {
type: "custom",
prompt: "Your custom instructions here",
context: {}
},
agentConfig: {
voice: "verse",
temperature: 0.8,
noiseReduction: "far_field",
model: "gpt-realtime"
}
}Built-in end_call tool allows AI to terminate calls:
// AI can call this when task is complete
end_call({ reason: "Task completed successfully" })Configure audio noise reduction for phone environments:
far_field- Recommended for phone calls (default)near_field- For close microphonesoff- Disable noise reduction
Monitor live call audio in your browser via WebSocket streaming with real-time G.711 ΞΌ-law decoding and playback.
twilio-voice-agent/
βββ server/ # Fastify server (port 5050)
β βββ routes/ # API endpoints and WebSocket handlers
β βββ agents/ # Agent configurations
β βββ services/ # Twilio client and call management
β βββ types/ # TypeScript interfaces
β βββ utils/ # Logger and utilities
βββ ui/ # Next.js app (port 3000)
β βββ app/
β βββ api/ # API routes
β βββ page.tsx # Main UI component
βββ docs/ # Documentation
βββ scripts/ # Helper scripts
βββ package.json # Dependencies and scripts
βββ README.md # This file
# Development
npm run dev # Start both UI and server
npm run ui:dev # Start UI only
npm run server:dev # Start server only
# Production
npm run build # Build UI for production
npm run start # Start both in production mode
npm run ui:start # Start UI in production
npm run server:start # Start server in production
# Testing
npm run call # Test call script
npm run call:reminder # Test appointment reminder
npm run call:survey # Test survey callSee docs/twilio-testing-guide.md for:
- Local testing procedures
- End-to-end testing
- Debugging guides
- Performance testing
- Example curl commands
alloy- Neutral voiceash- Conversationalballad- Expressivecoral- Warmecho- Male voicesage- Clearverse- Default
custom- Free-form custom taskappointment_reminder- Appointment confirmationssurvey- Customer surveysnotification- Information delivery
- Temperature: 0.0 (focused) to 1.0 (creative)
- Noise Reduction: far_field, near_field, off
- Codec: G.711 ΞΌ-law (8kHz) β PCM16 (24kHz)
-
Call not connecting
- Check Twilio credentials in
.env - Verify PUBLIC_DOMAIN is accessible
- Check Cloudflare Tunnel is running
- Check Twilio credentials in
-
No audio
- Verify WebSocket connection in browser console
- Check microphone permissions
- Ensure noise reduction is configured
-
Transcript not appearing
- Check Server-Sent Events connection
- Verify callSid matches active call
- Check browser console for errors
Enable detailed logging:
LOG_LEVEL=debug npm run server:dev- Target Latency: <200ms end-to-end
- Concurrent Calls: No artificial limits
- Memory per Call: ~10MB
- CPU: Minimal (I/O bound)
- Multi-instance deployment with Redis
- Call recording and storage
- Analytics and metrics dashboard
- Custom tool integration
- Multi-language support
See docs/FUTURE_IMPROVEMENTS.md for the roadmap.
See LICENSE file for details.
For issues and questions:
- Check docs/ directory for detailed documentation
- Review docs/ARCHITECTURE.md for system design
- See docs/twilio-testing-guide.md for debugging
This is a demonstration project. Feel free to fork and customize for your use case.