Search code examples
c#botframeworkchatbotazure-qna-maker

How to call a QNA bot with in a waterfall dialog?


Say example when we have 3 menu( choices ) within a waterfall dialog in an initial step, when user selected third choice, the system should take over to qna bot form that , is that something possible ?


Solution

  • Nodejs here instead of C# but hopefully this will point you in the right direction. You can do this, you just need to create a separate QnA Dialog and call it from within your waterfall via await step.beginDialog(YOUR_QNA_DIALOG_NAME). You would want that dialog to prompt for the question in the first step, provide the answer in the second step, and (if desired) prompt if they want to ask another question so you can loop via replaceDialog. If there are steps after the initial menu selection, you may wish to cancellAllDialogs instead of endDialog when they exit, otherwise the bot will pick up where it left off with the first dialog.

    There might be a more elegant way to do this without using a waterfall dialog but I haven't found it yet.

    I have provided a sample QnA Dialog below, but note that in this case I am using it as a default action if no intent is recognized, so it's using the activity.text from the ActivityHandler instead of explicitly prompting the user, and it does not loop. Still, I though this might be helpful.

    // Copyright (c) Microsoft Corporation. All rights reserved.
    // Licensed under the MIT License.
    
    const { Dialog, MessageFactory } = require('botbuilder');
    const { QnAServiceHelper } = require('../helpers/qnAServiceHelper');
    const { CardHelper} = require('../helpers/cardHelper');
    
    class QnADialog {
    
        constructor() {
    
        }
    
        async processAsync(oldState, activity){
    
            const defaultAnswer = `I'm sorry, I don't know how to help with that. Try asking a different question or type "Help" for options.`;
            var MINIMUM_SCORE = 50;
    
            var newState = null;
            var query = activity.text;
            var qnaResult = await QnAServiceHelper.queryQnAService(query, oldState);
            var qnaAnswer = qnaResult[0].answer;
    
            var prompts = null;
            if(qnaResult[0].context != null){
                prompts = qnaResult[0].context.prompts;
            }
    
            var outputActivity = null;
            if (prompts == null || prompts.length < 1) {
                if (qnaResult[0].score > MINIMUM_SCORE) {
                    outputActivity = MessageFactory.text(qnaAnswer);
                } else {
                    outputActivity = MessageFactory.text(defaultAnswer);
                }
            }
            else {
                var newState = {
                    PreviousQnaId: qnaResult[0].id,
                    PreviousUserQuery: query
                }
    
                outputActivity = CardHelper.GetHeroCard('', qnaAnswer, prompts);
            }
    
            return [newState, outputActivity , null];
        }  
    }
    
    module.exports.QnADialog = QnADialog;