Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
412 views
in Technique[技术] by (71.8m points)

node.js - Set Timer Using Microsoft Bot Framework

If user doesn't respond to bot for more than 5 sec,Bot should prompt "are you there".To implement this logic, could you please help, how to set timer in chat bot using Node Js SDK and V4 version in Microsoft Bot framework

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

After a certain period of inactivity from the user, you can have WebChat or BotChat send a back-channel event to the bot, and the bot can respond by asking the user if they are still there. Note, I would recommend using WebChat since BotChat has been depreciated and the implementation in WebChat is slightly cleaner.

enter image description here

WebChat

In WebChat, we are going to create a custom store and middleware to listen for events where the user sends a message and when the bot sends a message - WEB_CHAT/SEND_MESSAGE and DIRECT_LINE/INCOMING_ACTIVITY respectively.

When the bot sends a message that isn't asking the user if they are still there, we will create a timeout that executes a callback after a set time frame - in this case, five seconds. The callback will dispatch a back-channel event to notify the bot that the user has been inactivity for more than the allotted time interval and the bot can respond accordingly. We will add a name to the back channel event - 'inactive' - so we can identify it on the bot side.

When the user sends a message, we will clear the timeout that was created when the bot sent a message, so the callback won't be executed since the user responded within the allotted time frame. See the code snippet below for more details.

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

We can create the same effect in BotChat - creating a timeout when the bot sends a message and clearing the timeout when the user sends a message; however, we have to create a custom DirectLine Object to see when the user sends a message and subscribe to and filter the activities so we can identify when the bot sent a message. See the code snippet below for more details.

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 Code - Node

In the Bot's onTurn method, we are going to check if any incoming activities are named 'inactive.' If the activity is named inactive, send an activity asking if the user is still there; otherwise, continue with the normal bot dialog. We are also going to name the activity asking the user if they're there 'inactive' so we don't create a new timeout every five seconds while the user doesn't respond. See the code snippet below.

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'
            });
        } 
        ...
    }
    ...
}

Hope this helps!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.8k users

...