Как повторить запрос на выбор в боте Microsoft для команд?

#node.js #botframework #microsoft-teams

Вопрос:

У меня есть бот Microsoft Teams, созданный с помощью NodeJS для пользователя, чтобы получить некоторые данные с помощью диалогового потока.

 constructor(id) {
    super(id);

    this.addDialog(
        new WaterfallDialog(WATERFALL_DIALOG, [
            this.getData1.bind(this),
            this.getChoice.bind(this),
            this.getData2.bind(this),
        ])
    )
    .addDialog(new TextPrompt(TEXT_PROMPT))
    .addDialog(new ChoicePrompt(CHOICE_PROMPT));

    this.initialDialogId = WATERFALL_DIALOG;
}
 
 async getData1(stepContext) {
    if (stepContext.context.activity.text) {
        var name = stepContext.context.activity.text;
        var result =  await axios({
            method: 'get',
            url: '<apiUrl>',
            headers: {
                "Accept": "application/json"
            }
        }).then(function(response) {
            var data = response.data;
            var cardButtons = [];
            var cardText = "";
                
            if (data.length > 0) {
                data.forEach(element => {
                    cardButtons.push({
                        type: ActionTypes.ImBack,
                        title: element.name,
                        value: element.name
                    });
                });
                cardText = "Data for "   name    ".";
           } else {
               cardText = "No Data Found.";
               cardButtons = null;
           }
           var dataCard = CardFactory.heroCard("Data-I", null, cardButtons, {
               text: cardText
            });
            return dataCard;
        }).catch(error => {
            console.log("Error > "   error);
        });
        if (result) {
            await stepContext.context.sendActivity({attachments: [result]});
        } else {
            await stepContext.context.sendActivity("Sorry, it looks like something went wrong. Please try again.");
            return await stepContext.endDialog();
        }
        const messageText = 'Select/Enter Data to View.';
        const msg = MessageFactory.text(messageText, messageText, InputHints.ExpectingInput);
        return await stepContext.prompt(TEXT_PROMPT, { prompt: msg });
    } else {
        await stepContext.context.sendActivity("Sorry, it looks like something went wrong. Please try again.");
        return await stepContext.endDialog();
    }
}
 
 async getChoice(stepContext) {
    return await stepContext.prompt(CHOICE_PROMPT, {
        prompt: 'Please select the data2 options.',
        choices: ChoiceFactory.toChoices(['Option A', 'Option B', 'Option C', 'Option D']),
        style: ListStyle.heroCard
    });
}
 
 async getData2(stepContext) {
    var dataChoice = null;
    if (stepContext.result) {
        dataChoice = stepContext.result
    }
    var result =  await axios({
        method: 'get',
        url: '<data2apiUrl>',
        headers: {
            'Accept': 'application/json',
            'dataChoice': dataChoice
        }
    }).then(function (response) {
        var data = response.data;
        console.log("Data KPI > ", JSON.stringify(data));
        var body = [];

        if (data.length > 0) {
            data.forEach(element => {
                var header = {
                    "type": "Container",
                    "spacing": "medium",
                    "style": "emphasis",
                    "verticalContentAlignment": "center",
                    "items": [
                        {
                            "type": "TextBlock",
                            "text": element.fullTitle,
                            "size": "medium",
                            "horizontalAlignment": "center",
                            "weight": "bolder",
                            "wrap": true
                        }
                    ]
                }
                body.push(body);
            });
        } else {
            //Recall the Choice Prompt
        }

        var dataCard = CardFactory.adaptiveCard({
            "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
            "type": "AdaptiveCard",
            "version": "1.0",
            "body": body
        });
        return dataCard;
    }).catch(error => {
        console.log("Error > "   error);
    });
    if (result) {
        await stepContext.context.sendActivity({attachments: [result]});
    } else {
        await stepContext.context.sendActivity("Sorry, it looks like something went wrong. Please try again.");
    }
    return await stepContext.endDialog();
 }
 

Так что это тот диалоговый поток, который у меня есть. Теперь getChoice(stepContext) ,если я выберу вариант, для которого у меня нет никаких данных, я хочу, чтобы бот снова вызвал этот getChoice(stepContext) шаг вместо того, чтобы использовать stepContext.endDialog() и повторять все это снова с первого шага диалогового окна, т. Е. getData1(stepContext)

Ответ №1:

Вы можете использовать валидаторы. проверьте этот образец.

.addDialog(new ChoicePrompt(SKILL_ACTION_PROMPT, this.skillActionPromptValidator))

 /**
* This validator defaults to Message if the user doesn't select an existing option.
*/
 async skillActionPromptValidator(promptContext) {
    if (!promptContext.recognized.succeeded) {
        promptContext.recognized.value = { value: SKILL_ACTION_MESSAGE };
    }

    return true;
}
 

Взгляните на документ, показывающий валидаторы выбора.

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

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

1. Я не смотрю на то, выбирает ли пользователь правильный вариант. Учитывая, что гарантируется, что пользователь обязательно выберет один из предоставленных вариантов, я хочу, чтобы выбранный пользователем параметр не содержал данных с помощью вызова API на этом getData2() шаге, я хочу ChoicePrompt , чтобы он снова был показан пользователю.

2. Похоже, вы можете переместить код из getData2 в валидатор, если у вас есть какие-то данные, тогда вы продолжаете.

3. Я создал новый диалог водопада с getChoice() и в getData2() качестве шагов в водопаде. Это работает на меня. Спасибо за эту помощь, хотя буду иметь в виду, если столкнусь с подобной проблемой.

4. О, Удивительно. Спасибо, что поделился.