Водопад в каталогах компонентов

#node.js #botframework #azure-bot-service

#node.js #botframework #azure-бот-сервис

Вопрос:

У меня возникли проблемы с реализацией WaterfallDialogs в ComponentDialogs , инициируемой LUIS в BotFramework V4.2 . После первого шага диалоговое окно не продолжает водопад. Я не совсем понимаю, каким должен быть правильный подход для сохранения ComponentDialog : save ConversationState ? установите step.context ? Я пробовал оба, но пока у меня ничего не получалось 😣

Это мой код для bot.js, где у меня есть экземпляр LUIS для выполнения функций оркестратора между диалоговыми окнами:

 async onTurn(turnContext) {
...
switch (dialogResult.status) {
   case DialogTurnStatus.empty:
      // Call to LUIS recognizer to get intent   entities
      const results = await this.luisRecognizer.recognize(dc.context);
      const topIntent = results.luisResult.topScoringIntent;

      switch (topIntent.intent) {
          case FMM_INTENT:
              return await dc.beginDialog(FeedbackDialog.Name);
          ...
      }
   case DialogTurnStatus.waiting:
      // The active dialog is waiting for a response from the user, so do nothing
       break;
...
}
  

И это мой код для FeedbackDialog.js где у меня есть логика WaterfallDialog с Prompts :

 module.exports = {
FeedbackDialog: class extends ComponentDialog {
    static get Name() { return DIALOG_NAME; }
    constructor(conversationState, botConfig, feedbackStateAccessor, dialogId) {
        (dialogId === undefined) ? super(DIALOG_NAME) : super(dialogId);

        this.conversationState = conversationState;
        this.feedbackStateAccessor = feedbackStateAccessor;

        this.addDialog(new WaterfallDialog(FBK_EVAL, [
            this.feedbackPrompt.bind(this),
            this.feedbackEvaluation.bind(this)
        ]));

        this.addDialog(new ChoicePrompt(FBK_PROMPT));
    }

    async feedbackPrompt(step) {
        let fmmState = await this.feedbackStateAccessor.get(step.context);
        if (fmmState === undefined) {
            await this.feedbackStateAccessor.set(step.context);
            //opciones válidas, las mayúsculas las detecta también
            const options = ['👍','👎'];
            return await step.prompt(FBK_PROMPT, {
                prompt: `¿Te ha resultado útil la respuesta?`,
                retryPrompt: `¿Qué te ha parecido la respuesta?`,
                choices: options
            });
        }
    }

    async feedbackEvaluation(step) {
        let fmmState = await this.feedbackStateAccessor.get(step.context);
        if (fmmState === undefined amp;amp; step.result){
            if (step.result == '👍'){
                await step.context.sendActivity("¡Gracias por el feedback!");
                return await step.endDialog();
            }else {
                await step.context.sendActivity("¡Revisaremos tu pregunta para seguir mejorando!");
                return await this.conversationState.saveChanges(step.context);
            }             
        } else {
            return await step.next();
            //next steps omitted since the code doesn't reach this step
        }          
    }
  

Ответ №1:

Я не уверен, чего вы пытаетесь достичь, но если вы используете ChoicePrompt, я полагаю, что результат шага возвращается в ключ значения, т. Е. вместо

 if (step.result == '👍') 
  

попробуйте

 if (step.result.value === '👍')
  

Затем вы можете отправить сообщение обратно пользователю и завершить диалоговое окно, и все должно быть в порядке:

 await step.context.sendActivity("¡Gracias por el feedback!");
return step.endDialog();
  

или

 await step.context.sendActivity("¡Revisaremos tu pregunta para seguir mejorando!");
return step.endDialog();
  

Кроме того, не забудьте правильно инициализировать диалоговое окно, то есть в вашем файле bot:

 const { FeedbackDialog } = require('path/to/feedbackDialog')
const FEEDBACK_DIALOG = 'FeedbackDialog'
const FEEDBACK_PROPERTY = 'feedbackProperty'
  

и в конструкторе бота (я использую UserState для средств доступа к состояниям, а не для состояния разговора):

 this.dialogs = new DialogSet(this.dialogState)
this.feedbackAccessor = userState.createProperty(FEEDBACK_PROPERTY)
this.dialogs.add(new FeedbackDialog(
  FEEDBACK_DIALOG,
  this.feedbackAccessor
))
  

затем вызовите его как:

 await dc.beginDialog(FEEDBACK_DIALOG);
  

Комментарии:

1. Спасибо @Naadof, моя проблема заключалась в использовании ConversationState для средств доступа к состояниям. Я перешел на UserState, и теперь все работает нормально. Что касается ChoicePrompt , я не уверен, что это лучший подход, но step.result отлично работает, если у кого-то возникает такой же вопрос