如何在Bot框架v4的两个步骤之间有延迟?



我想有这样的对话流step1→延迟→步骤2

async step1(stepContext) {
    await stepContext.context.sendActivity('Give user some task to do');
    return await stepContext.next();
    }
    
async delay(stepContext) {
    await stepContext.context.sendActivity({type: 'delay', value:5000});
    return await stepContext.next();
    }
async step2(stepContext) {}

上面的代码不能正常工作。当我运行bot时,它等待5秒,然后执行步骤1和步骤2。我希望延迟在step1之后。

实际上,我想延迟2分钟。我在想那机器人不会继续睡觉之类的。很抱歉,我是新手。

我认为在使用瀑布对话框的同时实现这一点的最佳方法是通过使用setTimeout和主动消息。我将在这里做一些假设,你熟悉的东西,如对话状态,Bot框架适配器,和转弯处理程序,但如果你需要进一步的指导,请告诉我。

首先,从根本上说,您需要捕获会话引用,以便发送主动消息。我发现这最容易在你的onTurn函数中做,并将其保存到对话状态,如下所示:

const conversationData = await this.dialogState.get(context, {});
conversationData.conversationReference = TurnContext.getConversationReference(context.activity);
await this.conversationState.saveChanges(context);

现在,您可以按如下方式设置对话框。你可能有几种不同的方法。我通常会尝试让每一步都提示,但您可能会切换这些操作,仍然可以使其工作。

async step1(stepContext) {
    // First give the user the task
    await stepContext.context.sendActivity('Give user some task to do');
    
    // Next set up a timeout interval. The action here is to send a proactive message.
    const conversationData = await this.dialogState.get(stepContext.context, {});
    this.inactivityTimer = setTimeout(async function(conversationReference) {
        try {
            const adapter = new BotFrameworkAdapter({
                appId: process.env.microsoftAppID,
                appPassword: process.env.microsoftAppPassword
            });
            await adapter.continueConversation(conversationReference, async turnContext => {
                await turnContext.sendActivity('Were you able to successfully complete the task?');
            });
        } catch (error) {
            //console.log('Bad Request. Please ensure your message contains the conversation reference and message text.');
            console.log(error);
        }
    }, 120000, conversationData.conversationReference);
    // Give the user a confirmation prompt
    return await stepContext.prompt('choicePrompt', 'Please confirm the results of the task when you are finished',['Passed','Failed']);
}
async step2(stepContext) {
    // Clear timeout to prevent the proactive message if user has already responded
    clearTimeout(this.inactivityTimer);
    /* REST OF YOUR DIALOG HERE */
    return await stepContext.endDialog();
}
如前所述,确保您正在导入Bot框架适配器,设置提示符(我使用choice,但显然它可以是任何选项),导入会话状态等。此外,需要注意的一件事是,如果用户的响应非常接近计时器(我在这里设置了2分钟),则有可能在bot到达clearTimeout语句之前调用主动消息。我认为这充其量只是一个烦恼,但是你需要根据人们在接近2分钟内完成任务的频率来决定用户体验是否ok。

最后需要注意的是,您可以将主动消息调用放在单独的helper函数中,特别是如果您将在许多不同的对话框中使用它。这样,除了使代码更容易更新之外,您还不必创建适配器的多个实例。也就是说,如果你像我一样只在某个地方需要它,我发现将它插入到对话框中要容易得多,因为它没有那么多代码。

最新更新