如何在 Bot Framework v4 中的两个步骤之间有延迟?
How to have delay between two steps in Bot Framework v4?
我想要这样的对话流程
步骤 1 -> 延迟 -> 步骤 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) {}
以上代码无法正常工作。当我 运行 机器人等待 5 秒,然后执行 step1 和 step2。我希望延迟在步骤 1 之后。
实际上,我希望延迟为 2 分钟。我想知道机器人不会继续睡觉什么的。对不起,我是新手。
我认为使用瀑布对话框实现此目的的最佳方法是使用 setTimeout
和主动消息。我将在这里做出一些假设,即您熟悉对话状态、Bot 框架适配器和 Turn Handlers 等内容,但如果您需要任何进一步的指导,请告诉我。
首先,从根本上说,您将需要捕获对话参考以发送主动消息。我发现这最简单,只需在您的 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 Framework Adapter、设置提示(我使用了 choice 但显然它可以是任何内容)、导入对话状态等。另外,需要注意的一件事是如果用户响应非常接近计时器(我在此处设置为 2 分钟),则可能会在 bot 到达 clearTimeout
语句之前调用主动消息。我认为这最多是一件烦人的事,但您需要根据某人在将近 2 分钟内完成任务的频率来确定该用户体验是否正常。
最后一点,您可以将主动消息调用放在一个单独的辅助函数中,特别是如果您要在许多不同的对话框中使用它。这样您就不必创建适配器的多个实例,此外还能使您的代码更易于更新。也就是说,如果您像我一样只在某个地方需要它,我发现将它插入到对话框中会容易得多,因为它没有那么多代码。
我想要这样的对话流程 步骤 1 -> 延迟 -> 步骤 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) {}
以上代码无法正常工作。当我 运行 机器人等待 5 秒,然后执行 step1 和 step2。我希望延迟在步骤 1 之后。
实际上,我希望延迟为 2 分钟。我想知道机器人不会继续睡觉什么的。对不起,我是新手。
我认为使用瀑布对话框实现此目的的最佳方法是使用 setTimeout
和主动消息。我将在这里做出一些假设,即您熟悉对话状态、Bot 框架适配器和 Turn Handlers 等内容,但如果您需要任何进一步的指导,请告诉我。
首先,从根本上说,您将需要捕获对话参考以发送主动消息。我发现这最简单,只需在您的 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 Framework Adapter、设置提示(我使用了 choice 但显然它可以是任何内容)、导入对话状态等。另外,需要注意的一件事是如果用户响应非常接近计时器(我在此处设置为 2 分钟),则可能会在 bot 到达 clearTimeout
语句之前调用主动消息。我认为这最多是一件烦人的事,但您需要根据某人在将近 2 分钟内完成任务的频率来确定该用户体验是否正常。
最后一点,您可以将主动消息调用放在一个单独的辅助函数中,特别是如果您要在许多不同的对话框中使用它。这样您就不必创建适配器的多个实例,此外还能使您的代码更易于更新。也就是说,如果您像我一样只在某个地方需要它,我发现将它插入到对话框中会容易得多,因为它没有那么多代码。