重复的ChoicePrompt清除UserState

时间:2019-02-22 11:17:13

标签: javascript botframework prompt

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

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

此行为是故意的还是有办法防止这种情况发生?

1 个答案:

答案 0 :(得分:1)

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

  1. 再次检查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'];
}
  1. 请记住,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);
}
  1. 在“ 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);
}

enter image description here

  1. 在“ 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并不会破坏状态。

enter image description here

希望有帮助!