# voice-telephony > Voice calls with Twilio, Telnyx, and Plivo APIs. Make outbound calls, handle inbound, and use TTS. - Author: a.mor - Repository: alimrb/suruf-platform-repo - Version: 20260208142121 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-08 - Source: https://github.com/alimrb/suruf-platform-repo - Web: https://mule.run/skillshub/@@alimrb/suruf-platform-repo~voice-telephony:20260208142121 --- --- name: voice-telephony description: "Voice calls with Twilio, Telnyx, and Plivo APIs. Make outbound calls, handle inbound, and use TTS." --- # Voice Telephony Skill Make and receive voice calls using Twilio, Telnyx, or Plivo APIs. ## Twilio Voice (Python) ```python # twilio_voice.py import os from twilio.rest import Client from twilio.twiml.voice_response import VoiceResponse # Initialize client account_sid = os.environ["TWILIO_ACCOUNT_SID"] auth_token = os.environ["TWILIO_AUTH_TOKEN"] client = Client(account_sid, auth_token) def make_call(to: str, from_: str, message: str) -> str: """Make an outbound call with TTS message.""" # Create TwiML response = VoiceResponse() response.say(message, voice="alice") response.hangup() # Make call call = client.calls.create( to=to, from_=from_, twiml=str(response), ) return call.sid def make_call_with_url(to: str, from_: str, webhook_url: str) -> str: """Make call that fetches TwiML from webhook.""" call = client.calls.create( to=to, from_=from_, url=webhook_url, ) return call.sid def get_call_status(call_sid: str) -> dict: """Get call status.""" call = client.calls(call_sid).fetch() return { "sid": call.sid, "status": call.status, "duration": call.duration, "to": call.to, "from_": call.from_, } # Webhook handler (Flask) from flask import Flask, request, Response app = Flask(__name__) @app.route("/voice/webhook", methods=["POST"]) def voice_webhook(): """Handle incoming call or call status updates.""" response = VoiceResponse() response.say("Hello! How can I help you today?", voice="alice") response.gather( input="speech", action="/voice/process", speech_timeout="auto", ) return Response(str(response), mimetype="text/xml") ``` ## Twilio Voice (Node.js) ```javascript // twilio-voice.mjs import twilio from "twilio"; const accountSid = process.env.TWILIO_ACCOUNT_SID; const authToken = process.env.TWILIO_AUTH_TOKEN; const client = twilio(accountSid, authToken); async function makeCall(to, from, message) { const VoiceResponse = twilio.twiml.VoiceResponse; const response = new VoiceResponse(); response.say({ voice: "alice" }, message); response.hangup(); const call = await client.calls.create({ to, from, twiml: response.toString(), }); return call.sid; } async function getCallStatus(callSid) { const call = await client.calls(callSid).fetch(); return { sid: call.sid, status: call.status, duration: call.duration, }; } // Express webhook handler import express from "express"; const app = express(); app.use(express.urlencoded({ extended: false })); app.post("/voice/webhook", (req, res) => { const VoiceResponse = twilio.twiml.VoiceResponse; const response = new VoiceResponse(); response.say({ voice: "alice" }, "Hello! How can I help you?"); response.gather({ input: "speech", action: "/voice/process", speechTimeout: "auto", }); res.type("text/xml"); res.send(response.toString()); }); ``` ## Telnyx Voice (Python) ```python # telnyx_voice.py import os import telnyx telnyx.api_key = os.environ["TELNYX_API_KEY"] def make_telnyx_call(to: str, from_: str, webhook_url: str) -> str: """Make outbound call via Telnyx.""" call = telnyx.Call.create( connection_id=os.environ["TELNYX_CONNECTION_ID"], to=to, from_=from_, webhook_url=webhook_url, ) return call.call_control_id def speak_in_call(call_control_id: str, message: str): """Speak TTS in active call.""" call = telnyx.Call(call_control_id=call_control_id) call.speak(payload=message, voice="female", language="en-US") def hangup_call(call_control_id: str): """Hang up a call.""" call = telnyx.Call(call_control_id=call_control_id) call.hangup() ``` ## Plivo Voice (Python) ```python # plivo_voice.py import os import plivo auth_id = os.environ["PLIVO_AUTH_ID"] auth_token = os.environ["PLIVO_AUTH_TOKEN"] client = plivo.RestClient(auth_id, auth_token) def make_plivo_call(to: str, from_: str, answer_url: str) -> str: """Make outbound call via Plivo.""" response = client.calls.create( from_=from_, to_=to, answer_url=answer_url, answer_method="POST", ) return response["request_uuid"] # Generate Plivo XML response from plivo import plivoxml def generate_plivo_response(message: str) -> str: """Generate Plivo XML for TTS.""" response = plivoxml.ResponseElement() response.add(plivoxml.SpeakElement(message)) return response.to_string() ``` ## Webhook Security ```python # Validate Twilio webhook signature from twilio.request_validator import RequestValidator def validate_twilio_request(request): validator = RequestValidator(auth_token) signature = request.headers.get("X-Twilio-Signature", "") url = request.url params = request.form.to_dict() return validator.validate(url, params, signature) ``` ## Common TwiML Patterns ### Play Audio File ```xml https://example.com/audio.mp3 ``` ### Gather Speech Input ```xml Please tell me how I can help you. ``` ### Transfer Call ```xml +15551234567 ``` ### Record Call ```xml ``` ## Tips - Always validate webhook signatures in production - Use ngrok or similar for local webhook development - Set appropriate timeouts for speech recognition - Handle all call states (queued, ringing, in-progress, completed, failed) - Store call SIDs for status tracking - Use async/background jobs for call processing - Test with Twilio/Telnyx test credentials first