Template for deploying an AI voice assistant with Twilio, OpenAI Realtime API, and Cloudflare Workers
View the Project on GitHub jmoore2333/twilio-openai-voice-assistant-cloudflare-template
Use this after your first deploy to confirm Twilio, the Worker, OpenAI Realtime, and your database are all wired correctly.
In the Twilio phone number configuration:
POST https://<your-domain>/voice/incoming/voice/ws/.../voice/outboundMake one short inbound call and give the assistant a simple name and reason.
Good example:
Jean-LucI'm looking to pick up my saddleThat makes it easier to confirm the structured intake fields were saved correctly.
Replace the database name if needed:
npx wrangler d1 execute voice-assistant-template --remote --command "SELECT twilio_call_sid, from_number, to_number, caller_name, preferred_language, reason_summary, call_status, email_status, created_at, updated_at, length(COALESCE(transcript_text, '')) AS transcript_chars FROM intake_calls ORDER BY id DESC LIMIT 5;"
What you want to see:
call_status eventually becomes completedcaller_name and reason_summary are populatedtranscript_chars is greater than 0npx wrangler d1 execute voice-assistant-template --remote --command "SELECT twilio_call_sid, COUNT(*) AS transcript_events FROM call_transcript_events GROUP BY twilio_call_sid ORDER BY MAX(id) DESC LIMIT 5;"
You should see transcript events for the latest call SID.
npx wrangler d1 execute voice-assistant-template --remote --command "SELECT twilio_call_sid, stage, event_type, message, created_at FROM call_debug_events ORDER BY id DESC LIMIT 20;"
Useful signs:
incoming_call_recordedsave_call_intake_calledpersist_completed_succeededwebsocket_closedCheck these first:
POST /voice/incoming/voice/incoming and /voice/ws/*OPENAI_API_KEY and TWILIO_AUTH_TOKEN are set as Worker secrets/healthnpx wrangler delete <worker-name>
npx wrangler d1 delete <database-name>