Search code examples
javascriptdialogflow-esvoximplant

Connecting Dialogflow ES and Call Lists in Voximplant


I'm trying to connect my DialogFlow agent with the Call list feature in Voximplant and have been unable to do so.

I wondered if anayone could help me?

The error I am getting is: JS error: number is undefined in /application.js:427:7

This is a link to the full log for the failed call: https://storage-gw-gb-01.voximplant.com/voxdata-gb-logs/2022/08/07/Yzc5OWFlNTJjNTEwOTNkMDgwYTMxMGVjMGE2MTk1MTEvaHR0cDovL3d3dy1mci0wNS0yMTEudm94aW1wbGFudC5jb206ODA4MC9sb2dzLzIwMjIvMDgvMDcvMTEyNTM1X0JBNDA3QkQ4NzUwMjYzODguMTY1OTg3MTUzNS4zMzU4NTIzXzE1Mi4yMjguMjQ3LjIxMS5sb2c-?sessionid=476447299&session_id=6c48e685feee43ada193b016aa7d31e7&account_id=4910907

Here is the scenario code I am using:

require(Modules.CallList);
require(Modules.AI)

let dialogflow, call, hangup

var CALLER_ID = "441618022716"
let number;
let phone_number


// Create outbound call as soon as StartScenarios HTTP API arrives
VoxEngine.addEventListener(AppEvents.Started, function (e) {
    let data = VoxEngine.customData(); // <-- data from CSV string in JSON format
    data = JSON.parse(data);
     phone_number = data.phone_number;
     call = VoxEngine.callPSTN(phone_number, CALLER_ID) // replace CALLER_ID with the number we bought in previous step (the real one, test number does not work)
     call.addEventListener(CallEvents.Connected, onCallConnected)
     call.addEventListener(CallEvents.Disconnected, VoxEngine.terminate)
     call.addEventListener(CallEvents.Failed, VoxEngine.terminate)
})

function onCallConnected(e) {
  // Create Dialogflow object
    dialogflow = AI.createDialogflow({
      lang: DialogflowLanguage.ENGLISH_US
    })
    dialogflow.addEventListener(AI.Events.DialogflowResponse, onDialogflowResponse)
    // 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) => {
      // Dialogflow TTS playback finished. Hangup the call if hangup flag was set to true
      if (hangup) call.hangup()
    })
    dialogflow.addEventListener(AI.Events.DialogflowPlaybackStarted, (e) => {
      // Dialogflow TTS playback started
    })
    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) {
    call.sendMediaTo(dialogflow)
  } else if (e.response.queryResult !== undefined && e.response.responseId !== undefined) {
    // Do whatever required with e.response.queryResult or e.response.webhookStatus
        // If we need to hangup because end of conversation has been reached
        if (e.response.queryResult.diagnosticInfo !== undefined && 
           e.response.queryResult.diagnosticInfo.end_conversation == true) {
           hangup = true
        }

// 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) {
    /**
    * Example:
    * dialogflow.stop()
    * let newcall = VoxEngine.callPSTN(msg.telephonyTransferCall.phoneNumber, "put verified CALLER_ID here")
    * 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: 
    // if (msg.telephonySynthesizeSpeech.ssml !== undefined) call.say(msg.telephonySynthesizeSpeech.ssml, {"language": VoiceList.Amazon.en_US_Joanna})
    // else call.say(msg.telephonySynthesizeSpeech.text, {"language": VoiceList.Amazon.en_US_Joanna})
  }
  // 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.googleapis.com/")
    // Example: call.startPlayback(url)
  }
}

Solution

  • The issue occurs because scenario can't find field named phone_number in custom data passed into it. Most likely this is caused by incorrect delimiter used in CSV file that was uploaded as a call list. You can try using semicolon instead of comma - that should help.