Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
VoxEngine Dialogflow Voicebot example
require(Modules.AI)
require(Modules.Recorder)
const MAX_NO_INPUT_TIME = 10000
const VOICEBOT_PHONE_NUMBER = 18576002939
let dialogflow, call
// Fire the "NO_INPUT" event if there is no speech for MAX_NO_INPUT_TIME
class Timer {
constructor() {
this.expired = false
this.noInputTimer = null
}
start(){
this.noInputTimer = setTimeout(()=>{
this.expired = true
Logger.write("No_Input timer exceeded")
dialogflow.sendQuery({event : {name: "NO_INPUT", language_code: "en"}})
}, MAX_NO_INPUT_TIME || 15 * 1000)
Logger.write("No_Input timer started")
}
stop(){
this.expired = false
clearTimeout(this.noInputTimer)
Logger.write("No_Input cleared")
}
}
let timer = new Timer()
const waitForTone = false
// Inbound call processing
VoxEngine.addEventListener(AppEvents.CallAlerting, (e) => {
call = e.call
call.addEventListener(CallEvents.Connected, onCallConnected)
call.addEventListener(CallEvents.Disconnected, VoxEngine.terminate)
call.addEventListener(CallEvents.RecordStarted, e => { Logger.write("Recording URL: " + e.url)})
call.handleTones(true)
call.addEventListener(CallEvents.ToneReceived, onTone)
call.answer()
})
function onCallConnected(e) {
// Start recording
call.record({stereo: true})
// Create Dialogflow object
dialogflow = AI.createDialogflow({
lang: DialogflowLanguage.ENGLISH_US
})
dialogflow.addEventListener(AI.Events.DialogflowResponse, onDialogflowResponse)
// Set a phone context with phone parameters
// ToDo: error handling if returned parameters are null?
phoneContext = {
name: "phone",
lifespanCount: 99,
parameters: {
caller_id: call.callerid(),
called_number: call.number()
}
}
dialogflow.setQueryParameters({contexts: [phoneContext]})
// Sending WELCOME event to let the agent says a welcome message
dialogflow.sendQuery({event : {name: "WELCOME", language_code: "en"}})
// Playback marker used for better user experience
dialogflow.addMarker(-300)
// Start sending media from Dialogflow to the call
dialogflow.sendMediaTo(call)
dialogflow.addEventListener(AI.Events.DialogflowPlaybackFinished, (e) => {
timer.start()
waitForTone = false
})
dialogflow.addEventListener(AI.Events.DialogflowPlaybackStarted, (e) => {
// Dialogflow TTS playback started
timer.stop()
})
dialogflow.addEventListener(AI.Events.DialogflowPlaybackMarkerReached, (e) => {
// Playback marker reached - start sending audio from the call to Dialogflow
call.sendMediaTo(dialogflow)
})
}
// Handle Dialogflow responses
function onDialogflowResponse(e) {
// If DialogflowResponse with queryResult received - the call stops sending media to Dialogflow
// in case of response with queryResult but without responseId we can continue sending media to dialogflow
if (e.response.queryResult !== undefined && e.response.responseId === undefined) {
if (!timer.expired && !waitForTone)
call.sendMediaTo(dialogflow)
} else if (e.response.queryResult !== undefined && e.response.responseId !== undefined) {
// Do whatever required with e.response.queryResult or e.response.webhookStatus
// Telephony messages arrive in fulfillmentMessages array
if (e.response.queryResult.fulfillmentMessages != undefined) {
e.response.queryResult.fulfillmentMessages.forEach((msg) => {
if (msg.platform !== undefined && msg.platform === "TELEPHONY") processTelephonyMessage(msg)
})
}
}
}
// Process telephony messages from Dialogflow
function processTelephonyMessage(msg) {
// Transfer call to msg.telephonyTransferCall.phoneNumber
if (msg.telephonyTransferCall !== undefined) {
dialogflow.stop()
let newcall = VoxEngine.callPSTN(msg.telephonyTransferCall.phoneNumber, VOICEBOT_PHONE_NUMBER)
VoxEngine.easyProcess(call, newcall)
}
// Synthesize speech from msg.telephonySynthesizeSpeech.text
if (msg.telephonySynthesizeSpeech !== undefined) {
// See the list of available TTS languages at https://voximplant.com/docs/references/voxengine/language
// Example: call.say(msg.telephonySynthesizeSpeech.text, Premium.US_ENGLISH_FEMALE)
}
// Play audio file located at msg.telephonyPlayAudio.audioUri
if (msg.telephonyPlayAudio !== undefined) {
// audioUri contains Google Storage URI (gs://), we need to transform it to URL (https://)
let url = msg.telephonyPlayAudio.audioUri.replace("gs://", "https://storage.cloud.google.com/")
// Example: call.startPlayback(url)
}
}
function onTone(e){
//ToDo: error handling - i.e. check to make sure Dialogflow is connected and running first, tone valuess
waitForTone = true
dialogflow.sendQuery({event : {name: "DTMF", language_code: "en", parameters: { dtmf_digits: e.tone} }})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.