Search code examples
c#.net-corebotframeworkchatbotweb-chat

Set Timer Using Microsoft Bot Framework in chat bot using c# and v4 version in Micorsoft bot framework


Hello someone would have an example of a web chat timeout implementation. Let me explain I want my bot to receive an event after 5 seconds of inactivity from the user to send him a message (are you there?) following a response or question from the bot. I am new to bot framework and use .net core. thank you in advance for your feedback


Solution

  • I can't help with C#, but I had an implementation of exactly this in nodejs which maybe you can adapt. The basic process is this:

    In your onMessage handler:

    1. Get your conversation state object (I have called it conversationData)
    2. Get the current conversation reference and save to conversation state
    3. Clear the timer object (e.g. this.inactivityTimer) Set a new instance of the timer
    4. When timer runs, start a new instance of BotFrameworkAdapter to send proactive message
    5. Send the inactivity message to the user

    Note that in addition to setting the timeout value, you need to pass in your conversation reference (or the entire conversation state object). Here is a specific example I used:

    // Inactivity messages
    // Reset the inactivity timer
    clearTimeout(this.inactivityTimer);
    this.inactivityTimer = setTimeout(async function(conversationReference) {
        console.log('User is inactive');
        try {
            const adapter = new BotFrameworkAdapter({
                appId: process.env.microsoftAppID,
                appPassword: process.env.microsoftAppPassword
            });
            await adapter.continueConversation(conversationReference, async turnContext => {
                await turnContext.sendActivity('Are you still there?');
            });
        } catch (error) {
            //console.log('Bad Request. Please ensure your message contains the conversation reference and message text.');
           console.log(error);
        }
    }, 300000, conversationData.conversationReference);
    

    If you don't want to use proactive messages and/or render a new bot adapter and you are doing this for directline channel only, you can create a custom event from your website and set up an onEvent handler to look for it. For example, if you send an event called "inactive", you can in your event handler do something like

    if (context.activity.name && context.activity.name === 'inactive') {
        await context.sendActivity({
            text: 'Are you still there? Is there anything else I can help you with?',
            name: 'inactive'
        });
    }
    

    This will require you to have some sort of custom store. I'm not doing this anymore, but here is an example of one I had on a page at one point. I believe it should still work. You can see it is very similar to my onMessage handler, though a bit more complex due to the way you have to check the messages. I also had code to change the page title for more visibility. For what it's worth, in my case users hated it (the notification in general but especially the page flash). But it can be done.

                const store = window.WebChat.createStore({}, function(dispatch) { return function(next) { return function(action) {
                    if (action.type === 'WEB_CHAT/SEND_MESSAGE') {
                        // Message sent by the user
                        PageTitleNotification.Off();
                        clearTimeout(interval);
                    } else if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY' && action.payload.activity.name !== "inactive") {
                        // Message sent by the bot
                        clearInterval(interval);
                        interval = setTimeout(function() {
                            // Change title to flash the page
                            PageTitleNotification.On('Are you still there?');
                            
                            // Notify bot the user has been inactive
                            dispatch.dispatch({
                                type: 'WEB_CHAT/SEND_EVENT',
                                payload: {
                                    name: 'inactive',
                                    value: ''
                                }
                            });
                            
                        }, 300000)
                    }
    
                    return next(action);
                }}});