Bot framework (v4) - How to get state from custom prompt validation

拜拜、爱过 提交于 2020-06-18 02:14:57

问题


I'm implementing a custom prompt validation where I need to access my state to compare with the user's input.

I did a lot of search and microsoft documentation and some samples too but I couldn't figure out how to do that.

The problem is that to be able to get the state you need to pass StatePropertyAccessor as a parameter as you would normally do with dialogs but when you extend a Prompt you can't do the same.

How can I get my state on this code ? Please, see the comment on onRecognize().

class AddressTextPrompt extends TextPrompt {
  private userProfile: StatePropertyAccessor<State>;
  public defaultLocale: string | undefined;

  constructor(dialogId: string, validator?: PromptValidator<string>, defaultLocale?: string) {
    super(dialogId, validator);
    this.defaultLocale = defaultLocale;
  }

  protected async onPrompt(context: TurnContext, state: any, options: PromptOptions, isRetry: boolean): Promise<void> {
    if (isRetry && options.retryPrompt) {
      await context.sendActivity(options.retryPrompt, null, InputHints.ExpectingInput);
    } else if (options.prompt) {
      await context.sendActivity(options.prompt, null, InputHints.ExpectingInput);
    }
  }

  protected async onRecognize(context: TurnContext, state: any, options: PromptOptions): Promise<PromptRecognizerResult<string>> {
    const result: PromptRecognizerResult<string> = { succeeded: false };
    const activity: Activity = context.activity;

    // I can't access my state here and there's no way to pass StatePropertyAccessor through contructor
    const userState: State = await this.userProfile.get(context);

    result.succeeded = (userState.user.address === activity.text)

    return result;
  }
}

export { AddressTextPrompt };

Adding prompt to dialog

this.addDialog(new AddressTextPrompt(ADDRESS_TEXT_PROMPT));

Using it

  const messageText = `Some text ${hideStringPartially(userDetails.address)}`;
  const msg = MessageFactory.text(messageText, messageText, InputHints.ExpectingInput);
  return await step.prompt(ADDRESS_TEXT_PROMPT, { prompt: msg, retryPrompt: `Some text. ${messageText}` });

回答1:


If the only reason AddressTextPrompt extends TextPrompt is so that you can do validation, then you should really just pass a validator in to a TextPrompt.

In the Multi-Turn-Prompt Sample,

...it passes in the validator:

this.addDialog(new NumberPrompt(NUMBER_PROMPT, this.agePromptValidator));

...then performs the validation:

async agePromptValidator(promptContext) {
    // This condition is our validation rule. You can also change the value at this point.
    return promptContext.recognized.succeeded && promptContext.recognized.value > 0 && promptContext.recognized.value < 150;
}

If the validator returns false, then the retryPrompt is fired. Otherwise, activity.Text is passed to the next step like normal. For you, the validator might look something like:

async addressValidator(promptContext) {
    const userState: State = await this.userProfile.get(context);
    // This condition is our validation rule. You can also change the value at this point.
    return promptContext.recognized.succeeded && promptContext.recognized.value === userState.user.address;
}


来源:https://stackoverflow.com/questions/57441392/bot-framework-v4-how-to-get-state-from-custom-prompt-validation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!