【问题标题】:Bot Framework: How to stop a ChoicePrompt from RePromptingBot Framework:如何阻止 ChoicePrompt 重新提示
【发布时间】:2019-06-25 17:41:14
【问题描述】:

我通过 React 开发了一个网页,其中 Webchat-Bot 和 React 应用程序进行交互。 React 应用程序包含一个计时器,它应该停止在那一刻运行的任何对话框。它通过 Direct-Line 发送事件来执行此操作。 无论如何,我得到了不需要的行为,如果机器人逻辑位于瀑布中,其中步骤是(选择-)提示,则问题会被重新提示。 (因为它没有从用户那里收到所需的答案)。我的问题是:

如何阻止 ChoicePrompt 重新提示?

当 Bot 收到“超时”事件时,它会停止与await endDialog() 的当前对话并开始一个发送新消息的新对话。在下一个用户输入之后,弹出之前的提示。所以我假设,后台的提示仍在等待答案之一,并且因为它没有收到它,所以它会重新启动或重新提示。

我尝试将 maxRetries 设置为 0:

var options = {maxRetries: '0'};
await step.prompt(CONFIRM_PROMPT, `text abc..`, ['sure', 'not sure'], options);

弹出事件的代码片段..

async onTurn(turnContext) {
const dc = await this.dialogs.createContext(turnContext);
..
if (turnContext.activity.name === 'time-feedback') {
    ..
    await dc.endDialog(); // when a choice-prompt is active, it keeps reprompting, before the next line gets activated. I wish to end the reprompt and current (waterfall dialog) immediately
    await dc.beginDialog(PromptForStartingNew); // start a new waterfall dialog

}

【问题讨论】:

  • 当对话框收到不是选项之一的输入时,您希望发生什么?只是结束对话?你如何处理这个选择?
  • @Naadof 我希望以不等待包含选项之一的答案的方式取消提示对话框。我不需要关于这个问题的任何结果或输入,因为我想开始一个新的对话。你知道一个可能的方法吗?
  • 您要清除整个对话框堆栈还是只弹出一个对话框?
  • 只有这一个对话框..
  • @KyleDelaney, Naadof 你有提示我该如何解决这个问题吗?您需要更多信息来理解我的观点吗?

标签: javascript node.js botframework web-chat


【解决方案1】:

replaceDialog 函数完全符合您的要求。它结束活动对话框,然后开始一个新对话框,但不会恢复堆栈中下一个最高的对话框。

此方法在概念上等同于调用 endDialog() 然后立即调用 beginDialog()。不同之处在于父对话框不会恢复或以其他方式通知它启动的对话框已被替换。

我怀疑您遇到的一些问题是因为在您开始新对话之前,正在为瀑布调用 resumeDialog。但是,瀑布将停留在当前步骤并再次调用相同的选择提示对我来说没有意义。我期望发生的是让瀑布继续下一步并开始一个新的提示,然后将您的中断对话框放在下一步提示之上的堆栈中。然后当你的打断对话结束时,会再次提示下一步的提示,而不是第一步的提示。如果不查看您的其余代码,很难知道实际发生了什么,但如果我的解决方案适合您,那么这种区别可能无关紧要。

既然你说你想结束整个瀑布,而不仅仅是提示,你需要比replaceDialog多一点。您希望结束活动对话框,然后替换其下方的对话框,但前提是活动对话框是提示且下一个对话框是瀑布。你可以试试这样:

// Check if there are at least 2 dialogs on the stack
if (dc.stack.length > 1) {
    const activeInstance = dc.activeDialog;
    const parentInstance = dc.stack[dc.stack.length - 2];
    const activeDialog = dc.findDialog(activeInstance.id);
    const parentDialog = dc.findDialog(parentInstance.id);

    if (activeDialog instanceof Prompt && parentDialog instanceof WaterfallDialog)
    {
        // Calling endDialog is probably unnecessary for prompts
        // but it's good practice to do it anyway
        await activeDialog.endDialog(turnContext, activeInstance, DialogReason.endCalled);
        // Remove the prompt from the stack without resuming the waterfall
        dc.stack.pop();
    }
}

// Replace the waterfall (or any active dialog) with your interrupting dialog
await dc.replaceDialog(PromptForStartingNew);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-08
    • 2010-09-16
    • 2023-01-23
    • 2019-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多