public async Task DialogContinueAsync(DialogContext dc)
        {
            if (dc == null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            // Recognize token
            var tokenResult = await _prompt.RecognizeAsync(dc.Context).ConfigureAwait(false);

            // Check for timeout
            var state       = dc.ActiveDialog.State as OAuthPromptOptions;
            var isMessage   = dc.Context.Activity.Type == ActivityTypes.Message;
            var hasTimedOut = isMessage && (DateTime.Compare(DateTime.Now, state.Expires) > 0);

            if (hasTimedOut)
            {
                // if the token fetch request timesout, complete the prompt with no result.
                await dc.EndAsync(null).ConfigureAwait(false);
            }
            else if (tokenResult != null)
            {
                // if the token fetch was successful and it hasn't timed out (as verified in the above if)
                await dc.EndAsync(tokenResult).ConfigureAwait(false);
            }
            else if (isMessage && !string.IsNullOrEmpty(state.RetryPromptString))
            {
                // if this is a retry, then retry getting user credentials by resending the activity.
                await dc.Context.SendActivityAsync(state.RetryPromptString, state.RetrySpeak).ConfigureAwait(false);
            }
        }
Exemple #2
0
        public override async Task <DialogTurnResult> DialogContinueAsync(DialogContext dc)
        {
            if (dc == null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            // Recognize token
            var recognized = await RecognizeTokenAsync(dc.Context).ConfigureAwait(false);

            // Check for timeout
            var state       = dc.ActiveDialog.State;
            var expires     = (DateTime)state[PersistedExpires];
            var isMessage   = dc.Context.Activity.Type == ActivityTypes.Message;
            var hasTimedOut = isMessage && (DateTime.Compare(DateTime.Now, expires) > 0);

            if (hasTimedOut)
            {
                // if the token fetch request timesout, complete the prompt with no result.
                return(await dc.EndAsync().ConfigureAwait(false));
            }
            else
            {
                var promptState   = (IDictionary <string, object>)state[PersistedState];
                var promptOptions = (PromptOptions)state[PersistedOptions];

                // Validate the return value
                var    end       = false;
                object endResult = null;
                if (_validator != null)
                {
                    var prompt = new PromptValidatorContext <TokenResponse>(dc, promptState, promptOptions, recognized);
                    await _validator(dc.Context, prompt).ConfigureAwait(false);

                    end       = prompt.HasEnded;
                    endResult = prompt.EndResult;
                }
                else if (recognized.Succeeded)
                {
                    end       = true;
                    endResult = recognized.Value;
                }

                // Return recognized value or re-prompt
                if (end)
                {
                    return(await dc.EndAsync(endResult).ConfigureAwait(false));
                }
                else
                {
                    if (!dc.Context.Responded && isMessage && promptOptions != null && promptOptions.RetryPrompt != null)
                    {
                        await dc.Context.SendActivityAsync(promptOptions.RetryPrompt).ConfigureAwait(false);
                    }

                    return(Dialog.EndOfTurn);
                }
            }
        }
        private async Task RunStepAsync(DialogContext dc, IDictionary <string, object> result = null)
        {
            if (dc == null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            var step = dc.ActiveDialog.Step;

            if (step >= 0 && step < _steps.Length)
            {
                SkipStepFunction next = (r) =>
                {
                    // Skip to next step
                    dc.ActiveDialog.Step++;
                    return(RunStepAsync(dc, r));
                };

                // Execute step
                await _steps[step](dc, result, next).ConfigureAwait(false);
            }
            else
            {
                // End of waterfall so just return to parent
                await dc.EndAsync(result).ConfigureAwait(false);
            }
        }
Exemple #4
0
        public async Task DialogContinueAsync(DialogContext dc)
        {
            if (dc == null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            // Don't do anything for non-message activities
            if (dc.Context.Activity.Type != ActivityTypes.Message)
            {
                return;
            }

            // Recognize value
            var instance   = dc.ActiveDialog;
            var recognized = await OnRecognizeAsync(dc, (PromptOptions)instance.State).ConfigureAwait(false);

            // TODO: resolve the inconsistency of approach between the Node SDK and what we have here
            if (!recognized.Succeeded())
            {
                // TODO: setting this to null is intended to mimicking the behavior of the Node SDK PromptValidator
                recognized = null;
            }

            if (recognized != null)
            {
                // Return recognized value
                await dc.EndAsync(recognized).ConfigureAwait(false);
            }
            else if (!dc.Context.Responded)
            {
                // Send retry prompt
                await OnPromptAsync(dc, (PromptOptions)instance.State, true).ConfigureAwait(false);
            }
        }
        public override async Task <DialogTurnResult> DialogBeginAsync(DialogContext dc, DialogOptions options = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (dc == null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            // Start the inner dialog.
            var dialogState = new DialogState();

            dc.ActiveDialog.State[PersistedDialogState] = dialogState;
            var cdc        = new DialogContext(_dialogs, dc.Context, dialogState);
            var turnResult = await OnDialogBeginAsync(cdc, options, cancellationToken).ConfigureAwait(false);

            // Check for end of inner dialog
            if (turnResult.HasResult)
            {
                // Return result to calling dialog
                return(await dc.EndAsync(turnResult.Result, cancellationToken).ConfigureAwait(false));
            }
            else
            {
                // Just signal end of turn
                return(Dialog.EndOfTurn);
            }
        }
        public override async Task <DialogTurnResult> DialogContinueAsync(DialogContext dc)
        {
            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).ConfigureAwait(false);

            // Validate the return value
            var prompt = new PromptValidatorContext <Activity>(dc, state, options, recognized);

            await _validator(dc.Context, prompt).ConfigureAwait(false);

            // Return recognized value or re-prompt
            if (prompt.HasEnded)
            {
                return(await dc.EndAsync(prompt.EndResult).ConfigureAwait(false));
            }
            else
            {
                return(Dialog.EndOfTurn);
            }
        }
Exemple #7
0
        private async Task <DialogTurnResult> RunStepAsync(DialogContext dc, int index, DialogReason reason, object result, CancellationToken cancellationToken)
        {
            if (dc == null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            if (index < _steps.Length)
            {
                // Update persisted step index
                var state = dc.ActiveDialog.State;
                state[StepIndex] = index;

                // Create step context
                var options = (DialogOptions)state[PersistedOptions];
                var values  = (IDictionary <string, object>)state[PersistedValues];
                var step    = new WaterfallStepContext(this, dc, options, values, index, reason, result);

                // Execute step
                return(await OnStepAsync(dc, step, cancellationToken).ConfigureAwait(false));
            }
            else
            {
                // End of waterfall so just return any result to parent
                return(await dc.EndAsync(result).ConfigureAwait(false));
            }
        }
Exemple #8
0
        public override async Task <DialogTurnResult> DialogBeginAsync(DialogContext dc, DialogOptions options = null)
        {
            if (dc == null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            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.ExpectingInput;
                    }

                    if (opt.RetryPrompt != null && string.IsNullOrEmpty(opt.RetryPrompt.InputHint))
                    {
                        opt.RetryPrompt.InputHint = InputHints.ExpectingInput;
                    }
                }
                else
                {
                    throw new ArgumentException(nameof(options));
                }
            }

            // Initialize state
            var timeout = _settings.Timeout ?? DefaultPromptTimeout;
            var state   = dc.ActiveDialog.State;

            state[PersistedOptions] = opt;
            state[PersistedState]   = new Dictionary <string, object>();
            state[PersistedExpires] = DateTime.Now.AddMilliseconds(timeout);

            // Attempt to get the users token
            var output = await GetUserTokenAsync(dc.Context).ConfigureAwait(false);

            if (output != null)
            {
                // Return token
                return(await dc.EndAsync(output).ConfigureAwait(false));
            }
            else
            {
                // Prompt user to login
                await SendOAuthCardAsync(dc.Context, opt?.Prompt).ConfigureAwait(false);

                return(Dialog.EndOfTurn);
            }
        }
        public async Task DialogBeginAsync(DialogContext dc, IDictionary <string, object> dialogArgs = null)
        {
            if (dc == null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            PromptOptions promptOptions = null;

            if (dialogArgs != null)
            {
                if (dialogArgs is PromptOptions)
                {
                    promptOptions = dialogArgs as PromptOptions;
                }
                else
                {
                    throw new ArgumentException(nameof(dialogArgs));
                }
            }

            // persist options and state
            var timeout  = _settings.Timeout ?? DefaultPromptTimeout;
            var instance = dc.ActiveDialog;

            instance.State = new OAuthPromptOptions(promptOptions);

            var tokenResult = await _prompt.GetUserTokenAsync(dc.Context).ConfigureAwait(false);

            if (tokenResult != null && tokenResult.TokenResponse != null)
            {
                // end the prompt, since a token is available.
                await dc.EndAsync(tokenResult).ConfigureAwait(false);
            }
            else if (!string.IsNullOrEmpty(promptOptions?.PromptString))
            {
                // send supplied prompt and then OAuthCard
                await dc.Context.SendActivityAsync(promptOptions.PromptString, promptOptions.Speak).ConfigureAwait(false);

                await _prompt.PromptAsync(dc.Context);
            }
            else
            {
                // if the bot developer has supplied an activity to show the user for signin, use that.
                if (promptOptions == null)
                {
                    await _prompt.PromptAsync(dc.Context).ConfigureAwait(false);
                }
                else
                {
                    await _prompt.PromptAsync(dc.Context, promptOptions.PromptActivity);
                }
            }
        }
Exemple #10
0
        public override async Task <DialogTurnResult> DialogContinueAsync(DialogContext dc)
        {
            if (dc == null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            // Don't do anything for non-message activities
            if (dc.Context.Activity.Type != ActivityTypes.Message)
            {
                return(Dialog.EndOfTurn);
            }

            // 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).ConfigureAwait(false);

            // Validate the return value
            var    end       = false;
            object endResult = null;

            if (_validator != null)
            {
                var prompt = new PromptValidatorContext <T>(dc, state, options, recognized);
                await _validator(dc.Context, prompt).ConfigureAwait(false);

                end       = prompt.HasEnded;
                endResult = prompt.EndResult;
            }
            else if (recognized.Succeeded)
            {
                end       = true;
                endResult = recognized.Value;
            }

            // Return recognized value or re-prompt
            if (end)
            {
                return(await dc.EndAsync(endResult).ConfigureAwait(false));
            }
            else
            {
                if (!dc.Context.Responded)
                {
                    await OnPromptAsync(dc.Context, state, options, true).ConfigureAwait(false);
                }

                return(Dialog.EndOfTurn);
            }
        }
Exemple #11
0
        private static async Task <DialogTurnResult> ReturnAlarmStepAsync(DialogContext dc, WaterfallStepContext step)
        {
            // Save time if prompted for.
            if (step.Result != null)
            {
                step.Values[AlarmTime] = step.Result;
            }

            // Format alarm and return to caller.
            var alarm = new Alarm
            {
                Title = (string)step.Values[AlarmTitle],
                Time  = (DateTime)step.Values[AlarmTime],
            };

            return(await dc.EndAsync(alarm).ConfigureAwait(false));
        }
Exemple #12
0
        public async Task DialogContinueAsync(DialogContext dc)
        {
            if (dc == null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            // Continue controls dialog stack.
            IDictionary <string, object> result = null;
            var cdc = new DialogContext(this.Dialogs, dc.Context, dc.ActiveDialog.State, (r) => { result = r; });
            await cdc.ContinueAsync().ConfigureAwait(false);

            // End if the controls dialog ends.
            if (cdc.ActiveDialog == null)
            {
                await dc.EndAsync(result).ConfigureAwait(false);
            }
        }
Exemple #13
0
        public async Task DialogBeginAsync(DialogContext dc, IDictionary <string, object> dialogArgs = null)
        {
            if (dc == null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            // Start the controls entry point dialog.
            IDictionary <string, object> result = null;
            var cdc = new DialogContext(this.Dialogs, dc.Context, dc.ActiveDialog.State, (r) => { result = r; });
            await cdc.BeginAsync(DialogId, dialogArgs);

            // End if the controls dialog ends.
            if (cdc.ActiveDialog == null)
            {
                await dc.EndAsync(result);
            }
        }
Exemple #14
0
        public override async Task <DialogTurnResult> DialogContinueAsync(DialogContext dc)
        {
            if (dc == null)
            {
                throw new ArgumentNullException(nameof(dc));
            }

            // Continue execution of inner dialog.
            var dialogState = (DialogState)dc.ActiveDialog.State[PersistedDialogState];
            var cdc         = new DialogContext(_dialogs, dc.Context, dialogState);
            var turnResult  = await OnDialogContinueAsync(cdc).ConfigureAwait(false);

            // Check for end of inner dialog
            if (turnResult.HasResult)
            {
                // Return result to calling dialog
                return(await dc.EndAsync(turnResult.Result).ConfigureAwait(false));
            }
            else
            {
                // Just signal end of turn
                return(Dialog.EndOfTurn);
            }
        }
Exemple #15
0
 protected virtual Task <DialogTurnResult> EndComponentAsync(DialogContext outerDc, object result, CancellationToken cancellationToken)
 {
     return(outerDc.EndAsync(result));
 }
Exemple #16
0
 /// <summary>
 /// Method called when an instance of the dialog is the "current" dialog and the
 /// user replies with a new activity. The dialog will generally continue to receive the users
 /// replies until it calls either `DialogSet.end()` or `DialogSet.begin()`.
 /// If this method is NOT implemented then the dialog will automatically be ended when the user replies.
 /// </summary>
 /// <param name="dc">The dialog context for the current turn of conversation.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
 public virtual async Task <DialogTurnResult> DialogContinueAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken))
 {
     // By default just end the current dialog.
     return(await dc.EndAsync(cancellationToken).ConfigureAwait(false));
 }
Exemple #17
0
 /// <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> DialogResumeAsync(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.EndAsync(result, cancellationToken).ConfigureAwait(false));
 }
Exemple #18
0
 /// <summary>
 /// Method called when an instance of the dialog is the "current" dialog and the
 /// user replies with a new activity. The dialog will generally continue to receive the users
 /// replies until it calls either `DialogSet.end()` or `DialogSet.begin()`.
 /// If this method is NOT implemented then the dialog will automatically be ended when the user replies.
 /// </summary>
 /// <param name="dc">The dialog context for the current turn of conversation.</param>
 /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
 public virtual async Task <DialogTurnResult> DialogContinueAsync(DialogContext dc)
 {
     // By default just end the current dialog.
     return(await dc.EndAsync().ConfigureAwait(false));
 }