1

我通过 React 开发了一个网页,其中一个 Webchat-Bot 和 React App 交互。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

}
4

1 回答 1

0

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);
于 2019-07-30T22:18:44.873 回答