如何保存MS Bot状态数据与对话?Node.js Bot Builder SDK场景技术问询
解决Bot Builder SDK调用
endConversation()时conversationData被清空的问题 我之前也碰到过这个坑,Bot Builder SDK里调用endConversation()时清空conversationData确实是设计预期——毕竟会话结束后,对应的会话状态会被标记为过期清理。但如果需要保留会话里的关键数据,有几个实用的解决方案:
方案1:调用endConversation()前手动备份数据到userData
userData是和用户绑定的持久化状态,不会随会话结束被清空。你可以在结束会话前,把需要保留的conversationData内容复制过去:
// 定义备份会话数据的工具函数 async function backupConversationData(turnContext) { // 获取当前会话数据和用户数据 const conversationData = await turnContext.conversationState.get(turnContext); const userData = await turnContext.userState.get(turnContext); // 把需要保留的字段复制到userData(比如会话记录、用户选择的选项等) userData.lastSessionInfo = { sessionId: turnContext.activity.conversation.id, userSelectedOption: conversationData.selectedOption, sessionEndTime: new Date().toISOString() }; // 保存userData的变更 await turnContext.userState.saveChanges(turnContext); } // 在需要结束会话的逻辑里先备份再结束 await backupConversationData(turnContext); await turnContext.endConversation("会话已结束,关键数据已保存");
方案2:自定义CosmosDB存储,跳过conversationData的清空逻辑
如果想完全保留conversationData,可以扩展默认的CosmosDB存储类,在处理删除请求时过滤掉会话数据的key:
const { CosmosDbPartitionedStorage } = require('botbuilder-azure'); class CustomCosmosStorage extends CosmosDbPartitionedStorage { async delete(keys) { // 过滤掉包含conversationData的key,只删除其他需要清理的状态 const filteredKeys = keys.filter(key => !key.includes('conversationData')); return super.delete(filteredKeys); } } // 用自定义存储替换默认的CosmosDB存储 const storage = new CustomCosmosStorage({ cosmosDbEndpoint: process.env.COSMOS_DB_ENDPOINT, authKey: process.env.COSMOS_DB_AUTH_KEY, databaseId: process.env.COSMOS_DB_DATABASE_ID, containerId: process.env.COSMOS_DB_CONTAINER_ID }); // 初始化状态管理器 const conversationState = new ConversationState(storage); const userState = new UserState(storage);
方案3:使用独立的自定义会话状态属性
不依赖SDK自带的conversationData,而是创建自己的会话状态属性,自主控制数据生命周期:
const { ConversationState, StatePropertyAccessor } = require('botbuilder'); // 创建自定义的会话状态属性 const conversationState = new ConversationState(storage); const persistentSessionData = conversationState.createProperty('persistentSessionData'); // 读取和保存数据时使用这个自定义属性 async function savePersistentData(turnContext, data) { await persistentSessionData.set(turnContext, data); await conversationState.saveChanges(turnContext); }
这种方式下,即使调用endConversation(),自定义属性的数据也不会被自动清空,你可以根据业务需求手动管理数据的删除逻辑,避免CosmosDB积累过多无效数据。
内容的提问来源于stack exchange,提问作者Royjad
相关产品推荐
相关产品推荐

