如何在自动驾驶仪 Twilio 中重置流程?
How can I reset a flow in autopilot Twilio?
我正在尝试取消或重置流程,同时响应收集问题,如果客户选择了一个错误的选项并且他想取消,这是必要的,但现在我只是退出收集添加验证收集和何时完成 max_attempts,我重定向到 main.
我想写 CANCEL 并重定向到 Main,我尝试了一个函数,但收集验证不允许我将重定向从函数发送到 Main Task。
有什么想法吗?
非常感谢。
这是我的功能:
exports.handler = function(context, event, callback) {
var got = require('got');
var value = event.CurrentInput;
if(true){
let responseObject = {
"actions": [
{
"redirect": "task://greetings"
}]
};
callback(null, responseObject);
}};
后来我在 webhook 中使用 onCollectAttempt 调用它,但它没有发生任何事情,只是继续 Collect
Function
Webhook
此处为 Twilio 开发人员布道师。
由于 Collect
函数的当前 JSON bin 不允许“取消”或 "resetting",因此没有简单的方法来执行此操作,但这是一个潜在的与动态 Collect
一起使用的变通方法(您使用 Twilio Function 将其写入 Node.js 而不是将其写入 Autopilot 控制台的 JSON bin。
下面我们有:
1. 我们需要的 Collect 问题集(要涵盖来自单个函数的许多收集,我们需要一些额外的东西,比如动态地从 db/passing 中提取它们)
2. 我们可以使用静态单词检查的用例的代理关键字,例如指示用户随时键入 "agent" 以定向到人类。
//code courtesy of Evangelos Resvanis, Senior Solutions Engineer at Twilio
const questions = [
{
"question": "You want to book appointment?",
"name": "book"
},
{
"question": "When do you need the appointment for?",
"name": "appointment_date"
},
{
"question": "And what time?",
"name": "appointment_time"
}
];
const agent_keywords = ["agent", "i want to speak to agent", "let me talk to someone"];
var stringSimilarity = require('string-similarity');
const COLLECT_TASK = "collect_task";
/*************************** Main Function ********************/
/*
This function generates the collect questions in steps. Each step we enter the function again and check the user input. We keep a counter to exit when
the collect questions are exhausted.
Two main use cases examined (any use case can be built)
- We want to break the collect on specific user input/keywords e.g. "agent". We use string comparison (Use Case 1)
- We want to send the user input to the Queries API to see if they provided fields. We use the API to avoid the Collect validate, as we can't break the Collect
from there (Use Case 2)
Uncomment/comment each use case to examine the results.
*/
exports.handler = function(context, event, callback) {
let count;
//If event.count is set, then we are at least in the first answer from the collect list
if(event.count) {
count = parseInt(event.count);
//Use case 1
/*var matches = stringSimilarity.findBestMatch(event.CurrentInput, agent_keywords);
if (matches.bestMatch.rating > 0.5){
callback(null, {"actions": [{"say": "Sure, handing over to one of our agents now..."}]});
}
else buildCollect(count);*/
//Use case 2
getFieldsOrNextTask(event.CurrentInput, count);
}
else {count = 1;buildCollect(count, null);}
/*
Send the user input to Queries endpoint
- If there are fields and confidence is high, assume user input is ok, remember the value and continue to next question (improvement: check the exact type of field found)
- If there are no fields, check the results of the task and confidence, assuming the user wants to break the collect. Choose the target task based on rules you test, excluding the collect task
*/
async function getFieldsOrNextTask(input, count){
const client = require('twilio')(context.ACCOUNT_SID, context.AUTH_TOKEN);
let fields_result = await client.autopilot.assistants(context.AUTOPILOT_SID).queries.create({language: 'en-US', query: input, tasks: COLLECT_TASK});
if(fields_result.results.task_confidence < 0.4 || !fields_result.results.fields.length){
let all_tasks_string = "";
let tasks = await client.autopilot.assistants(context.AUTOPILOT_SID).tasks.list();
for(let i = 0; i < tasks.length; i++){
if (tasks[i].uniqueName === COLLECT_TASK)continue;
let name = tasks[i].uniqueName;
let unique_name = i === tasks.length-1 ? name : name + ",";
all_tasks_string += unique_name;
}
console.log("All tasks without the Collect task: " + all_tasks_string);
let task_result = await client.autopilot.assistants(context.AUTOPILOT_SID).queries.create({language: 'en-US', query: event.CurrentInput, tasks: all_tasks_string});
let task_confidence = task_result.results.task_confidence;
let chosen_task = parseFloat(task_confidence) < 0.4 && !task_result.results.next_best_task ? "fallback": task_result.results.task;
console.log("Chosen new task to break Collect is: " + chosen_task);
callback(null, {"actions": [{"redirect": "task://" + chosen_task}]});
}
else{
console.log("seemed a valid field of the Collect task, remember it and move to next question");
buildCollect(count, event.CurrentInput);
}
}
function buildCollect(count, userInputToRemember){
console.log("Current count: " + count);
if(count > questions.length){
callback(null, {"actions": [{"say": "Thank you, that is the end of our questions, moving to the next part of the flow"}]});
}
else{
//Create the current collect object and increase the count in on_complete for the next iteration
let name = "collect_" + count;
let on_complete = {
"redirect": "https://" + context.DOMAIN_NAME + "/dynamic-collect?count=" + (count+1)
};
let collect_object = {};
collect_object.name = name;
collect_object.questions = [];
collect_object.questions[0] = questions[count-1];
collect_object.on_complete = on_complete;
console.log("Current Collect object: " + JSON.stringify(collect_object));
if(userInputToRemember){
let remember_var = questions[count-1].name;
console.log(remember_var);
callback(null, {"actions": [{"remember": {remember_var: userInputToRemember}},{"collect": collect_object}]});
}
else{
callback(null, {"actions": [{"collect": collect_object}]});
}
}
}
};
让我知道这是否有帮助! <3
我正在尝试取消或重置流程,同时响应收集问题,如果客户选择了一个错误的选项并且他想取消,这是必要的,但现在我只是退出收集添加验证收集和何时完成 max_attempts,我重定向到 main.
我想写 CANCEL 并重定向到 Main,我尝试了一个函数,但收集验证不允许我将重定向从函数发送到 Main Task。
有什么想法吗?
非常感谢。
这是我的功能:
exports.handler = function(context, event, callback) {
var got = require('got');
var value = event.CurrentInput;
if(true){
let responseObject = {
"actions": [
{
"redirect": "task://greetings"
}]
};
callback(null, responseObject);
}};
后来我在 webhook 中使用 onCollectAttempt 调用它,但它没有发生任何事情,只是继续 Collect
Function Webhook
此处为 Twilio 开发人员布道师。
由于 Collect
函数的当前 JSON bin 不允许“取消”或 "resetting",因此没有简单的方法来执行此操作,但这是一个潜在的与动态 Collect
一起使用的变通方法(您使用 Twilio Function 将其写入 Node.js 而不是将其写入 Autopilot 控制台的 JSON bin。
下面我们有: 1. 我们需要的 Collect 问题集(要涵盖来自单个函数的许多收集,我们需要一些额外的东西,比如动态地从 db/passing 中提取它们) 2. 我们可以使用静态单词检查的用例的代理关键字,例如指示用户随时键入 "agent" 以定向到人类。
//code courtesy of Evangelos Resvanis, Senior Solutions Engineer at Twilio
const questions = [
{
"question": "You want to book appointment?",
"name": "book"
},
{
"question": "When do you need the appointment for?",
"name": "appointment_date"
},
{
"question": "And what time?",
"name": "appointment_time"
}
];
const agent_keywords = ["agent", "i want to speak to agent", "let me talk to someone"];
var stringSimilarity = require('string-similarity');
const COLLECT_TASK = "collect_task";
/*************************** Main Function ********************/
/*
This function generates the collect questions in steps. Each step we enter the function again and check the user input. We keep a counter to exit when
the collect questions are exhausted.
Two main use cases examined (any use case can be built)
- We want to break the collect on specific user input/keywords e.g. "agent". We use string comparison (Use Case 1)
- We want to send the user input to the Queries API to see if they provided fields. We use the API to avoid the Collect validate, as we can't break the Collect
from there (Use Case 2)
Uncomment/comment each use case to examine the results.
*/
exports.handler = function(context, event, callback) {
let count;
//If event.count is set, then we are at least in the first answer from the collect list
if(event.count) {
count = parseInt(event.count);
//Use case 1
/*var matches = stringSimilarity.findBestMatch(event.CurrentInput, agent_keywords);
if (matches.bestMatch.rating > 0.5){
callback(null, {"actions": [{"say": "Sure, handing over to one of our agents now..."}]});
}
else buildCollect(count);*/
//Use case 2
getFieldsOrNextTask(event.CurrentInput, count);
}
else {count = 1;buildCollect(count, null);}
/*
Send the user input to Queries endpoint
- If there are fields and confidence is high, assume user input is ok, remember the value and continue to next question (improvement: check the exact type of field found)
- If there are no fields, check the results of the task and confidence, assuming the user wants to break the collect. Choose the target task based on rules you test, excluding the collect task
*/
async function getFieldsOrNextTask(input, count){
const client = require('twilio')(context.ACCOUNT_SID, context.AUTH_TOKEN);
let fields_result = await client.autopilot.assistants(context.AUTOPILOT_SID).queries.create({language: 'en-US', query: input, tasks: COLLECT_TASK});
if(fields_result.results.task_confidence < 0.4 || !fields_result.results.fields.length){
let all_tasks_string = "";
let tasks = await client.autopilot.assistants(context.AUTOPILOT_SID).tasks.list();
for(let i = 0; i < tasks.length; i++){
if (tasks[i].uniqueName === COLLECT_TASK)continue;
let name = tasks[i].uniqueName;
let unique_name = i === tasks.length-1 ? name : name + ",";
all_tasks_string += unique_name;
}
console.log("All tasks without the Collect task: " + all_tasks_string);
let task_result = await client.autopilot.assistants(context.AUTOPILOT_SID).queries.create({language: 'en-US', query: event.CurrentInput, tasks: all_tasks_string});
let task_confidence = task_result.results.task_confidence;
let chosen_task = parseFloat(task_confidence) < 0.4 && !task_result.results.next_best_task ? "fallback": task_result.results.task;
console.log("Chosen new task to break Collect is: " + chosen_task);
callback(null, {"actions": [{"redirect": "task://" + chosen_task}]});
}
else{
console.log("seemed a valid field of the Collect task, remember it and move to next question");
buildCollect(count, event.CurrentInput);
}
}
function buildCollect(count, userInputToRemember){
console.log("Current count: " + count);
if(count > questions.length){
callback(null, {"actions": [{"say": "Thank you, that is the end of our questions, moving to the next part of the flow"}]});
}
else{
//Create the current collect object and increase the count in on_complete for the next iteration
let name = "collect_" + count;
let on_complete = {
"redirect": "https://" + context.DOMAIN_NAME + "/dynamic-collect?count=" + (count+1)
};
let collect_object = {};
collect_object.name = name;
collect_object.questions = [];
collect_object.questions[0] = questions[count-1];
collect_object.on_complete = on_complete;
console.log("Current Collect object: " + JSON.stringify(collect_object));
if(userInputToRemember){
let remember_var = questions[count-1].name;
console.log(remember_var);
callback(null, {"actions": [{"remember": {remember_var: userInputToRemember}},{"collect": collect_object}]});
}
else{
callback(null, {"actions": [{"collect": collect_object}]});
}
}
}
};
让我知道这是否有帮助! <3