如何使用BotFramework SDK V4 NodeJS执行stepContext.prompt()并自动将其移至WaterfallDialog中的下一步

时间:2019-11-05 19:02:58

标签: node.js azure botframework

我正在使用Microsoft BotBuilder V4 NodeJs SDK进行机器人开发。我遇到一个我想起瀑布对话框的问题。在内部,异步step()之一-我正在调用作为textPrompt类型的hint()的调用。 在这里,我面临的问题是: 在Waterfall Dialog的第一个初始执行周期上-hint()正常工作。 但是,在第二次调用相同的瀑布对话框时-prompt()不会等待用户输入文本。相反,它会自动移至下一个异步step()。

如何在不向机器人发送其他消息的情况下移至瀑布对话框中的下一个异步step()函数?

 const { ComponentDialog, TextPrompt, WaterfallDialog } = 
 require('botbuilder-dialogs');
 const { CardFactory, ActionTypes } = require('botbuilder');
 const initialId = 'Main_Dialog';
 const MAIN_WATERFALL_DIALOG = 'mainDWaterfallDialog';
class Main_Dialog extends ComponentDialog {
constructor(conversationState, userState, luisApplication, luisPredictionOptions) {
    super('Main_Dialog');

    this.luisRecognizer = new LuisRecognizer(luisApplication, luisPredictionOptions, true);

    this.conversationData = conversationState.createProperty("mainDialog");
    this.userProfile = userState.createProperty("mainDialog");

    // Create our bot's dialog set, adding a main dialog and their component dialogs.
    this.addDialog(new TextPrompt('PromptTextPrompt', this.waitForUserPromptValidator))
        .addDialog(new MyAdaptiveBot('MyAdaptiveBot'))
        .addDialog(new Welcome_C_Dialog('Welcome_C_Dialog'))
        .addDialog(new WaterfallDialog(MAIN_WATERFALL_DIALOG, [
            this.introStep.bind(this),
            this.actStep.bind(this),
            this.finalStep.bind(this)
        ]));

    this.initialDialogId = MAIN_WATERFALL_DIALOG;
    this.query_flag = false;
    this.process_flag = false;
}


async run(turnContext, accessor) {
    const dialogSet = new DialogSet(accessor);
    dialogSet.add(this);

    const dialogContext = await dialogSet.createContext(turnContext);
    const results = await dialogContext.continueDialog();
    if (results.status === DialogTurnStatus.empty) {
        await dialogContext.beginDialog(this.id);
    }
}

async introStep(stepContext) {
    if (this.recognizer !== undefined) {
        throw new Error('[MainDialog]: LUIS LuisRecognizer not configured properly');
    }

    return await stepContext.prompt('PromptTextPrompt', 'What can I do for you?', {retryPrompt: 'Sorry, please submit your adverse event case. Otherwise, say cancel.'});
}


async actStep(stepContext) {


        const luisResult = await this.luisRecognizer.recognize(stepContext.context);
        let switch_case = LuisRecognizer.topIntent(luisResult);

        switch (switch_case) {
            case "Greetings":
                // await turnContext.sendActivity(`Welcome to AECaseBuilder!`);
                this.query_flag = true;    // set - true query_flag
                await stepContext.beginDialog('Welcome_C_Dialog');
                break;

            case "Enquiry":
                //const user_inp = turnContext.activity.text;
                await stepContext.beginDialog('MyAdaptiveBot', null);
                this.query_flag = false;    // reset query_flag
                break;


            default:
                // Catch all for unhandled intents
                break;
        }

    return await stepContext.next();
}

async finalStep(stepContext) {

    // Restart the main dialog with a different message the second time around
    const messageText = "Whats else can I do for you?";
    return await stepContext.replaceDialog(this.initialDialogId, { restartMsg: messageText });
}
async waitForUserPromptValidator(promptContext){
    console.log(`prompt : ${promptContext.recognized.value}`);
    if(promptContext.recognized.value.trim() === ''){
            return false;
    }
    return true;
}
}

module.exports.Main_Dialog = Main_Dialog;




 //@File: Welcome_C_Dialog

 const { ComponentDialog, TextPrompt, WaterfallDialog } = require('botbuilder-dialogs');
 const { CardFactory, ActionTypes } = require('botbuilder');

 const initialId = 'Welcome_C_Dialog';
 const welcomeCard = require('./resources/welcome_acb.json');

 class Welcome_C_Dialog extends ComponentDialog {
    /**
     * 
     * @param {*} id
     * @method - constructor()
     * @returns - void 
     */
   constructor(id){
           super(id);

           // ID of the child dialog that should be started anytime the component is started.
           this.initialDialogId = initialId;

           // Define the prompts used in this conversation flow.
           this.addDialog(new TextPrompt('textPrompt', this.waitForInputValidator));

           // Define the conversation flow using a waterfall model.
           this.addDialog(new WaterfallDialog(initialId,[
                       // dialog steps
                       async function(step){
                               // Clear the case information and prompt for user to submit new case intake.
                               step.values.caseInfo = {};
                               await step.context.sendActivity({
                                   text: "",
                                   attachments: [CardFactory.adaptiveCard(welcomeCard)]
                               });

                            //    return await step.prompt('textPrompt', 'Waiting for your case intake...',{ 
                            //            retryPrompt: 'Sorry, please submit your case for AECaseBuilder or say cancel.'
                            //    });
                            //    return MyAdaptiveDialog.EndOfTurn;
                               return await step.endDialog();
                       }/*, 
                       async function(step){
                               await step.context.sendActivity('received case...');
                               const resultValue = step.result;
                               //console.log(` input text: ${resultValue}`);
                               step.values.caseInfo.inputText = resultValue;

                               return await step.endDialog({inputText: resultValue});
                       }*/
           ]));

   }

   /**
    * 
    * @param {*} promptContext 
    * @method waitForInputValidator()
    * @returns true if case input received successfully. Otherwise, returs false.
    */
   async waitForInputValidator(promptContext){
           //console.log(`prompt : ${promptContext.recognized.value}`);
            if(promptContext.recognized.value.trim() === ''){
                    return false;
            }
            return true;
   }
}

exports.Welcome_C_Dialog = Welcome_C_Dialog;

0 个答案:

没有答案