有两种不同的方法可以解决这个问题,一种是直接使用事件,另一种是使用setTimeout 用于所有频道。直连解决方案需要您的网络聊天客户端上的一些代码,但后者需要您保存对话引用并启动新的机器人适配器。两种方法都可以。
仅直通线
如果在计时器到期之前没有发送任何活动,您需要设置您的网络聊天客户端来设置计时器并向您的机器人发送事件。您需要创建一个自定义商店来执行此操作。这是我过去使用的一个示例:
const store = window.WebChat.createStore({}, function(dispatch) { return function(next) { return function(action) {
if (action.type === 'WEB_CHAT/SEND_MESSAGE') {
// Message sent by the user
clearTimeout(interval);
} else if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY' && action.payload.activity.name !== "inactive") {
// Message sent by the bot
clearInterval(interval);
interval = setTimeout(function() {
// Notify bot the user has been inactive
dispatch.dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'inactive',
value: ''
}
});
}, 300000)
}
return next(action);
}}});
这将向您的机器人发送一个名为“inactive”的事件。现在你需要设置你的机器人来处理它。因此,在您的 this.onEvent 处理程序中,您需要执行以下操作:
if (context.activity.name && context.activity.name === 'inactive') {
await context.sendActivity({
text: 'Are you still there? Is there anything else I can help you with?',
name: 'inactive'
});
}
所有频道
在我输入此内容时,我意识到您应该能够从您的机器人本身发出事件并放弃启动一个新的机器人适配器实例。但我之前没有尝试过,所以我提供了我现有的解决方案。但是您可能希望尝试在达到超时时发出非活动事件,而不是执行以下操作。
也就是说,这是一个您可以在 this.onMessage 处理程序中使用的解决方案。
// Inactivity messages
// Reset the inactivity timer
clearTimeout(this.inactivityTimer);
this.inactivityTimer = setTimeout(async function(conversationReference) {
console.log('User is inactive');
try {
const adapter = new BotFrameworkAdapter({
appId: process.env.microsoftAppID,
appPassword: process.env.microsoftAppPassword
});
await adapter.continueConversation(conversationReference, async turnContext => {
await turnContext.sendActivity('Are you still there?');
});
} catch (error) {
//console.log('Bad Request. Please ensure your message contains the conversation reference and message text.');
console.log(error);
}
}, 300000, conversationData.conversationReference);
请注意,如果您走这条路线,您必须获取并保存会话引用,以便在计时器到期时您可以调用continueConversation。我通常也在我的this.onMessage 处理程序中执行此操作,以确保我始终拥有有效的对话参考。您可以使用以下代码获取它(我假设您已经定义了对话状态和状态访问器)。
const conversationData = await this.dialogState.get(context, {});
conversationData.conversationReference = TurnContext.getConversationReference(context.activity);
现在,正如我在第一个解决方案中提到的那样,我相信您应该能够在 try 块中发送不活动事件,而不是启动机器人适配器。如果您尝试了它并且它有效,请告诉我,以便我可以更新此解决方案!