我通过React开发了一个Webchat-Bot和React App交互的网页。 React App包含一个计时器,该计时器应停止那一刻正在运行的任何对话框。它通过直接发送事件来执行此操作。 无论如何,我得到了一个有害的行为,即如果漫游器逻辑位于一个瀑布中,而该步骤是一个(Choice-)提示,则该问题将被再次提示。 (因为它没有从用户那里收到所需的答案)。我的问题是:
如何阻止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
}
答案 0 :(得分: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);