Azure Web Chat中ConversationUpdate事件顺序异常,欢迎消息延迟求助
解决Azure Web Chat中欢迎消息延迟发送的问题
问题根源
你碰到的这个差异其实是Azure Web Chat和Bot Framework Emulator的会话初始化机制不一样导致的:
- 模拟器里,会话启动时会一次性把机器人和用户都加入会话,所以两个
ConversationUpdate事件会接连触发,这时候你在用户输入前发欢迎消息完全没问题。 - 但Azure Web Chat的控件为了优化性能,会等到用户第一次输入内容后,才触发用户加入的
ConversationUpdate事件,这就直接导致你的欢迎消息被拖到用户输入后才发送了。
两种可行的解决方案
方案一:用Web Chat初始化事件主动触发欢迎逻辑
与其依赖不靠谱的ConversationUpdate事件,不如在Web Chat加载完成后,主动给机器人发一个自定义的欢迎事件,这样就能精准控制欢迎消息的发送时机:
// 在Web Chat的初始化代码里加这段逻辑 const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => { // 当Direct Line连接成功后发送自定义事件 if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') { dispatch({ type: 'WEB_CHAT/SEND_EVENT', payload: { name: 'webchat_user_join', value: { userId: window.WebChat.createUserID() } } }); } return next(action); }); // 渲染Web Chat控件 window.WebChat.renderWebChat( { directLine: window.WebChat.createDirectLine({ token: '你的Direct Line令牌' }), store }, document.getElementById('webchat') );
然后在你的机器人代码里,监听这个自定义的webchat_user_join事件,触发欢迎消息:
// C# 示例代码 protected override async Task OnEventActivityAsync(ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken) { if (turnContext.Activity.Name == "webchat_user_join") { // 获取用户名,这里可以从用户的身份信息里取 var userName = turnContext.Activity.From.Name; await turnContext.SendActivityAsync(MessageFactory.Text($"Hi, {userName}! Welcome to our bot!"), cancellationToken); } await base.OnEventActivityAsync(turnContext, cancellationToken); }
方案二:调整机器人对ConversationUpdate事件的处理逻辑
如果你还是想基于ConversationUpdate事件来做,可以在机器人里判断会话的初始状态,忽略用户输入后触发的那个用户加入事件,转而在机器人加入的事件里尝试发送欢迎消息:
// C# 示例代码 protected override async Task OnConversationUpdateActivityAsync(ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken) { var activity = turnContext.Activity; // 只处理机器人被加入会话的事件 if (activity.MembersAdded.Any(member => member.Id == activity.Recipient.Id)) { // 找到会话里的用户 var user = activity.MembersAdded.FirstOrDefault(member => member.Id != activity.Recipient.Id); if (user != null) { await turnContext.SendActivityAsync(MessageFactory.Text($"Hi, {user.Name}! Glad you're here!"), cancellationToken); } } // 忽略用户加入的事件(因为Web Chat里这个事件会在用户输入后才来) else if (activity.MembersAdded.Any(member => member.Id == activity.From.Id)) { // 这里可以留空或者做一些后续的初始化操作,但不要发欢迎消息 } await base.OnConversationUpdateActivityAsync(turnContext, cancellationToken); }
不过这个方案有个小问题:在Web Chat里,机器人加入的ConversationUpdate事件触发时,用户的信息可能还没完全加载好,所以推荐优先用方案一,自定义事件的方式更稳定可靠。
总结
核心就是绕开Web Chat里ConversationUpdate事件的触发延迟问题,要么主动发自定义事件触发欢迎消息,要么调整机器人对事件的处理逻辑,优先在机器人加入会话时发送欢迎内容。
内容的提问来源于stack exchange,提问作者Rainmaker
相关产品推荐
相关产品推荐

