Skip to content

Telephony

Botsquad bots can work as interactive, smart IVR systems on traditional phone line. Contact us for more information about this.

The dial statement

By using dial, you can forward the current phone call to a new destination.

The phone number given to dial is a full E164 phone number, e.g. including country code and the + sign.

dialog main do
  say "Please hold."
  dial "+31201234567"
end

In case the calling party does not pick up the dialog continues where it left off. The event.payload variable is then filled with a string which describes the cause why the caller did not pick up:

dialog main do
  say "Please hold."
  dial "+31201234567"

  branch event.payload do
  "BUSY" ->
    say "The line is busy."

  "NOANSWER" ->
    say "The caller did not answer."

  true ->
    say "We are unable to connect you through due to an unknown error."
  end
end

The following call denial reasons are supported:

event.payload Description
CHANUNAVAIL Channel unavailable (for example in sip.conf, when using qualify=, the SIP chan is unavailable)
BUSY Returned busy
NOANSWER No Answer (i.e SIP 480 or 604 response)
ANSWER Call was answered
CANCEL Call attempt cancelled (i.e user hung up before the call connected)
DONTCALL Privacy manager don’t call
CONGESTION Congestion, or anything else (some other error setting up the call)

Speech adaptation

The phone backend uses Google Speech to Text for recognizing a user's voice.

As such, it is possible to hint the recognizer about certain words, phrases or entities that should be recognized better. This process is called speech adaptation.

The adapter takes hints that are extracted from the expecting: part of ask. Certain references to entities that are contained in the expecting clause are automatically converted to their corresponding class token:

Bubblescript entity Class token
[amount_of_money] $MONEY
[phone_number] $FULLPHONENUM
[number] $OOV_CLASS_DIGIT_SEQUENCE
[date] $FULLDATE
[time] $TIME

So when you have a script like this:

dialog main do
  ask "When is your birthdate?", expecting: entity(match: "[time]")
end

The phone adapter will automatically add $TIME to its speech context.

Other entities or just text and labels will not be automatically taken as speech_hints. So for labels and text you need to define explicit speech_hints, see paragraph below.

speech_hints: option to ask

It is also possible to override these speech hints by providing a speech_hints: option to ask:

dialog main do
  ask "Where do you live?", speech_hints: ["i live at $POSTALCODE"]
end

In this case, you would use the class tokens directly as part of the sample phrases.

DTMF and quick replies

Whenever an ask with quick_replies is encountered, these quick replies are automatically mapped onto the DTMF numbers.

So in the following case:

dialog main do
  ask "Do you want to continue?", expecting: ["Yes", "No"]
end

Pressing 1 would automatically select "Yes" as the answer.

Note there is no hint ("press 1 for yes") spoken, nor are the actual options (the quick replies) read aloud, you would have to implement this yourself in Bubblescirpt.

Automatic replacements

In some cases the text-to-speech engine always makes the same mistake spelling out certain names, et cetera. The phone adapter can be configured to automatically replace strings in the SSML output. Note that this replacement is being done before any Speech Markdown processing.

To do this, create a voice_config YAML file with the following contents:

output_translate:
  $i18n: true
  en:
    - { from: "Hi", to: "Hai" }
    - { from: "Arjan", to: '(Arjan)[sub:"Aryuhn"]' }

This would replace all occurrences of the word Hi with the word Hai, and, more realisticly, annotate the name Arjan with a Speech Markdown sub tag, so that it is pronounced correctly.

Webhook API response

The https://bsqd.me/phone/webhook/<identifier>/<callerid>/<channelid> endpoint has the following return value:

{
  // whether or not this is the final response
  "is_final": false,

  // the locale in which the bot speaks
  "locale": "nl",

  // the text that the bot says, as SSML.
  "ssml": "<speak><s>Hello...</s></speak>",

  // the configured Text-to-speech voice (optional)
  "voice": {
    "type": "google",
    "name": "nl-NL-Standard-A",
    "gender": "FEMALE",
    "locale": "nl"
  },

  // Any speech context elements to be passed into Google's speech-to-text `speechContexts` object (optional)
  "speechContexts": [{
    "phrases": ["I want a cookie"]
  }],

  // if dial is set, redirect this call to the given number (optional)
  "dial": "+31641322222"
}