我用Microsoft BotFramework实现了一个机器人。为了收集用户数据,我使用ChoicePrompts。当用户未选择建议的选项之一时,ChoicePrompt会重复进行,直到用户输入有效的选项为止(这是提示方法的默认行为)。

不幸的是,在未选择有效选择选项之一之后,将刷新用户状态。这意味着到那时我将丢失所有收集的用户数据。

这是故意的行为还是有防止这种行为的方法?

最佳答案

您提供的链接上的代码有几个问题。由于看不到您的完整代码,因此在某些部分进行了猜测。


仔细检查userState和userData是否正确设置。我的构造函数如下所示:


const DIALOG_STATE_PROPERTY = 'dialogState';
const USER_PROFILE_PROPERTY = 'user';

const EDUCATION_PROMPT = 'education_prompt';
const MAJOR_PROMPT = 'major_prompt';

constructor(conversationState, userState) {
    this.conversationState = conversationState;
    this.userState = userState;

    this.dialogState = this.conversationState.createProperty(DIALOG_STATE_PROPERTY);
    this.userData = this.userState.createProperty(USER_PROFILE_PROPERTY);

    this.dialogs = new DialogSet(this.dialogState);

    // Add prompts that will be used by the main dialogs.
    this.dialogs
        .add(new TextPrompt(NAME_PROMPT))
        .add(new TextPrompt(AGE_PROMPT))
        .add(new TextPrompt(GENDER_PROMPT))
        .add(new ChoicePrompt(EDUCATION_PROMPT))
        .add(new ChoicePrompt(MAJOR_PROMPT));

    // Create dialog for prompting user for profile data
    this.dialogs.add(new WaterfallDialog(START_DIALOG, [
        this.promptForName.bind(this),
        this.promptForAge.bind(this),
        this.promptForGender.bind(this),
        this.promptForEducation.bind(this),
        this.promptForMajor.bind(this),
        this.returnUser.bind(this)
    ]));

    this.majors = ['English', 'History', 'Computer Science'];
}



请记住,TextPrompt返回step.result中的值。 ChoicePrompt返回该值作为step.result.value

我假设在您的“ promptForEducation”步骤中,您将性别值分配给用户该值来自选择提示。否则,您将失去价值。仔细检查您是否指定了正确的来源。


.add(new TextPrompt(GENDER_PROMPT))
.add(new ChoicePrompt(EDUCATION_PROMPT))

...

if (!user.gender) {
    user.gender = step.result;
    // Give user object back to UserState storage
    await this.userData.set(step.context, user);
    console.log(user);
}



在“ promptForMajor”步骤中,step.Prompt中的第二个参数采用字符串并表示选择的对话框部分。您的代码应如下所示,并将产生以下输出。在这种情况下,我在构造函数中为“ this.majors”分配了值(如上所示)。


this.majors = ['English', 'History', 'Computer Science'];

...

if (!user.major) {
    // Copy List of majors and add "Other" entry
    let majorsOther = this.majors.slice(0, this.majors.length);
    majorsOther.push('Einen anderen Studiengang');
    // return await step.prompt(MAJOR_PROMPT, this.userData.major, majorsOther);
    return await step.prompt(MAJOR_PROMPT, 'List of majors:', majorsOther);
}


javascript - 重复的ChoicePrompt清除UserState-LMLPHP


在“ onTurn”末尾检查您是否正在保存状态。


// Save changes to the user state.
await this.userState.saveChanges(turnContext);

// End this turn by saving changes to the conversation state.
await this.conversationState.saveChanges(turnContext);


如果实现上述要求,则应该设置。我能够毫无问题地奔跑,而且不会失去状态。此外,在最终提供适当的响应之前,反复不回答ChoicePrompt不会中断状态。

javascript - 重复的ChoicePrompt清除UserState-LMLPHP

希望有帮助!

10-08 19:11