Reputation: 2626
I'd like to send a bot something similar to this
"[Person] wants to meet at [Place] at [Date]"
however, if the person misses some pieces of information I want the bot to ask for it piece by piece.
So for example if a person writes:
"Let's meet!"
The bot would ask a series of questions to fulfill all the data requirements. Something like:
If the person ask something like:
"Alex would like to meet tomorrow"
Then the bot would only ask
"Where should they meet?"
Once all the required data it complete it would send a response like:
"Great, I will meet [Person] in [Location] at [DateTime]"
I've been trying approaches like this with little luck and getting a "Too many calls to session.EndDialog()" error:
dialog.on('Meeting', [
function (session, results, next) {
var person = builder.EntityRecognizer.findEntity(results.entities, 'Person');
if(!person){
builder.Prompts.text(session, prompts.meetingPersonMissing);
} else {
next({ response: {
person: person.entity
}
});
}
},
function (session, results, next) {
var location = builder.EntityRecognizer.findEntity(results.entities, 'location');
if(!location){
builder.Prompts.text(session, prompts.meetingLocationMissing);
} else {
// Pass title to next step.
next({ response: {
person: results.person,
location: location.entity
}
});
}
},
function (session, results, next) {
var time = builder.EntityRecognizer.findEntity(results.entities, 'builtin.datetime.date');
if(!time){
builder.Prompts.text(session, prompts.meetingTimeMissing);
} else {
next({ response: {
person: results.person,
location: results.location,
time: time.entity
}
});
}
},
function (session, results) {
if (results.response) {
session.send(prompts.meetingSubmited);
} else {
session.send(prompts.canceled);
}
}
]);
Unsuccessful Attempt #2 (no longer passing data from 'next()'). This results in same EndDialog error
dialog.on('Meeting', [
function (session, results, next) {
var person = builder.EntityRecognizer.findEntity(results.entities, 'Person');
var location = builder.EntityRecognizer.findEntity(results.entities, 'location');
var time = builder.EntityRecognizer.findEntity(results.entities, 'builtin.datetime');
session.messageData = {
person: person || null,
location: location || null,
time: time || null
}
if(!session.messageData.person){
builder.Prompts.text(session.messageData.person, prompts.meetingPersonMissing);
} else {
next();
}
},
function (session, results, next) {
if(!session.messageData.location){
builder.Prompts.text(session.messageData.location, prompts.meetingLocationMissing);
} else {
next();
}
},
function (session, results, next) {
if(!session.messageData.time){
builder.Prompts.text(session.messageData.time, prompts.meetingTimeMissing);
} else {
next();
}
},
function (session, results) {
debugger;
if (results.response) {
session.send('Meeting scheduled');
} else {
session.send(prompts.canceled);
}
}
]);
Update #3: In this version it works well if the utterance doesn't contain any relevant entities. For example "Could we meet?" works fine.
The issue with this version is when I try "Could we meet tomorrow?". Tomorrow is successfully identified as a datetime entity, however once it hits the next()
in this block:
function getDate(session, results){
session.dialogData.topic = results.response;
if(session.dialogData.date){
next();
}else{
builder.Prompts.time(session, "What date would you like to meet?");
}
}
It fails and gives me the same Too many calls to to session.EndDialog()
issues
dialog.on('Meeting', [meetingQuery, getDate, getTime, respondMeeting]);
function meetingQuery(session, results){
if (results.response) {
session.dialogData.date = builder.EntityRecognizer.resolveTime([results.response]);
}
session.userData = {
person: session.message.from.name
}
builder.Prompts.text(session, "Hi "+ session.userData.person +"!\n\n What is the meeting in reference too?");
}
function getDate(session, results){
session.dialogData.topic = results.response;
if(session.dialogData.date){
next();
}else{
builder.Prompts.time(session, "What date would you like to meet?");
}
}
function getTime(session, results){
if (results.response) {
session.dialogData.date = builder.EntityRecognizer.resolveTime([results.response]);
}
if(session.dialogData.time){
next();
}else{
builder.Prompts.choice(session, "Your professor has the follow times availeble?", ["1pm", "2pm", "3pm"]);
}
}
function respondMeeting(session, results){
var time = results.response;
session.send("Your meeting has been schedueld for " + session.dialogData.date + " at " + time.entity + ". Check your email for the invite.");
}
Upvotes: 2
Views: 1321
Reputation: 11
I think you should access
results.response.person
instead of
results.person
same applies for other closures for this waterfall.
Upvotes: 0
Reputation: 11
Try this instead, it works on my bot.
dialog.on('QuieroQueMeLlamen', [
function (session, args) {
var Telefono = builder.EntityRecognizer.findEntity(args.entities, 'Usuario::Telefono');
if(!Telefono){
builder.Prompts.number(session, "Dame un número telefónico donde pueda llamarte una de nuestras enfermeras (sin espacios ni caracteres: ej: 3206907529)");
}
},
function (session, results) {
if (results.response) {
//IF STRLEN es un celular entonces:
session.send("Te estamos llamando al número %s, por favor contesta", results.response);
}
}
]);
Upvotes: 1
Reputation: 711
You should not pass a parameter to the next() function but use the session.YOUVARIABLES to store data through the waterfall.
Something like :
function (session, results, next) {
var person = builder.EntityRecognizer.findEntity(results.entities, 'Person');
if(!person){
builder.Prompts.text(session, prompts.meetingPersonMissing);
} else {
session.person = person.entity
next();
}
}
Upvotes: 0