Skip to main content

Voice Integration

Process voice calls, webhooks, and TeXML applications using Edge Compute functions for low-latency call handling.

Call Control Integration

Handle call events and control calls programmatically:

export default async function(request) {
const webhook = await request.json();

switch (webhook.event_type) {
case 'call.initiated':
return handleCallInitiated(webhook);
case 'call.answered':
return handleCallAnswered(webhook);
case 'call.hangup':
return handleCallHangup(webhook);
default:
return new Response('OK', { status: 200 });
}
}

async function handleCallInitiated(webhook) {
// Answer the call
const response = await fetch(`https://api.telnyx.com/v2/calls/${webhook.data.payload.call_control_id}/actions/answer`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.TELNYX_API_KEY}`,
'Content-Type': 'application/json'
}
});

return new Response('Call answered', { status: 200 });
}

TeXML Processing

Process TeXML applications at the edge:

<!-- TeXML served from Edge Compute -->
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>Welcome to our edge-powered call system</Say>
<Gather numDigits="1" action="https://your-function.edge.telnyx.com/process-dtmf">
<Say>Press 1 for sales, 2 for support</Say>
</Gather>
</Response>
export default async function(request) {
const url = new URL(request.url);

if (url.pathname === '/process-dtmf') {
const formData = await request.formData();
const digits = formData.get('Digits');

let responseXML;
if (digits === '1') {
responseXML = `
<Response>
<Say>Connecting you to sales</Say>
<Dial>+15551234567</Dial>
</Response>
`;
} else if (digits === '2') {
responseXML = `
<Response>
<Say>Connecting you to support</Say>
<Dial>+15559876543</Dial>
</Response>
`;
}

return new Response(responseXML, {
headers: { 'Content-Type': 'application/xml' }
});
}

// Default TeXML response
const defaultXML = `
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>Welcome to our service</Say>
</Response>
`;

return new Response(defaultXML, {
headers: { 'Content-Type': 'application/xml' }
});
}

Conference Management

Manage conference calls dynamically:

import json
import os

async def handler(request):
webhook = await request.json()

if webhook['event_type'] == 'conference.participant.joined':
return await handle_participant_joined(webhook)
elif webhook['event_type'] == 'conference.participant.left':
return await handle_participant_left(webhook)

return {"status": "ok"}

async def handle_participant_joined(webhook):
conference_id = webhook['data']['payload']['conference_id']
participant_count = webhook['data']['payload']['participant_count']

# Play welcome message for first participant
if participant_count == 1:
await play_conference_music(conference_id)

# Announce when participant joins
await speak_to_conference(
conference_id,
f"Participant {participant_count} has joined the conference"
)

return {"status": "handled"}

async def speak_to_conference(conference_id, message):
url = f"https://api.telnyx.com/v2/conferences/{conference_id}/actions/speak"
headers = {
'Authorization': f'Bearer {os.environ["TELNYX_API_KEY"]}',
'Content-Type': 'application/json'
}
data = {
'payload': message,
'voice': 'alice',
'language': 'en-US'
}

# Make API call to Telnyx.
async with aiohttp.ClientSession() as session:
await session.post(url, headers=headers, json=data)

Learn more about voice integrations in our Voice API documentation.