关于Microsoft ConversationBot自定义存储及会话ID获取的技术问询
解决Teams Bot自定义存储会话信息及会话ID获取问题
一、获取会话ID与会话引用(ConversationReference)
Bot给用户发消息的核心依赖是ConversationReference对象,它包含会话ID、用户ID、Teams服务地址等关键信息,只能在用户与Bot交互时捕获:
- 当用户发送消息、@Bot、或添加Bot到聊天时,Bot会收到
Activity对象,直接从中提取完整会话引用:protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken) { // 从Activity中获取会话引用 var conversationReference = turnContext.Activity.GetConversationReference(); // 这里可以把conversationReference序列化后存到自定义存储(比如Redis、SQL数据库) // 示例序列化:var json = JsonSerializer.Serialize(conversationReference); } - 其中
conversationReference.Conversation.Id就是你要找的会话ID,conversationReference.From.Id是用户ID,这两个字段加上ServiceUrl是发送消息的核心参数。 - 注意:Bot无法主动给从未交互过的用户发消息,必须用户先发起对话(比如发消息给Bot、@Bot),否则会因权限不足失败。
二、替换本地存储为自定义共享存储
TeamsToolkit生成的.notification.localstore.json只是本地开发临时存储,生产环境需换成分布式共享存储,核心是把ConversationReference的读写逻辑替换为自定义实现:
1. 定义存储接口与实现
先做通用存储接口,再根据技术栈实现(以Redis为例):
// 统一存储读写逻辑的接口 public interface IConversationStore { Task SaveUserConversationAsync(string userId, ConversationReference reference); Task<ConversationReference> GetUserConversationAsync(string userId); } // Redis存储实现(需引入StackExchange.Redis包) public class RedisConversationStore : IConversationStore { private readonly IDatabase _redisDb; public RedisConversationStore(IConnectionMultiplexer redisConn) { _redisDb = redisConn.GetDatabase(); } public async Task SaveUserConversationAsync(string userId, ConversationReference reference) { var json = JsonSerializer.Serialize(reference); await _redisDb.StringSetAsync($"teams:conv:{userId}", json, TimeSpan.FromDays(30)); } public async Task<ConversationReference> GetUserConversationAsync(string userId) { var json = await _redisDb.StringGetAsync($"teams:conv:{userId}"); return json.HasValue ? JsonSerializer.Deserialize<ConversationReference>(json) : null; } }
2. 发送消息时从自定义存储读取
在通知发送逻辑中,从存储取出会话引用后调用SendMessageAsync:
// 注入自定义存储服务与ConversationBot private readonly IConversationStore _convStore; private readonly ConversationBot _conversationBot; // 发送通知方法 public async Task SendNotificationToUser(string userId, string message, CancellationToken cancellationToken) { var convRef = await _convStore.GetUserConversationAsync(userId); if (convRef != null) { await _conversationBot.SendMessageAsync(convRef, message, cancellationToken); } else { // 处理用户未与Bot交互过的情况 throw new InvalidOperationException("用户未与Bot建立会话,无法发送通知"); } }
三、关键方法返回值说明
GetConversationReference():返回的ConversationReference核心字段:Conversation.Id:会话唯一标识,用于定位具体聊天窗口From.Id:目标用户的Teams唯一IDServiceUrl:Teams的API服务端点,Bot发送消息必须通过这个地址请求ChannelId:固定为"msteams",标识聊天渠道类型
SendMessageAsync():无返回值(返回Task),发送失败会直接抛出异常(如网络错误、会话过期、权限不足),需自行用try-catch捕获处理。
内容的提问来源于stack exchange,提问作者Mathias
相关产品推荐
相关产品推荐

