首页 > 解决方案 > 如何在bot框架javascript中从欢迎开始对话框

问题描述

我想在 bot 框架 sdk 中使用 javascript 从 Welcome 开始一个多级多选对话框。我有一个调用 LUIS 来预测意图的主对话框 (finalAnswerDialog),还有一个多级多选菜单对话框 (menuDialog) 来引导用户了解一些意图。我希望机器人从一开始就显示菜单对话框,但我总是出错。这是我的代码:

dialogAndWelcomeBot

const { CardFactory } = require('botbuilder');
const { DialogBot } = require('./dialogBot');
const { ActivityHandler, MessageFactory } = require('botbuilder');
const { ActionTypes } = require('botframework-schema');
const { MenuDialog } = require('../dialogs/menuDialog');

class DialogAndWelcomeBot extends DialogBot {
    constructor(conversationState, userState, dialog) {
        super(conversationState, userState, dialog);
        this.onMembersAdded(async (context, next) => {
            const membersAdded = context.activity.membersAdded;
            for (let cnt = 0; cnt < membersAdded.length; cnt++) {
                if (membersAdded[cnt].id !== context.activity.recipient.id) {
                    await dialog.run(context, conversationState.createProperty('DialogState'));
                    await step.beginDialog('menuDialog');
                }
            }

            // By calling next() you ensure that the next BotHandler is run.
            await next();
        });
    }
}


module.exports.DialogAndWelcomeBot = DialogAndWelcomeBot;

menuDialog调用 finalAnswerDialog 以便在任何时候管理 LUIS 调用

class MenuDialog extends ComponentDialog {
    constructor(finalAnswerDialog) {
        super('menuDialog');

        this.answered=true;
        this.addDialog(new TextPrompt(TEXT_PROMPT));
        this.addDialog(new TextPrompt(NAME_PROMPT));
        this.addDialog(new ChoicePrompt(CHOICE_PROMPT));
        this.addDialog(new ConfirmPrompt(CONFIRM_PROMPT));
        this.addDialog(finalAnswerDialog);

        this.addDialog(new WaterfallDialog(WATERFALL_DIALOG, [
            this.firstQuestion.bind(this),
            this.secondQuestion.bind(this),
            this.thirdQuestion.bind(this),
            this.answerTheQuestion.bind(this),
            this.finalStep.bind(this)
        ]));
        
        this.initialDialogId = WATERFALL_DIALOG;
    }

最终答案对话框

class FinalAnswerDialog extends ComponentDialog {
    constructor(luisRecognizer) {
        super('finalAnswerDialog');

        if (!luisRecognizer) throw new Error('[MainDialog]: Missing parameter \'luisRecognizer\' is required');
        this.luisRecognizer = luisRecognizer;

        // Define the main dialog and its related components.
        // This is a sample "book a flight" dialog.
        this.addDialog(new TextPrompt('TextPrompt'));
        this.addDialog(new WaterfallDialog(MAIN_WATERFALL_DIALOG, [
                //this.initStep.bind(this),
                this.actStep.bind(this),

            ]));

        this.initialDialogId = MAIN_WATERFALL_DIALOG;
    }

    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 initStep(stepContext) {
        return await stepContext.prompt(TEXT_PROMPT, promptOptions);
    }

    async actStep(stepContext) {
        if (!this.luisRecognizer.isConfigured) {
            const messageText = 'NOTE: LUIS is not configured. To enable all capabilities, add `LuisAppId`, `LuisAPIKey` and `LuisAPIHostName` to the .env file.';
            await stepContext.context.sendActivity(messageText, null, InputHints.IgnoringInput);
            return await stepContext.next();
        }

        const luisResult = await this.luisRecognizer.executeLuisQuery(stepContext.context);
        let top_intent = LuisRecognizer.topIntent(luisResult)
        //let top_intent="contacto"
        console.log("intent predicha por Luis: " + top_intent)
        
        switch (top_intent) {
//SendActivity

index.js

const dialog = new FinalAnswerDialog(luisRecognizer);
const bot = new DialogAndWelcomeBot(conversationState, userState, dialog);

如何在欢迎中启动菜单对话框?

标签: javascriptazure-bot-service

解决方案


是的,您可以从欢迎代码启动特定(菜单/任何)对话框。

关键是不要conversationUpdate从你的机器人代码中使用,而是从客户端提交一个事件活动,并添加一些代码来处理你的机器人代码中的事件。

以事件处理程序的形式添加活动,请参阅如何发送问候消息和常见问题


还有另一种解决方案是存储用户 ID 和会话的映射,然后使用 seesion.send 将对话发送给相应的用户。在大多数情况下,使用conversationUpdate可能是您最好的选择。

演示欢迎代码:

bot.on('conversationUpdate', function(message) {
  if (message.membersAdded) {
    message.membersAdded.forEach(function(identity) {
      if (identity.id === message.address.bot.id) {
        var reply = new builder.Message()
          .address(message.address)
          .text("Welcome");
        bot.send(reply);
      }
    });
  }
});

要调用特定对话框,请执行以下操作:

bot.on('conversationUpdate', function (message) {
  if (message.membersAdded) {
    message.membersAdded.forEach(function (identity) {
      if (identity.id === message.address.bot.id) {
        bot.beginDialog(message.address, '/main');
      }
    });
  }
});

bot.dialog('/main', [
  function (session, args, next) {
    session.send("Glad you could join.");
    session.beginDialog('/next');
  }
]);

上面的代码是欢迎信息和启动对话框的组合。您也可以在此处找到类似的SO 线程


推荐阅读