IVR JS Example (OpenAI)
This example demonstrates an IVR script that harnesses the power of OpenAI by integrating it with Vodia's Javascript IVR capabilities.
Scenario:
- Play a welcome message using Vodia's TTS.
- Send a predefined set of instructions to OpenAI, in this case a map of words to numbers.
- Parse OpenAI's response to determine the appropriate call routing.
//
// OpenAI integration
//
// (C) Vodia Networks 2024
//
// This file is property of Vodia Networks Inc. All rights reserved.
// For more information mail Vodia Networks Inc., info@vodia.com.
//
'use strict';
var secret = "sk-proj-KEY"
var codec = "g711_ulaw" // or pcm16
var texts = {
initial: {
en: "Hi, I am your Vodia AI assistant. How may I help you today?",
de: "Sagen Sie etwas."
}
}
function text(name) {
var prompt = texts[name]
if (call.lang in prompt) return prompt[call.lang];
return prompt["en"]
}
call.say({text: text("initial")});
var timer = setTimeout(function() {call.transfer('700')}, 30000);
var ws = new Websocket("wss://api.openai.com/v1/realtime?model=gpt-4o-realtime-preview-2024-10-01")
ws.header([{ name: "Authorization", value: "Bearer " + secret, secret: true },
{ name: "Cache-Control", value: "no-cache" },
{ name: "Pragma", value: "no-cache" },
{ name: "Sec-Fetch-Dest", value: "websocket" },
{ name: "Sec-Fetch-Mode", value: "websocket" },
{ name: "Sec-Fetch-Site", value: "same-site" },
{ name: "Sec-WebSocket-Protocol", value: "realtime" },
{ name: "OpenAI-Beta", value: "realtime=v1" },
{ name: "User-Agent", value: "Vodia-PBX/69.5.3" }
])
ws.on('open', function() {
console.log("Websocket opened")
})
ws.on('close', function() {
console.log("Websocket closed")
call.stream()
})
ws.on('message', function(message) {
if (message.type != "response.audio.delta") console.log(message);
var msg = JSON.parse(message)
if (msg.type == "session.created") {
var update = {
type: "session.update",
session: {
instructions: "Here is a map of words to numbers: { sales: 785, marketing: 785, support: 739, Bob: 451, technical support: 739 }. Whenever someone tells you to call, or transfer to, would like to talk to, get someone online, return the exact text transfer, followed by a colon, followed by the number from that map based on the destination. If the destination is directly a number then don't use the map, just directly use that number. If there is no number mapped, then return transfer:700",
turn_detection: {
type: "server_vad",
threshold: 0.5,
prefix_padding_ms: 300,
silence_duration_ms: 500
},
voice: "alloy",
temperature: 0.8,
max_response_output_tokens: 4096,
tools: [],
modalities: ["text","audio"],
input_audio_format: codec,
output_audio_format: codec,
input_audio_transcription:{ model: "whisper-1" },
tool_choice: "auto"
}
}
ws.send(JSON.stringify(update))
}
else if (msg.type == "session.updated") {
call.stream({
codec: codec,
interval: 0.5,
callback: stream
})
}
else if (msg.type == "response.audio.delta") {
var audio = fromBase64String(msg.delta)
call.play({
direction: "out",
codec: codec,
audio: audio
})
}
else if (msg.type == "response.audio_transcript.done") {
if (msg.transcript) {
call.log("Message transcript: " + msg.transcript);
var t = msg.transcript.split(':');
if (t.length > 1) {
call.mute();
if (timer) clearTimeout(timer);
var cmd = t[0];
var value = t[1];
if (cmd == "transfer" && value) {
call.transfer(value);
}
else {
call.transfer('700');
}
}
}
}
})
function stream(audio) {
var frame = JSON.stringify({
"type": "input_audio_buffer.append",
"audio": toBase64String(audio)
})
ws.send(frame)
}
ws.connect()
For more information on Vodia's JavaScript capabilities, refer to: Vodia Backend JavaScript Documentation