Skype for Business机器人conversationUpdate事件欢迎消息异常及重复响应处理求助
解决Skype for Business中Bot首次ConversationUpdate发送欢迎消息失败的问题
我之前也碰到过类似的SfB Bot会话生命周期的坑,结合你的情况来看,核心原因是SfB的会话初始化逻辑和Web Chat完全不一样:当用户首次打开聊天窗口时,Bot收到的conversationUpdate其实只是会话的“预创建通知”,这时候SfB服务器端还没真正完成会话的落地创建,所以你直接发消息就会触发“Conversation does not exist”的错误;而当用户发送第一条消息后,会话才会完全激活,这时候的conversationUpdate就能正常响应。
下面是具体的解决方案,分两步实现:搞定首次消息的可靠发送,同时避免重复响应第二次conversationUpdate。
1. 用会话状态区分首次与重复触发
首先你需要维护一个会话状态存储(可以是内存存储、Redis或者数据库),专门记录每个conversationId是否已经发送过欢迎消息。这样第二次触发conversationUpdate时,就能直接跳过发送逻辑,避免重复回复。
2. 给首次触发加延迟/重试机制
因为首次触发时会话还未就绪,直接发送肯定报错,所以通过短延迟或者错误重试来规避这个问题:
- 收到
conversationUpdate时,先判断是否是用户加入会话(要排除Bot自身被加入的情况),并且该会话还没发过欢迎消息。 - 不要立即发送,设置1-2秒的延迟,给SfB服务器足够的时间完成会话创建,再尝试发送。
- 同时添加错误捕获,如果还是收到“Conversation does not exist”的错误,可以再重试1次(别无限重试,避免死循环)。
示例逻辑(以C#为例)
private readonly IStatePropertyAccessor<bool> _welcomeSentAccessor; public MyBot(ConversationState conversationState) { _welcomeSentAccessor = conversationState.CreateProperty<bool>("WelcomeSent"); } protected override async Task OnConversationUpdateActivityAsync(ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken) { // 筛选出加入会话的新用户(排除Bot自己) var membersAdded = turnContext.Activity.MembersAdded; foreach (var member in membersAdded) { if (member.Id != turnContext.Activity.Recipient.Id) { var welcomeSent = await _welcomeSentAccessor.GetAsync(turnContext, () => false, cancellationToken); if (!welcomeSent) { try { // 延迟1秒发送,给SfB服务器留足会话创建时间 await Task.Delay(1000, cancellationToken); await turnContext.SendActivityAsync("欢迎使用我们的服务!有任何问题都可以随时问我~", cancellationToken: cancellationToken); // 标记该会话已发送过欢迎消息 await _welcomeSentAccessor.SetAsync(turnContext, true, cancellationToken); await turnContext.ConversationState.SaveChangesAsync(turnContext, false, cancellationToken); } catch (HttpOperationException ex) { if (ex.Response.StatusCode == HttpStatusCode.NotFound && ex.Message.Contains("Conversation does not exist")) { // 重试一次 await Task.Delay(1000, cancellationToken); await turnContext.SendActivityAsync("欢迎使用我们的服务!有任何问题都可以随时问我~", cancellationToken: cancellationToken); await _welcomeSentAccessor.SetAsync(turnContext, true, cancellationToken); await turnContext.ConversationState.SaveChangesAsync(turnContext, false, cancellationToken); } } } } } }
3. 额外注意事项
- 确保你的Bot已经配置好SfB通道的全部权限,尤其是会话创建相关的权限。
- SfB 2016相比2013优化了会话触发逻辑,但仍然存在初始化延迟,所以延迟机制是核心。
- 如果用Node.js开发,逻辑完全相通:用
conversationState存储发送状态,用setTimeout实现延迟,捕获错误后重试即可。
这样就能实现用户首次打开窗口时自动发送欢迎消息,同时避免用户发第一条消息后重复响应conversationUpdate事件。
内容的提问来源于stack exchange,提问作者Vijay
相关产品推荐
相关产品推荐

