/// <summary> /// Called when a prompt dialog is the active dialog and the user replied with a new activity. /// </summary> /// <param name="dc">The dialog context for the current turn of conversation.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> /// <remarks>If the task is successful, the result indicates whether the dialog is still /// active after the turn has been processed by the dialog. /// <para>The prompt generally continues to receive the user's replies until it accepts the /// user's reply as valid input for the prompt.</para></remarks> public override async Task <DialogTurnResult> ContinueDialogAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken)) { if (dc == null) { throw new ArgumentNullException(nameof(dc)); } // Perform base recognition var instance = dc.ActiveDialog; var state = (IDictionary <string, object>)instance.State[PersistedState]; var options = (PromptOptions)instance.State[PersistedOptions]; var recognized = await OnRecognizeAsync(dc.Context, state, options, cancellationToken).ConfigureAwait(false); // Increment attempt count // Convert.ToInt32 For issue https://github.com/Microsoft/botbuilder-dotnet/issues/1859 state[Prompt <int> .AttemptCountKey] = Convert.ToInt32(state[Prompt <int> .AttemptCountKey]) + 1; // Validate the return value var isValid = false; if (_validator != null) { var promptContext = new PromptValidatorContext <Activity>(dc.Context, recognized, state, options); isValid = await _validator(promptContext, cancellationToken).ConfigureAwait(false); } else if (recognized.Succeeded) { isValid = true; } // Return recognized value or re-prompt if (isValid) { return(await dc.EndDialogAsync(recognized.Value, cancellationToken).ConfigureAwait(false)); } else { await OnPromptAsync(dc.Context, state, options, true, cancellationToken).ConfigureAwait(false); } return(EndOfTurn); }
private static async Task <bool> CheckValidatorAsync(DialogContext dc, PromptValidator <TokenResponse> validator, TokenResponse tokenResponse, CancellationToken cancellationToken) { const string AttemptCount = "AttemptCount"; if (validator != null) { // Increment attempt count. var promptState = dc.ActiveDialog.State[OAuthHelper.PersistedState].CastTo <IDictionary <string, object> >(); promptState[AttemptCount] = Convert.ToInt32(promptState[AttemptCount], CultureInfo.InvariantCulture) + 1; // Call the custom validator. var recognized = new PromptRecognizerResult <TokenResponse> { Succeeded = tokenResponse != null, Value = tokenResponse }; var promptOptions = dc.ActiveDialog.State[OAuthHelper.PersistedOptions].CastTo <PromptOptions>(); var promptContext = new PromptValidatorContext <TokenResponse>(dc.Context, recognized, promptState, promptOptions); return(await validator(promptContext, cancellationToken).ConfigureAwait(false)); } else { return(tokenResponse != null); } }
/// <summary> /// Called when a prompt dialog is the active dialog and the user replied with a new activity. /// </summary> /// <param name="dc">The dialog context for the current turn of conversation.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> /// <remarks>If the task is successful, the result indicates whether the dialog is still /// active after the turn has been processed by the dialog. /// <para>The prompt generally continues to receive the user's replies until it accepts the /// user's reply as valid input for the prompt.</para></remarks> public override async Task <DialogTurnResult> ContinueDialogAsync(DialogContext dc, CancellationToken cancellationToken = default) { if (dc == null) { throw new ArgumentNullException(nameof(dc)); } // Check for timeout var state = dc.ActiveDialog.State; var expires = (DateTime)state[PersistedExpires]; var isMessage = dc.Context.Activity.Type == ActivityTypes.Message; // If the incoming Activity is a message, or an Activity Type normally handled by OAuthPrompt, // check to see if this OAuthPrompt Expiration has elapsed, and end the dialog if so. var isTimeoutActivityType = isMessage || IsTokenResponseEvent(dc.Context) || IsTeamsVerificationInvoke(dc.Context) || IsTokenExchangeRequestInvoke(dc.Context); var hasTimedOut = isTimeoutActivityType && DateTime.Compare(DateTime.UtcNow, expires) > 0; if (hasTimedOut) { // if the token fetch request times out, complete the prompt with no result. return(await dc.EndDialogAsync(cancellationToken : cancellationToken).ConfigureAwait(false)); } // Recognize token var recognized = await RecognizeTokenAsync(dc, cancellationToken).ConfigureAwait(false); var promptState = state[PersistedState].CastTo <IDictionary <string, object> >(); var promptOptions = state[PersistedOptions].CastTo <PromptOptions>(); // Increment attempt count // Convert.ToInt32 For issue https://github.com/Microsoft/botbuilder-dotnet/issues/1859 promptState[Prompt <int> .AttemptCountKey] = Convert.ToInt32(promptState[Prompt <int> .AttemptCountKey], CultureInfo.InvariantCulture) + 1; // Validate the return value var isValid = false; if (_validator != null) { var promptContext = new PromptValidatorContext <TokenResponse>(dc.Context, recognized, promptState, promptOptions); isValid = await _validator(promptContext, cancellationToken).ConfigureAwait(false); } else if (recognized.Succeeded) { isValid = true; } // Return recognized value or re-prompt if (isValid) { return(await dc.EndDialogAsync(recognized.Value, cancellationToken).ConfigureAwait(false)); } else if (isMessage && _settings.EndOnInvalidMessage) { // If EndOnInvalidMessage is set, complete the prompt with no result. return(await dc.EndDialogAsync(cancellationToken : cancellationToken).ConfigureAwait(false)); } if (!dc.Context.Responded && isMessage && promptOptions?.RetryPrompt != null) { await dc.Context.SendActivityAsync(promptOptions.RetryPrompt, cancellationToken).ConfigureAwait(false); } return(EndOfTurn); }