Say
The Say action instructs an Assistant on what to speak back to the user. Say
may contain SSML or plain text.
Example 1: Simple Say
Hello World!
{
"actions": [
{
"say": "Hello World!"
}
]
}
This Say action would say "Hello World!" and end the dialogue. This is an example of statically-rendered JSON and the Say action is a static Action.
Example 2: Dynamic response
Say "Hello World" by calling dynamic JSON from a Twilio Function (or another endpoint) instead of the Autopilot Actions bin.
First you'll redirect to the Function from the Actions bin:
{
"actions": [
{
"redirect": "replace-with-your-function.twil.io/dynamicsay"
}
]
}
In the Twilio Function, your Node.js code to say "Hello World" by rendering Actions' JSON dynamically could look like this. This is also where you could add data from the conversation context, like the name of the user, to your bot's response:
exports.handler = function(context, event, callback) {
let actions = [];
let say = {
"say": "Hello World!"
}
actions.push(say);
let respObj = {
"actions": actions
};
callback(null, respObj);
};
Example 3: Say with SSML
Speech Synthesis Markup Language (SSML) is a W3C specification that allows developers to use XML-based markup language for assisting the generation of synthesized speech. SSML will only work with Polly voices.
{
"actions": [
{
"say": "John's phone number is, <say-as interpret-as='telephone'>4155551212</say-as>, would you like to call him?"
},
{
"listen": true
}
]
}
You can find all the SSML documentation here.
Example 4: Channel Specific Responses
You can customize your bot's response for the different channels by generating dynamic JSON from a Twilio Function (or another backend). The example below responds a different message to users that interact with the Bot via voice
, chat
or any other channel.
exports.handler = function(context, event, callback) {
let actions = [];
let channel = event.Channel;
let say = {};
if (channel == 'voice'){
say = {
"say": "Welcome to the demo IVR!"
}
} else if (channel == 'chat') {
say = {
"say": "Welcome to the demo Chatbot!"
}
} else {
say = {
"say": "Welcome!"
}
}
actions.push(say);
let respObj = {
"actions": actions
};
callback(null, respObj);
};
Example 5: Confidence-dependent response
Task Confidence gives you more granular control over how you handle Autopilot’s response using a Twilio Function (or another backend). When a task is triggered by a user’s utterance, Autopilot includes a confidence score via the CurrentTaskConfidence parameter, and the unique name of the task with the second highest probability of matching that input via the NextBestTask parameter in it’s request to your application. This data is also available on the Queries resource via the confidence and next_best_task attributes in the results object. The NextBestTask will be null if the fallback task is selected as the next best task.
The confidence score is a number between 0 and 1. Since Autopilot uses different machine learning models depending on the nature and quantity of your training data, the score is a relative measure of the probabilities returned by the model for the two tasks with the highest probabilities — (probability#1 - probability#2)/(probability#1).
A high confidence score indicates a larger difference between the probabilities of the top two tasks identified by the model. The task confidence feature is therefore very useful in helping you fine-tune the user experience when the NLU engine returns a low confidence score.
The example below disambiguates between the Task and NextBestTask when the confidence is below a certain level.
exports.handler = function(context, event, callback) {
let actions = [];
let confidence = event.CurrentTaskConfidence;
let task = event.CurrentTask;
let nextBestTask = event.NextBestTask;
let say = {};
if (confidence > 0.5){
say = {
"say": "Thank you, your appointment has been cancelled."
}
actions.push(say);
} else {
say = {
"say": "I didn't quite get that. Did you mean cancel or rechedule appointment?",
};
listen = {
"listen": {
"tasks": [
task,
nextBestTask
]
}
}
actions.push(say);
actions.push(listen);
}
let respObj = {
"actions": actions
};
callback(null, respObj);
};
Example 6: Dynamic response with Memory value
Using Twilio Functions or any other backend app you can respond to a user with a value stored in the Assistant's Memory.
The Twilio Function below demostrates how to respond with a value stored in the Assistant Memory.
NOTE:
- The value has to be in the Assistant's Memory before. Storing it in the Memory and using that value in the same response will not work.
- A response that does not include a Listen, Collect or Redirect ends the dialogue.
First, there needs to be a task that saves the value in Memory:
{
"actions": [
{
"say": "The order status was saved to memory"
},
{
"remember": {
"order_status": "delivered"
}
},
{
"listen": true
}
]
}
After that, a Twilio Function like the one below can use that value in a response.
exports.handler = function(context, event, callback) {
let actions = [];
let say = {};
let memory = JSON.parse(event.Memory);
say = {
"say": "Your order status is " + memory.order_status
}
actions.push(say);
let respObj = {
"actions": actions
};
callback(null, respObj);
};
Need some help?
We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd by visiting Twilio's Stack Overflow Collective or browsing the Twilio tag on Stack Overflow.