botframework - 使用 MS Bot Framework V4 时如何从虚拟助手取消技能对话框
问题描述
我们正在使用 bot-framework 版本 4.x
"botbuilder": "4.11.0",
"botbuilder-ai": "4.11.0",
"botbuilder-applicationinsights": "4.11.0",
"botbuilder-azure": "4.11.0",
"botbuilder-dialogs": "4.11.0",
"botbuilder-lg": "4.11.0",
"botbuilder-testing": "4.11.0",
"botframework-config": "4.11.0",
"botframework-connector": "4.11.0"
案子
我们需要在虚拟助手中启动一个对话框并取消任何正在进行的技能对话框(如果有)
例子
LiveChat - 虚拟助手的一部分 CreateIncidentDialog - 技能的一部分
假设我们在 CreateIncidentDialog 的中间,并且用户想要启动 LiveChat。我们应该启动 LiveChat 并取消当前的 CreateIncidentDialog。
示例代码
MainDialog.ts in Virtual Assistant
如果当前对话框是技能的一部分,我们将启动一个以activity.type 作为技能事件的对话框。
switch (gIntent) {
case 'Escalate': {
// Checking if current Dialog is a part of Skill
if (isSkill) {
const activity: Activity = innerDc.context.activity;
if ((activity.value === null || activity.value === undefined)) {
activity.value = { userState: userProfile };
};
activity.type = ActivityTypes.Event;
activity.name = "liveChat";
const skillDialogArgs: BeginSkillDialogOptions = {
activity: activity as Activity
};
await innerDc.beginDialog(EvaConfig.LUIS_DEFAULT_INTENT, skillDialogArgs);
} else {
await innerDc.cancelAllDialogs();
}
// code for starting LiveChat goes here
// .....
// .....
// .....
}
MainDialog.ts in Skill
如果 activity.type 是 EVENT 并且名称是 'liveChat',则取消对话。
protected async onContinueDialog(innerDc: DialogContext): Promise<DialogTurnResult> {
try {
let activity = innerDc.context.activity;
if (innerDc.context.activity.type === ActivityTypes.Message) {
// .....
// .....
// .....
} else if (activity.type === ActivityTypes.Event) {
const ev = activity;
if (ev.name !== undefined && ev.name.trim().length > 0) {
switch (ev.name) {
case 'liveChat': {
await innerDc.cancelAllDialogs(true);
return await innerDc.endDialog();
}
}
}
}
return await super.onContinueDialog(innerDc);
} catch (e) {
console.log(`Error onContinueDialog ---> ${e} `);
return await this.hanldeException(innerDc);
}
}
问题
上面的代码无法正确取消技能的对话。如果我们在取消技能对话后尝试启动一个新对话,它会再次向 Skill 中 MainDilaog.ts 的 routeStep 方法发送一个 activity.type 为 EVENT 的活动。请在下面找到相同的示例代码。
routeStep method of MainDialog.ts in Skill
protected async routeStep(stepContext: WaterfallStepContext): Promise<DialogTurnResult> {
console.log('skill routeStep');
if (activity.type === ActivityTypes.Message && activity.text !== undefined && activity.text.trim().length > 0) {
// .....
// .....
// .....
} else if (activity.type === ActivityTypes.Event) {
const ev = activity;
if (ev.name !== undefined && ev.name.trim().length > 0) {
switch (ev.name) {
case 'SampleAction': {
// .....
// .....
// .....
}
}
} else {
// If we try to start a new dialog, control comes here
await stepContext.context.sendActivity({
type: ActivityTypes.Trace,
text: 'An event with no name was received but not processed.'
});
}
}
} else {
await this.responder.replyWith(stepContext.context, MainResponses.responseIds.dontHavePermissionServiceNow);
await this.complete(stepContext);
}
return await stepContext.next();
}
复制步骤
步骤 1. 在技能中启动对话 步骤 2. 在技能中结束对话并在 VA 中启动对话 步骤 3. 开始新对话
谢谢。爱德华
解决方案
推荐阅读
- loops - 为什么我不能在两个不同的映射函数中可变地借用一个变量?
- javascript - D3.js v5 圆群图调整力以考虑可变大小的半径
- r - For 循环不使用 print() 函数返回任何值
- moodle - 如何删除 Moodle 课程中的主题 0
- python - Python 在多处理期间更新数据库
- c++ - 为什么会出现垃圾值?
- google-maps - 将 google markerclusterer plus 实现到模板 web 组件中
- python - 如何删除没有索引号的行 - Python
- python - 函数中的返回工作不正确
- reactjs - 在 React js 中使用 onclick 事件处理 Api 调用