如何在Node.js版Bot Framework SDK中实现用户无操作超时主动发消息?
实现方案
代码放置位置
计时器的全局存储、会话监听、重置逻辑放在index.js的适配器中间件层即可,不需要修改现有对话框的业务代码;超时后的消息推送逻辑可以直接写在计时器回调里,也可以封装成独立的工具函数调用。
具体实现逻辑
你需要基于会话ID标识每个独立会话,用Map(单实例部署)存储对应会话的计时器实例,每次收到用户消息时重置计时器,超时后调用Bot Framework原生的continueConversation方法推送主动消息,该方案只会在用户至少发送过一条消息后生效,符合不需要机器人主动发起会话的要求。
步骤1:定义全局存储和配置
在index.js顶部添加如下定义:
const { BotFrameworkAdapter, TurnContext } = require('botbuilder'); // 存储会话对应计时器,key为会话ID,value为计时器实例 const sessionTimers = new Map(); // 定义5分钟超时,单位毫秒 const INACTIVE_THRESHOLD = 5 * 60 * 1000;
步骤2:添加适配器中间件处理计时器逻辑
在index.js初始化适配器后,添加中间件监听用户消息,重置计时器:
adapter.use(async (turnContext, next) => { // 仅处理用户发送的普通消息,忽略系统类活动 if (turnContext.activity.type === 'message') { const currentConversationId = turnContext.activity.conversation.id; // 清理已有计时器 if (sessionTimers.has(currentConversationId)) { clearTimeout(sessionTimers.get(currentConversationId)); sessionTimers.delete(currentConversationId); } // 保存当前会话引用,供后续主动发消息使用 const conversationRef = TurnContext.getConversationReference(turnContext.activity); // 新建计时器 const timer = setTimeout(async () => { // 超时后清理存储的计时器 sessionTimers.delete(currentConversationId); // 调用主动消息接口推送内容 await adapter.continueConversation(conversationRef, async (ctx) => { await ctx.sendActivity('你已经5分钟没有发送消息了,还有什么需要帮助的吗?'); }); }, INACTIVE_THRESHOLD); // 存储新计时器 sessionTimers.set(currentConversationId, timer); } // 继续执行后续业务逻辑(包括对话框流转) await next(); });
注意事项
- 会话结束(用户主动退出、对话框触发结束逻辑)时,可添加
sessionTimers.delete(conversationId)逻辑清理无效计时器,避免内存泄漏 - 如果是多实例部署,不要使用本地
Map存储,替换为Redis等分布式缓存,同时将超时任务改为分布式定时任务实现 - Direct Line渠道原生支持主动消息推送,无需额外配置,只要会话引用有效即可正常发送
内容的提问来源于stack exchange,提问作者Adrián
相关产品推荐
相关产品推荐

