protected virtual async Task <DialogTurnResult> OnDialogContinueAsync(DialogContext dc) { return(await dc.ContinueAsync().ConfigureAwait(false)); }
/// <summary> /// Runs dialog system in the context of an ITurnContext. /// </summary> /// <param name="context">turn context.</param> /// <param name="cancellationToken">cancelation token.</param> /// <returns>result of the running the logic against the activity.</returns> public async Task <DialogManagerResult> OnTurnAsync(ITurnContext context, CancellationToken cancellationToken = default(CancellationToken)) { BotStateSet botStateSet = new BotStateSet(); ConversationState conversationState = this.ConversationState ?? context.TurnState.Get <ConversationState>() ?? throw new ArgumentNullException($"{nameof(ConversationState)} is not found in the turn context. Have you called adapter.UseState() with a configured ConversationState object?"); UserState userState = this.UserState ?? context.TurnState.Get <UserState>(); if (conversationState != null) { botStateSet.Add(conversationState); } if (userState != null) { botStateSet.Add(userState); } // create property accessors var lastAccessProperty = conversationState.CreateProperty <DateTime>(LASTACCESS); var lastAccess = await lastAccessProperty.GetAsync(context, () => DateTime.UtcNow, cancellationToken : cancellationToken).ConfigureAwait(false); // Check for expired conversation var now = DateTime.UtcNow; if (this.ExpireAfter.HasValue && (DateTime.UtcNow - lastAccess) >= TimeSpan.FromMilliseconds((double)this.ExpireAfter)) { // Clear conversation state await conversationState.ClearStateAsync(context, cancellationToken : cancellationToken).ConfigureAwait(false); } lastAccess = DateTime.UtcNow; await lastAccessProperty.SetAsync(context, lastAccess, cancellationToken : cancellationToken).ConfigureAwait(false); // get dialog stack var dialogsProperty = conversationState.CreateProperty <DialogState>(DIALOGS); DialogState dialogState = await dialogsProperty.GetAsync(context, () => new DialogState(), cancellationToken : cancellationToken).ConfigureAwait(false); // Create DialogContext var dc = new DialogContext(this.Dialogs, context, dialogState); // set DSM configuration dc.SetStateConfiguration(this.StateConfiguration ?? DialogStateManager.CreateStandardConfiguration(conversationState, userState)); // load scopes await dc.GetState().LoadAllScopesAsync(cancellationToken).ConfigureAwait(false); DialogTurnResult turnResult = null; // Loop as long as we are getting valid OnError handled we should continue executing the actions for the turn. // // NOTE: We loop around this block because each pass through we either complete the turn and break out of the loop // or we have had an exception AND there was an OnError action which captured the error. We need to continue the // turn based on the actions the OnError handler introduced. while (true) { try { if (dc.ActiveDialog == null) { // start root dialog turnResult = await dc.BeginDialogAsync(this.rootDialogId, cancellationToken : cancellationToken).ConfigureAwait(false); } else { // Continue execution // - This will apply any queued up interruptions and execute the current/next step(s). turnResult = await dc.ContinueDialogAsync(cancellationToken : cancellationToken).ConfigureAwait(false); if (turnResult.Status == DialogTurnStatus.Empty) { // restart root dialog turnResult = await dc.BeginDialogAsync(this.rootDialogId, cancellationToken : cancellationToken).ConfigureAwait(false); } } // turn successfully completed, break the loop break; } catch (Exception err) { // fire error event, bubbling from the leaf. var handled = await dc.EmitEventAsync(DialogEvents.Error, err, bubble : true, fromLeaf : true, cancellationToken : cancellationToken).ConfigureAwait(false); if (!handled) { // error was NOT handled, throw the exception and end the turn. (This will trigger the Adapter.OnError handler and end the entire dialog stack) throw; } } } // save all state scopes to their respective botState locations. await dc.GetState().SaveAllChangesAsync(cancellationToken).ConfigureAwait(false); // save botstate changes await botStateSet.SaveAllChangesAsync(dc.Context, false, cancellationToken).ConfigureAwait(false); // send trace of memory var snapshot = dc.GetState().GetMemorySnapshot(); var traceActivity = (Activity)Activity.CreateTraceActivity("BotState", "https://www.botframework.com/schemas/botState", snapshot, "Bot State"); await dc.Context.SendActivityAsync(traceActivity).ConfigureAwait(false); return(new DialogManagerResult() { TurnResult = turnResult }); }
/// <summary> /// Called when the dialog is _continued_, where it is the active dialog and the /// user replies with a new activity. /// </summary> /// <param name="dc">The <see cref="DialogContext"/> 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. The result may also contain a /// return value. /// /// If this method is *not* overridden, the dialog automatically ends when the user replies. /// </remarks> /// <seealso cref="DialogContext.ContinueDialogAsync(CancellationToken)"/> public virtual async Task <DialogTurnResult> ContinueDialogAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken)) { // By default just end the current dialog. return(await dc.EndDialogAsync(null, cancellationToken).ConfigureAwait(false)); }
/// <summary> /// Called when the dialog is started and pushed onto the dialog stack. /// </summary> /// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param> /// <param name="options">Optional, initial information to pass to the dialog.</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.</remarks> /// <seealso cref="DialogContext.BeginDialogAsync(string, object, CancellationToken)"/> public abstract Task <DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken));
private static async Task <DialogTurnResult> InnerRunAsync(ITurnContext turnContext, string dialogId, DialogContext dialogContext, CancellationToken cancellationToken) { // Handle EoC and Reprompt event from a parent bot (can be root bot to skill or skill to skill) if (IsFromParentToSkill(turnContext)) { // Handle remote cancellation request from parent. if (turnContext.Activity.Type == ActivityTypes.EndOfConversation) { if (!dialogContext.Stack.Any()) { // No dialogs to cancel, just return. return(new DialogTurnResult(DialogTurnStatus.Empty)); } var activeDialogContext = GetActiveDialogContext(dialogContext); // Send cancellation message to the top dialog in the stack to ensure all the parents are canceled in the right order. return(await activeDialogContext.CancelAllDialogsAsync(true, cancellationToken : cancellationToken).ConfigureAwait(false)); } // Handle a reprompt event sent from the parent. if (turnContext.Activity.Type == ActivityTypes.Event && turnContext.Activity.Name == DialogEvents.RepromptDialog) { if (!dialogContext.Stack.Any()) { // No dialogs to reprompt, just return. return(new DialogTurnResult(DialogTurnStatus.Empty)); } await dialogContext.RepromptDialogAsync(cancellationToken).ConfigureAwait(false); return(new DialogTurnResult(DialogTurnStatus.Waiting)); } } // Continue or start the dialog. var result = await dialogContext.ContinueDialogAsync(cancellationToken).ConfigureAwait(false); if (result.Status == DialogTurnStatus.Empty) { result = await dialogContext.BeginDialogAsync(dialogId, null, cancellationToken).ConfigureAwait(false); } await SendStateSnapshotTraceAsync(dialogContext, cancellationToken).ConfigureAwait(false); // Skills should send EoC when the dialog completes. if (result.Status == DialogTurnStatus.Complete || result.Status == DialogTurnStatus.Cancelled) { if (SendEoCToParent(turnContext)) { // Send End of conversation at the end. var code = result.Status == DialogTurnStatus.Complete ? EndOfConversationCodes.CompletedSuccessfully : EndOfConversationCodes.UserCancelled; var activity = new Activity(ActivityTypes.EndOfConversation) { Value = result.Result, Locale = turnContext.Activity.Locale, Code = code }; await turnContext.SendActivityAsync(activity, cancellationToken).ConfigureAwait(false); } } return(result); }
/// <summary> /// Uses the RecognizerResult to create a list of propeties to be included when tracking the result in telemetry. /// </summary> /// <param name="recognizerResult">Recognizer Result.</param> /// <param name="telemetryProperties">A list of properties to append or override the properties created using the RecognizerResult.</param> /// <param name="dialogContext">Dialog Context.</param> /// <returns>A dictionary that can be included when calling the TrackEvent method on the TelemetryClient.</returns> protected virtual Dictionary <string, string> FillRecognizerResultTelemetryProperties(RecognizerResult recognizerResult, Dictionary <string, string> telemetryProperties, DialogContext dialogContext = null) { var properties = new Dictionary <string, string> { { "Text", recognizerResult.Text }, { "AlteredText", recognizerResult.AlteredText }, { "TopIntent", recognizerResult.Intents.Any() ? recognizerResult.Intents.First().Key : null }, { "TopIntentScore", recognizerResult.Intents.Any() ? recognizerResult.Intents.First().Value?.ToString() : null }, { "Intents", recognizerResult.Intents.Any() ? JsonConvert.SerializeObject(recognizerResult.Intents) : null }, { "Entities", recognizerResult.Entities != null?recognizerResult.Entities.ToString() : null }, { "AdditionalProperties", recognizerResult.Properties.Any() ? JsonConvert.SerializeObject(recognizerResult.Properties) : null }, }; // Additional Properties can override "stock" properties. if (telemetryProperties != null) { return(telemetryProperties.Concat(properties) .GroupBy(kv => kv.Key) .ToDictionary(g => g.Key, g => g.First().Value)); } return(properties); }
protected abstract Task <T> OnRecognize(DialogContext dc, PromptOptions options);
/// <summary> /// Runs dialog system in the context of an ITurnContext. /// </summary> /// <param name="context">turn context.</param> /// <param name="cancellationToken">cancelation token.</param> /// <returns>result of the running the logic against the activity.</returns> public async Task <DialogManagerResult> OnTurnAsync(ITurnContext context, CancellationToken cancellationToken = default(CancellationToken)) { BotStateSet botStateSet = new BotStateSet(); ConversationState conversationState = this.ConversationState ?? context.TurnState.Get <ConversationState>() ?? throw new ArgumentNullException($"{nameof(ConversationState)} is not found in the turn context. Have you called adapter.UseState() with a configured ConversationState object?"); UserState userState = this.UserState ?? context.TurnState.Get <UserState>(); if (conversationState != null) { botStateSet.Add(conversationState); } if (userState != null) { botStateSet.Add(userState); } // create property accessors var lastAccessProperty = conversationState.CreateProperty <DateTime>(LASTACCESS); var lastAccess = await lastAccessProperty.GetAsync(context, () => DateTime.UtcNow, cancellationToken : cancellationToken).ConfigureAwait(false); // Check for expired conversation var now = DateTime.UtcNow; if (this.ExpireAfter.HasValue && (DateTime.UtcNow - lastAccess) >= TimeSpan.FromMilliseconds((double)this.ExpireAfter)) { // Clear conversation state await conversationState.ClearStateAsync(context, cancellationToken : cancellationToken).ConfigureAwait(false); } lastAccess = DateTime.UtcNow; await lastAccessProperty.SetAsync(context, lastAccess, cancellationToken : cancellationToken).ConfigureAwait(false); // get dialog stack var dialogsProperty = conversationState.CreateProperty <DialogState>(DIALOGS); DialogState dialogState = await dialogsProperty.GetAsync(context, () => new DialogState(), cancellationToken : cancellationToken).ConfigureAwait(false); // Create DialogContext var dc = new DialogContext(this.dialogSet, context, dialogState); // set DSM configuration dc.SetStateConfiguration(this.StateConfiguration ?? DialogStateManager.CreateStandardConfiguration(conversationState, userState)); // load scopes await dc.GetState().LoadAllScopesAsync(cancellationToken).ConfigureAwait(false); DialogTurnResult turnResult = null; if (dc.ActiveDialog == null) { // start root dialog turnResult = await dc.BeginDialogAsync(this.rootDialogId, cancellationToken : cancellationToken).ConfigureAwait(false); } else { // Continue execution // - This will apply any queued up interruptions and execute the current/next step(s). turnResult = await dc.ContinueDialogAsync(cancellationToken : cancellationToken).ConfigureAwait(false); if (turnResult.Status == DialogTurnStatus.Empty) { // restart root dialog turnResult = await dc.BeginDialogAsync(this.rootDialogId, cancellationToken : cancellationToken).ConfigureAwait(false); } } // save all state scopes to their respective stores. await dc.GetState().SaveAllChangesAsync(cancellationToken).ConfigureAwait(false); // save botstate changes await botStateSet.SaveAllChangesAsync(dc.Context, false, cancellationToken).ConfigureAwait(false); // send trace of memory var snapshot = dc.GetState().GetMemorySnapshot(); var traceActivity = (Activity)Activity.CreateTraceActivity("BotState", "https://www.botframework.com/schemas/botState", snapshot, "Bot State"); await dc.Context.SendActivityAsync(traceActivity).ConfigureAwait(false); return(new DialogManagerResult() { TurnResult = turnResult }); }
public static void Done(this DialogContext dc, object result) { dc.EndDialogAsync(result).Wait(); }
protected abstract Task OnPrompt(DialogContext dc, PromptOptions options, bool isRetry);
public static async Task PostAsync(this DialogContext dc, IMessageActivity message) { await dc.Context.SendActivityAsync(message).ConfigureAwait(false); }
public static void Fail(this DialogContext dc, Exception ex) { dc.PostAsync(ex.Message).Wait(); dc.CancelAllDialogsAsync().Wait(); }
protected virtual async Task OnDialogRepromptAsync(DialogContext dc) { await dc.RepromptAsync().ConfigureAwait(false); }
/// <summary> /// Method called when an instance of the dialog is being returned to from another /// dialog that was started by the current instance using `DialogSet.begin()`. /// If this method is NOT implemented then the dialog will be automatically ended with a call /// to `DialogSet.endDialogWithResult()`. Any result passed from the called dialog will be passed /// to the current dialogs parent. /// </summary> /// <param name="dc">The dialog context for the current turn of conversation.</param> /// <param name="reason">Reason why the dialog resumed.</param> /// <param name="result">(Optional) value returned from the dialog that was called. The type of the value returned is dependant on the dialog that was called.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public virtual async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default(CancellationToken)) { // By default just end the current dialog and return result to parent. return(await dc.EndDialogAsync(result, cancellationToken).ConfigureAwait(false)); }
/// <summary> /// Runs dialog system in the context of an ITurnContext. /// </summary> /// <param name="context">turn context.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns>result of the running the logic against the activity.</returns> public async Task <DialogManagerResult> OnTurnAsync(ITurnContext context, CancellationToken cancellationToken = default) { var botStateSet = new BotStateSet(); // Preload TurnState with DM TurnState. foreach (var pair in InitialTurnState) { context.TurnState.Set(pair.Key, pair.Value); } // register DialogManager with TurnState. context.TurnState.Set(this); if (ConversationState == null) { ConversationState = context.TurnState.Get <ConversationState>() ?? throw new InvalidOperationException($"Unable to get an instance of {nameof(ConversationState)} from turnContext."); } else { context.TurnState.Set(ConversationState); } botStateSet.Add(ConversationState); if (UserState == null) { UserState = context.TurnState.Get <UserState>(); } else { context.TurnState.Set(UserState); } if (UserState != null) { botStateSet.Add(UserState); } // create property accessors var lastAccessProperty = ConversationState.CreateProperty <DateTime>(LastAccess); var lastAccess = await lastAccessProperty.GetAsync(context, () => DateTime.UtcNow, cancellationToken).ConfigureAwait(false); // Check for expired conversation if (ExpireAfter.HasValue && (DateTime.UtcNow - lastAccess) >= TimeSpan.FromMilliseconds((double)ExpireAfter)) { // Clear conversation state await ConversationState.ClearStateAsync(context, cancellationToken).ConfigureAwait(false); } lastAccess = DateTime.UtcNow; await lastAccessProperty.SetAsync(context, lastAccess, cancellationToken).ConfigureAwait(false); // get dialog stack var dialogsProperty = ConversationState.CreateProperty <DialogState>(_dialogStateProperty); var dialogState = await dialogsProperty.GetAsync(context, () => new DialogState(), cancellationToken).ConfigureAwait(false); // Create DialogContext var dc = new DialogContext(Dialogs, context, dialogState); // promote initial TurnState into dc.services for contextual services foreach (var service in dc.Services) { dc.Services[service.Key] = service.Value; } // map TurnState into root dialog context.services foreach (var service in context.TurnState) { dc.Services[service.Key] = service.Value; } // get the DialogStateManager configuration var dialogStateManager = new DialogStateManager(dc, StateConfiguration); await dialogStateManager.LoadAllScopesAsync(cancellationToken).ConfigureAwait(false); dc.Context.TurnState.Add(dialogStateManager); DialogTurnResult turnResult = null; // Loop as long as we are getting valid OnError handled we should continue executing the actions for the turn. // // NOTE: We loop around this block because each pass through we either complete the turn and break out of the loop // or we have had an exception AND there was an OnError action which captured the error. We need to continue the // turn based on the actions the OnError handler introduced. var endOfTurn = false; while (!endOfTurn) { try { if (context.TurnState.Get <IIdentity>(BotAdapter.BotIdentityKey) is ClaimsIdentity claimIdentity && SkillValidation.IsSkillClaim(claimIdentity.Claims)) { // The bot is running as a skill. turnResult = await HandleSkillOnTurnAsync(dc, cancellationToken).ConfigureAwait(false); } else { // The bot is running as root bot. turnResult = await HandleBotOnTurnAsync(dc, cancellationToken).ConfigureAwait(false); } // turn successfully completed, break the loop endOfTurn = true; }
/// <summary> /// Runs current DialogContext.TurnContext.Activity through a recognizer and returns a generic recognizer result. /// </summary> /// <param name="dialogContext">Dialog context.</param> /// <param name="activity">activity to recognize.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <param name="telemetryProperties">Additional properties to be logged to telemetry with the LuisResult event.</param> /// <param name="telemetryMetrics">Additional metrics to be logged to telemetry with the LuisResult event.</param> /// <returns>Analysis of utterance.</returns> public virtual Task <RecognizerResult> RecognizeAsync(DialogContext dialogContext, Activity activity, CancellationToken cancellationToken = default, Dictionary <string, string> telemetryProperties = null, Dictionary <string, double> telemetryMetrics = null) { throw new NotImplementedException(); }
/// <summary> /// Called before an event is bubbled to its parent. /// </summary> /// <remarks> /// This is a good place to perform interception of an event as returning `true` will prevent /// any further bubbling of the event to the dialogs parents and will also prevent any child /// dialogs from performing their default processing. /// </remarks> /// <param name="dc">The dialog context for the current turn of conversation.</param> /// <param name="e">The event being raised.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns> Whether the event is handled by the current dialog and further processing should stop.</returns> protected override async Task <bool> OnPreBubbleEventAsync(DialogContext dc, DialogEvent e, CancellationToken cancellationToken) { return(await Task.FromResult(false).ConfigureAwait(false)); }
internal static async Task <DialogTurnResult> InternalRunAsync(ITurnContext turnContext, string dialogId, DialogContext dialogContext, DialogStateManagerConfiguration stateConfiguration, CancellationToken cancellationToken) { // map TurnState into root dialog context.services foreach (var service in turnContext.TurnState) { dialogContext.Services[service.Key] = service.Value; } var dialogStateManager = new DialogStateManager(dialogContext, stateConfiguration); await dialogStateManager.LoadAllScopesAsync(cancellationToken).ConfigureAwait(false); dialogContext.Context.TurnState.Add(dialogStateManager); DialogTurnResult dialogTurnResult = null; // Loop as long as we are getting valid OnError handled we should continue executing the actions for the turn. // // NOTE: We loop around this block because each pass through we either complete the turn and break out of the loop // or we have had an exception AND there was an OnError action which captured the error. We need to continue the // turn based on the actions the OnError handler introduced. var endOfTurn = false; while (!endOfTurn) { try { dialogTurnResult = await InnerRunAsync(turnContext, dialogId, dialogContext, cancellationToken).ConfigureAwait(false); // turn successfully completed, break the loop endOfTurn = true; } catch (Exception err) { // fire error event, bubbling from the leaf. var handled = await dialogContext.EmitEventAsync(DialogEvents.Error, err, bubble : true, fromLeaf : true, cancellationToken : cancellationToken).ConfigureAwait(false); if (!handled) { // error was NOT handled, throw the exception and end the turn. (This will trigger the Adapter.OnError handler and end the entire dialog stack) throw; } } } // save all state scopes to their respective botState locations. await dialogStateManager.SaveAllChangesAsync(cancellationToken).ConfigureAwait(false); // return the redundant result because the DialogManager contract expects it return(dialogTurnResult); }
protected virtual Task <DialogTurnResult> OnBeginDialogAsync(DialogContext innerDc, object options, CancellationToken cancellationToken = default(CancellationToken)) { return(innerDc.BeginDialogAsync(InitialDialogId, options, cancellationToken)); }
public abstract DialogContext CreateChildContext(DialogContext dc);
protected virtual Task <DialogTurnResult> OnContinueDialogAsync(DialogContext innerDc, CancellationToken cancellationToken = default(CancellationToken)) { return(innerDc.ContinueDialogAsync(cancellationToken)); }
/// <summary> /// Runs current DialogContext.TurnContext.Activity through a recognizer and returns a generic recognizer result. /// </summary> /// <param name="dialogContext">Dialog context.</param> /// <param name="activity">activity to recognize.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <param name="telemetryProperties">Additional properties to be logged to telemetry with the LuisResult event.</param> /// <param name="telemetryMetrics">Additional metrics to be logged to telemetry with the LuisResult event.</param> /// <returns>Analysis of utterance.</returns> #pragma warning disable CA1068 // CancellationToken parameters must come last (we can't change this without breaking binary compat) public virtual Task <RecognizerResult> RecognizeAsync(DialogContext dialogContext, Activity activity, CancellationToken cancellationToken = default, Dictionary <string, string> telemetryProperties = null, Dictionary <string, double> telemetryMetrics = null) #pragma warning restore CA1068 // CancellationToken parameters must come last { throw new NotImplementedException(); }
protected virtual Task <DialogTurnResult> EndComponentAsync(DialogContext outerDc, object result, CancellationToken cancellationToken) { return(outerDc.EndDialogAsync(result, cancellationToken)); }
/// <summary> /// Called after an event was bubbled to all parents and wasn't handled. /// </summary> /// <remarks> /// This is a good place to perform default processing logic for an event. Returning `true` will /// prevent any processing of the event by child dialogs. /// </remarks> /// <param name="dc">The dialog context for the current turn of conversation.</param> /// <param name="e">The event being raised.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns> Whether the event is handled by the current dialog and further processing should stop.</returns> protected virtual Task <bool> OnPostBubbleEventAsync(DialogContext dc, DialogEvent e, CancellationToken cancellationToken) { return(Task.FromResult(false)); }
/// <summary> /// Called when a prompt dialog is pushed onto the dialog stack and is being activated. /// </summary> /// <param name="dc">The dialog context for the current turn of the conversation.</param> /// <param name="options">Optional, additional information to pass to the prompt being started.</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 prompt is still /// active after the turn has been processed by the prompt.</remarks> public override async Task <DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { if (dc == null) { throw new ArgumentNullException(nameof(dc)); } if (options is CancellationToken) { throw new ArgumentException($"{nameof(options)} cannot be a cancellation token"); } PromptOptions opt = null; if (options != null) { if (options is PromptOptions) { // Ensure prompts have input hint set opt = options as PromptOptions; if (opt.Prompt != null && string.IsNullOrEmpty(opt.Prompt.InputHint)) { opt.Prompt.InputHint = InputHints.AcceptingInput; } if (opt.RetryPrompt != null && string.IsNullOrEmpty(opt.RetryPrompt.InputHint)) { opt.RetryPrompt.InputHint = InputHints.AcceptingInput; } } else { throw new ArgumentException(nameof(options)); } } // Initialize state var timeout = _settings.Timeout ?? (int)TurnStateConstants.OAuthLoginTimeoutValue.TotalMilliseconds; var state = dc.ActiveDialog.State; state[PersistedOptions] = opt; state[PersistedState] = new Dictionary <string, object> { { Prompt <int> .AttemptCountKey, 0 }, }; state[PersistedExpires] = DateTime.Now.AddMilliseconds(timeout); // Attempt to get the users token if (!(dc.Context.Adapter is IExtendedUserTokenProvider adapter)) { throw new InvalidOperationException("OAuthPrompt.Recognize(): not supported by the current adapter"); } var output = await adapter.GetUserTokenAsync(dc.Context, _settings.OAuthAppCredentials, _settings.ConnectionName, null, cancellationToken).ConfigureAwait(false); if (output != null) { // Return token return(await dc.EndDialogAsync(output, cancellationToken).ConfigureAwait(false)); } // Prompt user to login await SendOAuthCardAsync(dc.Context, opt?.Prompt, cancellationToken).ConfigureAwait(false); return(EndOfTurn); }
public override async Task <DialogTurnResult> ResumeDialogAsync(DialogContext dc, DialogReason reason, object result = null, CancellationToken cancellationToken = default) { await RepromptDialogAsync(dc.Context, dc.ActiveDialog, cancellationToken).ConfigureAwait(false); return(EndOfTurn); }
protected virtual async Task <DialogTurnResult> OnDialogBeginAsync(DialogContext dc, DialogOptions options) { return(await dc.BeginAsync(InitialDialogId, options).ConfigureAwait(false)); }