【问题标题】:Set Timer Using Microsoft Bot Framework使用 Microsoft Bot Framework 设置计时器
【发布时间】:2019-03-01 06:36:43
【问题描述】:

如果用户超过 5 秒没有回复机器人,机器人应该提示“你在吗”。要实现这个逻辑,请你帮忙,如何使用 Node Js SDK 和 V4 版本在聊天机器人中设置计时器在微软 Bot 框架中

【问题讨论】:

    标签: node.js botframework chatbot


    【解决方案1】:

    在用户一段时间不活动后,您可以让 WebChat 或 BotChat 向机器人发送反向通道事件,机器人可以通过询问用户是否仍然存在来做出响应。请注意,我建议使用 WebChat,因为 BotChat 已被贬低,并且 WebChat 中的实现稍微干净一些。

    网络聊天

    在 WebChat 中,我们将创建一个自定义存储和中间件来监听用户发送消息和机器人发送消息的事件 - 分别为 WEB_CHAT/SEND_MESSAGEDIRECT_LINE/INCOMING_ACTIVITY

    当机器人发送的消息没有询问用户是否仍然存在时,我们将创建一个超时,在设定的时间范围(在本例中为 5 秒)后执行回调。回调将调度一个反向通道事件以通知机器人用户已超过分配的时间间隔不活动,并且机器人可以相应地响应。我们将为反向通道事件添加一个名称 - 'inactive' - 这样我们就可以在机器人端识别它。

    当用户发送消息时,我们将清除机器人发送消息时创建的超时,因此不会执行回调,因为用户在分配的时间范围内响应。详情见下方代码sn-p。

    let interval;
    
    // We are using a customized store to add hooks to connect event
    const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
    
      if (action.type === 'WEB_CHAT/SEND_MESSAGE') {
        // Message sent by the user
        clearTimeout(interval);
      } else if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY' && action.payload.activity.name !== "inactive") {
        // Message sent by the bot
        clearInterval(interval);
        interval = setTimeout(() => {
          // Notify bot the user has been inactive
          dispatch({
            type: 'WEB_CHAT/SEND_EVENT',
            payload: {
              name: 'inactive',
              value: ''
            }
          });
        }, 5000)
      }
    
      return next(action);
      });
    
    window.WebChat.renderWebChat({
    directLine: window.WebChat.createDirectLine({ token }),
    store,
    }, document.getElementById('webchat'));
    

    聊天机器人

    我们可以在 BotChat 中创建相同的效果——在 bot 发送消息时创建超时,并在用户发送消息时清除超时;但是,我们必须创建一个自定义 DirectLine 对象来查看用户何时发送消息并订阅和过滤活动,以便我们可以识别机器人何时发送消息。详情见下方代码sn-p。

    let timeout;
    let dl = new BotChat.DirectLine({ secret: <Secret> });
    
    BotChat.App({
      botConnection: { ...dl,
        postActivity: activity => {
          // Listen for when the user sends a message and clear the timeout;
          clearTimeout(timeout);
          return dl.postActivity(activity);
        }
      },
      user: { id: 'userid' },
      bot: { id: 'botid' },
      resize: 'detect'
    }, document.getElementById("bot"));
    
    // Listen for incoming activities from the bot and create timeout
    dl.activity$
      .filter(activity => activity.name !== 'inactive')
      .filter(activity => activity.from.id !== 'userid')
      .subscribe(activity => {
    
        clearTimeout(timeout);
        timeout = setTimeout(() => {
          // Notify bot the user has been inactive
          dl.postActivity({
            type: 'Event',
            value: '',
            from: {
              id: 'userid'
            },
            name: 'inactive'
          })
          .subscribe()
        }, 5000);
      })
    

    机器人代码 - 节点

    在 Bot 的 onTurn 方法中,我们将检查是否有任何传入活动被命名为“非活动”。如果活动被命名为不活动,则发送活动询问用户是否还在;否则,继续正常的机器人对话框。我们还将将该活动命名为询问用户是否存在“不活动”,这样我们就不会在用户没有响应时每五秒创建一个新的超时。见下面的代码sn-p。

    async onTurn(turnContext) {
        if(turnContext.activity.type === ActivityTypes.Event) {
            if (turnContext.activity.name && turnContext.activity.name === 'inactive') {
                await turnContext.sendActivity({
                    text: 'Are you still there?',
                    name: 'inactive'
                });
            } 
            ...
        }
        ...
    }
    

    希望这会有所帮助!

    【讨论】:

    • 嗨..非常感谢您的快速帮助。我尝试实现上述逻辑,但是当加载网页时,在 turnContext JSON 中没有名称为“inactive”。 _activity":{"type":"conversationUpdate","id":"5U8tzdNdNWA","timestamp":"2019-03-04T08:08:54.8394652Z","serviceUrl":"directline.botframework.com/…":{"id ”:”YYY”},”conversation”:{“id”:”AAA”},”recipient”:{“id”:”XXX”,”name”:“AD Swarm_Bot”},”membersAdded”:[{ "id":"TTT","name":"AD Swarm_Bot"}]}}
    • 在bot端和WebChat/BotChat端的activity中添加name属性来识别我们什么时候需要设置和清除超时。看一下上面的代码sn-ps。您使用的是 WebChat 还是 BotChat?
    • 我正在使用网络聊天
    • 只有一些 Message 类型的活动应该有 name 属性。看起来您的机器人正在检查名称属性的对话更新,这应该会引发错误,因为活动不会有它。首先检查以确保活动是一条消息。我更新了上面的机器人代码以反映这一变化。
    • @tdurnford 我认为这可能不再准确。它对我不起作用,当监控活动时,它显示为类型Event,而不是Message。如有必要,您能否验证并更新答案?当我将条件更改为 turnContext.activity.type === ActivityTypes.Event 时,它运行良好。
    猜你喜欢
    • 1970-01-01
    • 2021-05-24
    • 1970-01-01
    • 2018-03-07
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 2023-04-08
    相关资源
    最近更新 更多