Example: Answering an incoming call

View as MarkdownOpen in Claude

This example answers an inbound Voximplant call and bridges audio to OpenAI Realtime for speech‑to‑speech conversations.

Jump to the Full VoxEngine scenario.

Prerequisites

Session setup

The example configures the OpenAI Realtime session with a short system prompt, a voice, and server VAD:

Session setup
1voiceAIClient.sessionUpdate({
2 session: {
3 type: "realtime",
4 instructions: SYSTEM_PROMPT,
5 voice: "alloy",
6 output_modalities: ["audio"],
7 turn_detection: { type: "server_vad", interrupt_response: true },
8 },
9});

Connect call audio

Once the session is ready, bridge audio both ways between the call and OpenAI:

Connect call audio
1VoxEngine.sendMediaBetween(call, voiceAIClient);

Barge-in

Barge-in
1voiceAIClient.addEventListener(OpenAI.RealtimeAPIEvents.InputAudioBufferSpeechStarted, () => {
2 voiceAIClient.clearMediaBuffer();
3});

Notes

See the VoxEngine API Reference for more details.

Full VoxEngine scenario

voxeengine-openai-answer-incoming-call.js
1/**
2 * Voximplant + OpenAI Realtime API connector demo
3 * Scenario: answer an incoming call and bridge it to OpenAI Realtime.
4 */
5
6require(Modules.OpenAI);
7require(Modules.ApplicationStorage);
8
9const SYSTEM_PROMPT = `
10You are Voxi, a helpful voice assistant for phone callers.
11Keep responses short and telephony-friendly (usually 1-2 sentences).
12`;
13
14const SESSION_CONFIG = {
15 session: {
16 type: "realtime",
17 instructions: SYSTEM_PROMPT,
18 voice: "alloy",
19 output_modalities: ["audio"],
20 turn_detection: {type: "server_vad", interrupt_response: true},
21 },
22};
23
24VoxEngine.addEventListener(AppEvents.CallAlerting, async ({call}) => {
25 let voiceAIClient;
26
27 call.addEventListener(CallEvents.Disconnected, () => VoxEngine.terminate());
28 call.addEventListener(CallEvents.Failed, () => VoxEngine.terminate());
29
30 try {
31 call.answer();
32 // call.record({hd_audio: true, stereo: true}); // Optional: record the call
33
34 voiceAIClient = await OpenAI.createRealtimeAPIClient({
35 apiKey: (await ApplicationStorage.get("OPENAI_API_KEY")).value,
36 model: "gpt-realtime",
37 onWebSocketClose: (event) => {
38 Logger.write("===OpenAI.WebSocket.Close===");
39 if (event) Logger.write(JSON.stringify(event));
40 VoxEngine.terminate();
41 },
42 });
43
44 //---------------------- Event handlers -----------------------
45 voiceAIClient.addEventListener(OpenAI.RealtimeAPIEvents.SessionCreated, () => {
46 voiceAIClient.sessionUpdate(SESSION_CONFIG);
47 });
48
49 voiceAIClient.addEventListener(OpenAI.RealtimeAPIEvents.SessionUpdated, () => {
50 VoxEngine.sendMediaBetween(call, voiceAIClient);
51 voiceAIClient.responseCreate({instructions: "Hello! How can I help today?"});
52 });
53
54 // Barge-in: clear buffered audio when the caller starts speaking
55 voiceAIClient.addEventListener(OpenAI.RealtimeAPIEvents.InputAudioBufferSpeechStarted, () => {
56 Logger.write("===BARGE-IN: OpenAI.InputAudioBufferSpeechStarted===");
57 voiceAIClient.clearMediaBuffer();
58 });
59
60 voiceAIClient.addEventListener(
61 OpenAI.RealtimeAPIEvents.ConversationItemInputAudioTranscriptionCompleted,
62 (event) => {
63 const payload = event?.data?.payload || event?.data || {};
64 const transcript = payload.transcript || payload.text || payload.delta;
65 if (transcript) Logger.write(`===USER=== ${transcript}`);
66 }
67 );
68
69 voiceAIClient.addEventListener(
70 OpenAI.RealtimeAPIEvents.ResponseOutputAudioTranscriptDelta,
71 (event) => {
72 const payload = event?.data?.payload || event?.data || {};
73 if (payload.delta) Logger.write(`===AGENT_DELTA=== ${payload.delta}`);
74 }
75 );
76
77 voiceAIClient.addEventListener(
78 OpenAI.RealtimeAPIEvents.ResponseOutputAudioTranscriptDone,
79 (event) => {
80 const payload = event?.data?.payload || event?.data || {};
81 const transcript = payload.transcript || payload.text;
82 if (transcript) Logger.write(`===AGENT=== ${transcript}`);
83 }
84 );
85
86 // Consolidated "log-only" handlers - key OpenAI/VoxEngine debugging events
87 [
88 OpenAI.RealtimeAPIEvents.ResponseCreated,
89 OpenAI.RealtimeAPIEvents.ResponseDone,
90 OpenAI.RealtimeAPIEvents.ResponseOutputAudioDone,
91 OpenAI.RealtimeAPIEvents.ConnectorInformation,
92 OpenAI.RealtimeAPIEvents.HTTPResponse,
93 OpenAI.RealtimeAPIEvents.WebSocketError,
94 OpenAI.RealtimeAPIEvents.Unknown,
95 OpenAI.Events.WebSocketMediaStarted,
96 OpenAI.Events.WebSocketMediaEnded,
97 ].forEach((eventName) => {
98 voiceAIClient.addEventListener(eventName, (event) => {
99 Logger.write(`===${event.name}===`);
100 if (event?.data) Logger.write(JSON.stringify(event.data));
101 });
102 });
103 } catch (error) {
104 Logger.write("===UNHANDLED_ERROR===");
105 Logger.write(error);
106 voiceAIClient?.close();
107 VoxEngine.terminate();
108 }
109});