Managing Timeouts in Bot Framework

In Artificial Intelligence by Christian HissibiniLeave a Comment

Let’s walk through a few strategies for managing timeouts and updating your bot. I’m not going to walk through every possibility, but rather show off a few representative solutions that will hopefully illustrate how to approach the problem, and provide enough information for you to implement what’s needed.

Adding a timeout

As mentioned above, a bot doesn’t timeout. As a result, if it’s been even a few days since the user last replied, the bot is going to attempt to pick up where it left off. This can either confuse the user, or operate on bad information, neither of which is a good thing.

Reset the conversation

The first potential solution, and the easiest to implement, is to simply reset the conversation. We’ll do this by adding a lastAccess property to userData. We’ll then query this to see how long it’s been since the user last talked to the bot, and, if necessary, reset the conversation.

We determine if the user is currently in a conversation by taking a look at the dialogStack and determining if there is at least one dialog there. Our threshold is 10 seconds, which is obviously artificially small, but I want you to be able to easily test the implementation.

bot.use(
    {
        botbuilder: (session, next) => {
            // grab the current time
            const currentTime = Date.now();
            // see how long it's been (in milliseconds) since the user last 
            // accessed the bot
            const lastAccessGap = currentTime - session.userData.lastAccess;
            // update the last access
            session.userData.lastAccess = currentTime;
            // see if there is a dialog and it's been greater than 10 seconds
            // since the user last talked to the bot
            if(session.dialogStack().length > 0 && lastAccessGap > 10000) {
                // a couple of friendly messages
                session.send(`Hey there! It looks like it's been a while since you were last here.`);
                session.send(`Let's start over to make sure we're both on the same page.`);
                // reset the conversation, sending the user to the root dialog
                session.reset('/');
            } else {
                // allow the flow to continue as normal
                next();
            }
        },
    }
)

Ask the user what they want to do

The next possibility, and slightly more advanced, is to ask the user what they want to do. We’ll use the same timestamp technique as above, but this time we’ll route the user to a confirmation dialog. If they say yes, we’ll end the dialog, which will reprompt the user. If they say no, we’ll reset the dialog like before. Again, the threshold is artificially small for testing purposes.


bot.use(
    {
        botbuilder: (session, next) => {
            // grab the current time
            const currentTime = Date.now();
            // see how long it's been (in milliseconds) since the user last 
            // accessed the bot
            const lastAccessGap = currentTime - session.userData.lastAccess;
            // update the last access
            session.userData.lastAccess = currentTime;
            // see if there is a dialog and it's been greater than 10 seconds
            // since the user last talked to the bot
            if(session.dialogStack().length > 0 && lastAccessGap > 10000) {
                // begin the confirmation dialog
                session.beginDialog('confirm-continue');
            } else {
                // allow the user to continue as normal
                next();
            }
        },
    }
)

bot.dialog('confirm-continue', [
    (session, args) => {
        // prompt the user
        builder.Prompts.confirm(session, `It looks like you've been gone for a little while. Do you want to continue where you left off?`);
    },
    (session, results) => {
        if(results.response) {
            // redirect back to the original dialog
            // the last active prompt will be re-run
            session.endDialog(`Sounds good. Here's the last question I asked you:`);
        } else {
            // reset the conversation
            session.send(`Sounds good. Let's start over.`);
            session.reset('/');
        }
    }
]);

Some thoughts on timeouts

It’s really up to you to decide how to best manage timeouts and what works best for your bot. You might decide to time the user out after twenty minutes, or maybe a couple of hours. You might automatially reset, especially in simpler two or three turn dialogs, or to prompt the user for more complex bots. You might even go a couple steps further, detecting which dialog the user is in, and make the decision based on that.

Leave a Comment