如果 BotFramework 发送两次事件类型的活动,如何使用活动中间件

How to use activitymiddleware if activities of type event are sent twice by BotFramework

为了能够在网络聊天客户端中隐藏发送框,我的机器人逻辑发送了一个事件来告诉客户端隐藏发送框。在客户端中,我使用中间件来捕获此事件并隐藏或显示发送框。在控制台中,我看到我从机器人发送的每个事件都由中间件处理两次,导致意外行为。有人知道如何处理吗?

在我的机器人代码中(瀑布式对话)

对话步骤 1.

const hideSendBox =
  {
     name: 'hideSendBox',
     type: 'event'
  };
await stepContext.context.sendActivity(hideSendBox);
return await stepContext.prompt(PROMPT_THAT_DOES_NOT_NEED_SENDBOX, '');

和对话步骤 2.

const showSendBox =
  {
     name: 'showSendBox',
     type: 'event'
  };
await stepContext.context.sendActivity(showSendBox);
return await stepContext.prompt(PROMPT_THAT_DOES_NEED_SENDBOX, '');

对话步骤 3.

return await stepContext.prompt(PROMPT_THAT_DOES_NEED_SENDBOX, '');

在我的网络聊天代码中

const activityMiddleware = () => next => ({ activity, nextVisibleActivity, ...otherArgs }) => {
    const { name, type } = activity;
    if (type === 'event') {console.log(activity)};
    if (type === 'event' && name === 'hideSendBox') {
      document.getElementsByClassName('main')[0].style.visibility = "hidden";
      return () => <Component1 activity={activity} nextVisibleActivity={nextVisibleActivity} />;
    } else if (type === 'event' && name === 'showSendBox') {
      document.getElementsByClassName('main')[0].style.visibility = "visible";
      return () => <Component2 activity={activity} nextVisibleActivity={nextVisibleActivity} />;
    }
    else {
      return next({ activity, nextVisibleActivity, ...otherArgs });
    }
  };

结果:

  1. 在第一个 activity 被发送(hideSendbox)后,activity 中间件获取事件并隐藏 sendBox
  2. 在发送第二个 activity 之后(showSendbox),activity 中间件获取第二个事件(将显示 sendBox),然后再次获取第一个事件。结果,sendBox又被隐藏了。
  3. 只要对话继续并且机器人发送其他活动),中间件就会再次获取第二个事件并显示发送框。

根据 docsactivityMiddleware 适用于 "adding new DOM components into the currently existing DOM of activities"。使用此中间件对于您要执行的操作是不正确的。

相反,您应该通过 Web Chat 的商店传递它。如下设置时,发送框根据传入的事件隐藏和显示。

请注意: 网络聊天团队强烈反对直接更改 DOM,如果可以的话。通过直接更改 DOM,如果 Web Chat 组件在未来进行大修,您可以接受可能的重大更改。

const store = window.WebChat.createStore( {}, ({ dispatch }) => next => action => {
  if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
    const { activity } = action.payload;
    if (activity.type === 'event') {
      if (activity.name === 'hideSendBox') {
        document.getElementsByClassName('main')[0].style.visibility = "hidden";
      } else if (activity.name === 'showSendBox') {
        document.getElementsByClassName('main')[0].style.visibility = "visible";
      }
    }
  }
} );

希望得到帮助!