如何检测 Botframework v4 中的对话结束?
How to detect end of dialog in Botframework v4?
我正在尝试在系统中完成任何其他对话后启动反馈对话。我发现 this answer 说要使用 onEndDialog
,但这在 ActivityHandler 中不是有效函数,只有 onDialog
。我的 "main dialog" 在 bot.js 中扩展了 ActivityHandler,这就是我不扩展 ComponentDialog 的原因。鉴于这是如何设置的,有没有办法确定对话何时结束?我试图检查 onDialog
中的对话框堆栈,但它显示为没有来自用户的欢迎消息和初始消息的对话框,之后始终显示为对话框 运行。有没有一种方法可以修改我的 function/bot 处理程序来检测对话事件的结束?这是我试过的 onDialog 函数。
this.onDialog(async (context, next) => {
const currentDialog = await this.dialogState.get(context, {});
if (currentDialog.dialogStack) {
console.log('Dialog is running');
} else {
console.log('Dialog is not running');
}
// By calling next() you ensure that the next BotHandler is run.
await next();
});
我考虑过在每个对话框的末尾添加一个额外的步骤来调用反馈对话框(可能通过 replaceDialog),但我不确定这是否是最佳做法。
这不能完全做到,因为 endDialog
不会冒泡到任何可从 ActivityHandler
访问的内容(据我所知)。
但对于解决方法,您已经很接近了!把它改成这样:
this.onDialog(async (context, next) => {
const currentDialog = await this.dialogState.get(context);
if (currentDialog === undefined) {
console.log('No dialogs started');
} else if (currentDialog.dialogStack && currentDialog.dialogStack.length > 0) {
console.log('Dialog is running');
} else {
console.log('Dialog is not running');
}
// By calling next() you ensure that the next BotHandler is run.
await next();
});
你的不是很好工作只是因为 currentDialog
被设置为 {}
如果它不存在,这是真的,所以我们需要检查 dialogStack 中是否有任何东西 currentDialog.dialogStack.length > 0
.
如果还没有对话开始,currentDialog
就是 undefined
,因此 currentDialog === undefined
或 !currentDialog
允许初始消息和欢迎消息。拥有这三个独立的分支应该可以让您处理每种情况。
关于 "best practices",如果您想在 every 结束时获得反馈,我会说这是 正确的 方法对话。如果有 任何 个您不想要反馈的地方,最好在适当的对话框结束时调用您的 FeedbackDialog。
我想出了一个更好的解决方案,它建立在@mdrichardson 的解决方案的基础上,并解决了在该答案的评论中提到的保存 dialogStack 的问题。保存和检查 dialogStack 的先前状态一点也不复杂。
请注意,由于最初的问题,我从 onMembersAdded
开始在对话状态中设置一些值,因此我的 conversationData 应该始终被定义。相反,我检查 !conversationData.dialogStack
。对于此解决方案,我还为 !conversationData
添加了一个 OR 检查,它应该说明根本没有对话状态以及有一个状态但没有对话堆栈。
// Add this in constructor of your bot.js file
this.onDialog(async (context, next) => {
// Set up end of dialog messages
const conversationData = await this.dialogState.get(context);
if (!conversationData || !conversationData.dialogStack) {
console.log('Dialog not started');
conversationData.previousDialogLength = 0;
} else {
console.log('Dialog running');
console.log(conversationData.dialogStack, conversationData.previousDialogLength);
if (conversationData.dialogStack.length == 0 && conversationData.previousDialogLength != 0) {
console.log('Dialog ended');
await context.sendActivity('Placeholder for End of Dialog action');
}
conversationData.previousDialogLength = conversationData.dialogStack.length;
}
await this.conversationState.saveChanges(context);
return await next();
});
我正在尝试在系统中完成任何其他对话后启动反馈对话。我发现 this answer 说要使用 onEndDialog
,但这在 ActivityHandler 中不是有效函数,只有 onDialog
。我的 "main dialog" 在 bot.js 中扩展了 ActivityHandler,这就是我不扩展 ComponentDialog 的原因。鉴于这是如何设置的,有没有办法确定对话何时结束?我试图检查 onDialog
中的对话框堆栈,但它显示为没有来自用户的欢迎消息和初始消息的对话框,之后始终显示为对话框 运行。有没有一种方法可以修改我的 function/bot 处理程序来检测对话事件的结束?这是我试过的 onDialog 函数。
this.onDialog(async (context, next) => {
const currentDialog = await this.dialogState.get(context, {});
if (currentDialog.dialogStack) {
console.log('Dialog is running');
} else {
console.log('Dialog is not running');
}
// By calling next() you ensure that the next BotHandler is run.
await next();
});
我考虑过在每个对话框的末尾添加一个额外的步骤来调用反馈对话框(可能通过 replaceDialog),但我不确定这是否是最佳做法。
这不能完全做到,因为 endDialog
不会冒泡到任何可从 ActivityHandler
访问的内容(据我所知)。
但对于解决方法,您已经很接近了!把它改成这样:
this.onDialog(async (context, next) => {
const currentDialog = await this.dialogState.get(context);
if (currentDialog === undefined) {
console.log('No dialogs started');
} else if (currentDialog.dialogStack && currentDialog.dialogStack.length > 0) {
console.log('Dialog is running');
} else {
console.log('Dialog is not running');
}
// By calling next() you ensure that the next BotHandler is run.
await next();
});
你的不是很好工作只是因为 currentDialog
被设置为 {}
如果它不存在,这是真的,所以我们需要检查 dialogStack 中是否有任何东西 currentDialog.dialogStack.length > 0
.
currentDialog
就是 undefined
,因此 currentDialog === undefined
或 !currentDialog
允许初始消息和欢迎消息。拥有这三个独立的分支应该可以让您处理每种情况。
关于 "best practices",如果您想在 every 结束时获得反馈,我会说这是 正确的 方法对话。如果有 任何 个您不想要反馈的地方,最好在适当的对话框结束时调用您的 FeedbackDialog。
我想出了一个更好的解决方案,它建立在@mdrichardson 的解决方案的基础上,并解决了在该答案的评论中提到的保存 dialogStack 的问题。保存和检查 dialogStack 的先前状态一点也不复杂。
请注意,由于最初的问题,我从 onMembersAdded
开始在对话状态中设置一些值,因此我的 conversationData 应该始终被定义。相反,我检查 !conversationData.dialogStack
。对于此解决方案,我还为 !conversationData
添加了一个 OR 检查,它应该说明根本没有对话状态以及有一个状态但没有对话堆栈。
// Add this in constructor of your bot.js file
this.onDialog(async (context, next) => {
// Set up end of dialog messages
const conversationData = await this.dialogState.get(context);
if (!conversationData || !conversationData.dialogStack) {
console.log('Dialog not started');
conversationData.previousDialogLength = 0;
} else {
console.log('Dialog running');
console.log(conversationData.dialogStack, conversationData.previousDialogLength);
if (conversationData.dialogStack.length == 0 && conversationData.previousDialogLength != 0) {
console.log('Dialog ended');
await context.sendActivity('Placeholder for End of Dialog action');
}
conversationData.previousDialogLength = conversationData.dialogStack.length;
}
await this.conversationState.saveChanges(context);
return await next();
});