@telnyx/voice-cloudflare
v0.1.0
Published
Telnyx voice providers for the Cloudflare Agents SDK
Downloads
109
Readme
@telnyx/voice-cloudflare
Telnyx voice providers for the Cloudflare Agents SDK.
Gives @cloudflare/voice agents access to Telnyx carrier-grade voice infrastructure -- real-time speech-to-text, text-to-speech, and PSTN phone bridging.
Installation
npm install @telnyx/voice-cloudflareRequires @cloudflare/voice as a peer dependency:
npm install @cloudflare/voiceSubpath Imports
Import only what you need — each subpath is independent:
// STT only (no @telnyx/webrtc dependency)
import { TelnyxSTT } from "@telnyx/voice-cloudflare/stt";
// TTS only (no @telnyx/webrtc dependency)
import { TelnyxTTS } from "@telnyx/voice-cloudflare/tts";
// Telephony (PSTN bridge, phone client, JWT endpoint)
import { TelnyxCallBridge, TelnyxPhoneClient } from "@telnyx/voice-cloudflare/telephony";
// Or import everything from the main entrypoint
import { TelnyxSTT, TelnyxTTS, TelnyxCallBridge } from "@telnyx/voice-cloudflare";Quick Start
Browser Voice Agent (STT + TTS)
Use Telnyx STT and TTS with a Cloudflare voice agent:
import { Agent, routeAgentRequest } from "agents";
import { withVoice, type VoiceTurnContext } from "@cloudflare/voice";
import { TelnyxSTT, TelnyxTTS } from "@telnyx/voice-cloudflare";
const VoiceAgent = withVoice(Agent);
export class MyAgent extends VoiceAgent<Env> {
transcriber = new TelnyxSTT({ apiKey: this.env.TELNYX_API_KEY });
tts = new TelnyxTTS({ apiKey: this.env.TELNYX_API_KEY });
async onTurn(transcript: string, context: VoiceTurnContext) {
return `You said: ${transcript}`;
}
}Phone Voice Agent (PSTN Bridge)
Route phone calls to an AI agent using TelnyxPhoneClient. This speaks the Cloudflare voice protocol directly and routes all audio through a PSTN bridge -- no browser speakers needed.
Server (Cloudflare Worker):
import { TelnyxJWTEndpoint } from "@telnyx/voice-cloudflare";
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
if (url.pathname === "/api/telnyx-token") {
const jwt = new TelnyxJWTEndpoint({
apiKey: env.TELNYX_API_KEY,
credentialConnectionId: env.TELNYX_CREDENTIAL_CONNECTION_ID,
});
return jwt.handleRequest(request);
}
return new Response("Not found", { status: 404 });
},
};Client:
import { TelnyxPhoneClient, createTelnyxVoiceConfig } from "@telnyx/voice-cloudflare";
import { WebSocketVoiceTransport } from "@cloudflare/voice/client";
// 1. Set up the call bridge
const telnyx = await createTelnyxVoiceConfig({
jwtEndpoint: "/api/telnyx-token",
autoAnswer: true,
});
// 2. Create a phone client
const phoneClient = new TelnyxPhoneClient({
transport: new WebSocketVoiceTransport({ agent: "my-voice-agent" }),
bridge: telnyx.bridge,
});
// 3. Listen for events
phoneClient.addEventListener("transcriptchange", (messages) => {
console.log(messages);
});
// 4. Connect and start the call
phoneClient.connect();
phoneClient.addEventListener("connectionchange", async (connected) => {
if (connected) await phoneClient.startCall();
});API Reference
Providers
TelnyxSTT
Real-time speech-to-text. Implements the Transcriber interface from @cloudflare/voice.
const stt = new TelnyxSTT({
apiKey: "...",
engine: "Telnyx", // or "Deepgram"
language: "en",
transcriptionModel: "nova-3", // Deepgram model (when engine is "Deepgram")
interimResults: true,
});TelnyxTTS
Text-to-speech with REST and WebSocket backends. Implements TTSProvider and StreamingTTSProvider.
const tts = new TelnyxTTS({
apiKey: "...",
voice: "Telnyx.NaturalHD.astra",
backend: "rest", // "rest" (default, works everywhere) or "websocket" (lower latency, Workers only)
});Phone Bridge
TelnyxCallBridge
Captures and plays PCM audio from PSTN phone calls via TelnyxRTC WebRTC. Implements VoiceAudioInput.
const bridge = new TelnyxCallBridge({
loginToken: "jwt-from-server",
autoAnswer: true,
});TelnyxPhoneClient
Standalone client that speaks the Cloudflare voice protocol directly and routes all audio through a TelnyxCallBridge. Includes silence detection, interrupt detection, transcript management, and mute.
const client = new TelnyxPhoneClient({
transport: new WebSocketVoiceTransport({ agent: "my-agent" }),
bridge: myBridge,
silenceThreshold: 0.04,
silenceDurationMs: 500,
});Events: statuschange, transcriptchange, interimtranscript, metricschange, audiolevelchange, connectionchange, error, mutechange, custommessage.
TelnyxPhoneTransport
Lightweight transport wrapper. Wraps any VoiceTransport, intercepts server audio, and routes it to a TelnyxCallBridge for PSTN playback. Use this when you want VoiceClient for status/transcript management but need audio routed to a phone instead of browser speakers.
const transport = new TelnyxPhoneTransport({
inner: new WebSocketVoiceTransport({ agent: "my-agent" }),
bridge: myBridge,
});Server Utilities
TelnyxJWTEndpoint
Server-side endpoint that generates Telnyx WebRTC login tokens. Keeps your API key secure on the server.
const jwt = new TelnyxJWTEndpoint({
apiKey: "...",
credentialConnectionId: "...",
});
const response = await jwt.handleRequest(request);createTelnyxVoiceConfig(options)
Convenience factory that fetches a JWT and creates a ready-to-use TelnyxCallBridge.
const { bridge, audioInput, cleanup } = await createTelnyxVoiceConfig({
jwtEndpoint: "/api/telnyx-token",
autoAnswer: true,
});Environment Variables
| Variable | Description |
|----------|-------------|
| TELNYX_API_KEY | Your Telnyx API key (server-side only) |
| TELNYX_CREDENTIAL_CONNECTION_ID | Credential connection UUID for WebRTC auth |
Set these via wrangler secret put for Cloudflare Workers.
Examples
See the examples/ directory:
basic-voice-agent-- Browser mic → Telnyx STT → AI agent → Telnyx TTS → browser speakerphone-voice-agent-- Phone call routed to an AI agent viaTelnyxPhoneClienthybrid-agent-- Browser mic + phone bridge running side-by-side
Related
License
MIT
