Intro

babblevoice Auto Attendant XML is a language designed to allow developers of web applications to integrate their systems, such as CRM with live auto attendants, allowing them to pass real information in and out of phone calls. This is where an Auto Attendant becomes Interactive Voice Response (IVR). The process is, babblevoice downloads a small, simple, chunk of XML for every step of the auto attendant. This small chunk of XML will contain simple instructions which when combined create powerful Auto Attendant applications (well technically IVR).

A call to a BAAXML URL is triggered via a normal call rule (this rule chunk can be found under Auto Attendants). babblevoice will honour any http get variables appended to the url, this can be used to configure security and we would always recommend using SSL to secure any request. As well as http get variables appended to the URL, babblevoice also appends its own: step: a number of how many times the url has been called next: the data from the next variable from the xml in the last request digits: any digits which have been entered via getdigits For every request, babblevoice will call a pre-defined URL specified by the author of the auto attendant.

<?xml version="1.0" encoding="ISO-8859-1"?>
<baaxml>
     <command>speak</command>
  <text>Thank you for calling babblevoice</text>
  <next>data</next>
</baaxml>
  • The data in the next tag is represented on the next call to the url.
  • babblevoice will keep any cookies for the duration of the phone call (i.e. session_start() in a php script can be called to save session information).

Parameters

The following is a list of parameters we pass in the URL as a GET query string

  • uuid - unique identifier of the call
  • destination_number - the number which was dialled
  • caller_id_number - the caller id number
  • step - the number of calls which have been completed during this cycle
  • caller_id_name - the caller id name
  • digits - if any digits have been collected then they will appear in this parameter
  • next - (not to be confused with the next command), contains the data included in the previous command (in the next parameter), useful for managing sessions
  • If the call has been answered, the following parameters are also presented:
  • bill_seconds
  • created_time
  • answered_time

Commands

Speak

Use the TTS (Text To Speech) engine to say the text defined in the param text. Once performed it will call the BAAXML url again. If the playing is interrupted by a user entering digits, the playing will stop and the BAAXML url will be called again. The digits will be saved for the next call of getdigits (as long as it is the following request). The speak command also supports the getdigits parameter to force a wait on user input (see playspeak).

Play

Play the wav file referenced by the param filename. Once performed it will call the BAAXML filename again. It plays this file from Voice Prompts. If the playing is interrupted by a user entering digits, the playing will stop and the BAAXML url will be called again. The digits will be saved for the next call of getdigits (as long as it is the following request). The play command takes the following params: filename - the name of the filename (as stored in prompt space) alt - if the filename does not exist what to say instead getdigits - see playspeak for example

PlaySpeak

Builds an array of prompt to stitch together. Useful for playing back prompts with snippets of text to speech squeezed in. i.e. “Your next available appointment is on Monday the 4th of July”, this maybe broken down into “Your next available appointment is on” as a recording and “Monday the 4th of July” as text to speech.

<?xml version="1.0" encoding="ISO-8859-1"?>
<baaxml>
  <command>playspeak</command>
  <playspeak>
    <row><command>play</command><filename>recording.wav</filename><alt>your next available appointment is on</alt></row>
    <row><command>speak</command><text>Monday the 4th of July</text></row>
  </playspeak>
  <getdigits><number>1</number><timeout>60</timeout></getdigits>
</baaxml>

Next

Finish the Auto Attendant and continue to the next rule in the babblevoice call rule.

Hangup

Hang the call up with normal hangup.

Getdigits

Will wait for digits to be entered by the user. Will timeout on 120 seconds. Has the following params: timeout - timeout in seconds to wait for the digits - default 120 seconds. If the collection is fixed by number then on timeout it will call the url with the value timeout number - the number to collect before finished, if omitted will exit on the user dialling ‘#’ or timeout. Once collected, babblevoice will call the BAAXML url with the get param digits.

Jumpto

Uses the parameter extension to jump to. Note, an extension is a combination of Device and internal rule.

Forward

Forwards the call to an external number. Takes the following parameters: number - the external number to call maintaincallerid - whether to maintain the callerid from an external number. There are two methods for how to alter the caller id on the forwarded leg. The person receiving the forwarded call will see a caller id this could be the dialled number into babblevoice, or the caller id of the caller of the original call. The param maintaincallerid modifies this behavior.

Setcallerid

Sets the caller id, data can be found in the tag.

Setcalleridname

Sets the caller id name, data can be found in the tag.

Examples

As commands are produced in XML, the programming language used to create it is neutral. Our first example is a Google Script published as a web app. This is really useful as these are hosted free of charge. The following code has been allowed to run as an anonymous user and then will run as my user account so that it has access to my contacts. The code shows just a simple collection of things we could do like set the caller id name based on phone number and the contact information which might be stored, playing wav files, collecting input from the user.

Example 1 - PHP

A simple example in PHP

<?php
  session_start();
  $xml = "";
  switch ($_SESSION["state"])
  {
    default:
      $_SESSION["state"] = "startoption";

      $xml = new SimpleXMLElement('<baaxml/>');
      $xml->addChild('command', 'speak');
      $xml->addChild('text', 'thank you for calling widgets dot com, please dial 1 to enter 10 digits or 2 to forward the call');
      $gt = $xml->addChild('getdigits');
      $gt->addChild('number','1');
      $gt->addChild('timeout','60');

      break;

    switch($_REQUEST["digits"])
    {
      case "1":

        $_SESSION["state"] = "gotdigits";
        $xml = new SimpleXMLElement('<baaxml/>');
        $xml->addChild('command', 'getdigits');
        $xml->addChild('number', '10');

        break;
      case "2":
        $_SESSION["state"] = "start";

        $xml = new SimpleXMLElement('<baaxml/>');
        $xml->addChild('command', 'forward');
        $xml->addChild('number', '07766088671');
        $xml->addChild('maintaincallerid', 'true');

        break;
      default:

        $xml = new SimpleXMLElement('<baaxml/>');
        $xml->addChild('command', 'speak');
        $xml->addChild('text', 'invalid, please try again');

        $gt = $xml->addChild('getdigits');
        $gt->addChild('number','1');
        $gt->addChild('timeout','60');

        break;
      }

      break;
}

Header('Content-type: text/xml');
print($xml->asXML());

Example 2 - A Google App script

A simple Google script embedded in a Google Doc.

// Script-as-app template.
function doGet(request) {

  var root = XmlService.createElement('baaxml');

  if ( null == request.parameters.next )
  {
    var child = XmlService.createElement('command')
    .setText("play");

    root.addContent(child);

    //child = XmlService.createElement('text')
    //.setText("This is our new test");

    child = XmlService.createElement('filename')
    .setText("myfile.wav");

    root.addContent(child);

    child = XmlService.createElement('next')
    .setText("setcallid");

    root.addContent(child);

  }
  else if( "setcallid" == request.parameters.next )
  {
    var child = XmlService.createElement('command')
      .setText("setcalleridname");

    root.addContent(child);

    child = XmlService.createElement('idname')
    .setText(getContactName(request.parameters.caller_id_number));

    root.addContent(child);

    child = XmlService.createElement('next')
    .setText("prompt");

    root.addContent(child);
  }
  else if( "prompt" == request.parameters.next )
  {
    var child = XmlService.createElement('command')
    .setText("speak");

    root.addContent(child);

    child = XmlService.createElement('text')
    .setText("Please enter 1 or 2");

    root.addContent(child);

    child = XmlService.createElement('next')
    .setText("gatherforfinish");

    root.addContent(child);
  }
  else if( "gatherforfinish" == request.parameters.next )
  {
    var child = XmlService.createElement('command')
    .setText("getdigits");

    root.addContent(child);

    child = XmlService.createElement('text')
    .setText("Please enter 1 or 2");

    root.addContent(child);

    number = XmlService.createElement('number')
    .setText("1");

    child = XmlService.createElement('next')
    .setText("finish");

    root.addContent(number);
    root.addContent(child);
  }
  else
  {
    if ("1" == request.parameters.digits)
    {
      // final - babblevoice rule to continue
      var child = XmlService.createElement('command')
      .setText("play");

      root.addContent(child);

      child = XmlService.createElement('filename')
      .setText("myotherfile.wav");

      root.addContent(child);
    }
    else
    {
      // final - babblevoice rule to continue
      var child = XmlService.createElement('command')
      .setText("next");

      root.addContent(child);
    }
  }

  // request.parameters.prefix

  var document = XmlService.createDocument(root);
  var ourxml = XmlService.getPrettyFormat().format(document);

  return ContentService.createTextOutput(ourxml).setMimeType(ContentService.MimeType.XML);
}


function getContactName(number)
{

  var contacts = ContactsApp.getContactsByPhone(number);

  if ( 0 != contacts.length )
  {
    return contacts[0].getFullName()
  }

  return ""
}

More information about

Also, check out the babblevoice University on Youtube or ask a question in our Google Group.