示例#1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="GraphAuthenticationBot"/> class.
        /// </summary>
        /// <param name="accessors">State accessors for the bot.</param>
        public GraphAuthenticationBot(GraphAuthenticationBotAccessors accessors)
        {
            if (string.IsNullOrWhiteSpace(ConnectionSettingName))
            {
                throw new InvalidOperationException("ConnectionSettingName must be configured prior to running the bot.");
            }

            _stateAccessors = accessors ?? throw new ArgumentNullException(nameof(accessors));
            _dialogs        = new DialogSet(_stateAccessors.ConversationDialogState);
            _dialogs.Add(OAuthHelpers.Prompt(ConnectionSettingName));
            _dialogs.Add(new ChoicePrompt("choicePrompt"));
            _dialogs.Add(new WaterfallDialog("graphDialog", new WaterfallStep[] { PromptStepAsync, ProcessStepAsync }));
        }
示例#2
0
        /// <summary>
        /// Waterfall dialog step to process the command sent by the user.
        /// </summary>
        /// <param name="step">A <see cref="WaterfallStepContext"/> provides context for the current waterfall step.</param>
        /// <param name="cancellationToken">(Optional) A <see cref="CancellationToken"/> that can be used by other objects
        /// or threads to receive notice of cancellation.</param>
        /// <returns>A <see cref="Task"/> representing the operation result of the operation.</returns>
        private async Task <DialogTurnResult> ProcessStepAsync(WaterfallStepContext step, CancellationToken cancellationToken)
        {
            if (step.Result != null)
            {
                // We do not need to store the token in the bot. When we need the token we can
                // send another prompt. If the token is valid the user will not need to log back in.
                // The token will be available in the Result property of the task.
                var tokenResponse = step.Result as TokenResponse;

                // If we have the token use the user is authenticated so we may use it to make API calls.
                if (tokenResponse?.Token != null)
                {
                    var    parts   = _stateAccessors.CommandState.GetAsync(step.Context, () => string.Empty, cancellationToken: cancellationToken).Result.Split(' ');
                    string command = parts[0].ToLowerInvariant();

                    if (command == "me")
                    {
                        await OAuthHelpers.ListMeAsync(step.Context, tokenResponse);
                    }
                    else if (command.StartsWith("send"))
                    {
                        await OAuthHelpers.SendMailAsync(step.Context, tokenResponse, parts[1]);
                    }
                    else if (command.StartsWith("recent"))
                    {
                        await OAuthHelpers.ListRecentMailAsync(step.Context, tokenResponse);
                    }
                    else if (command.StartsWith("token"))
                    {
                        await step.Context.SendActivityAsync($"Your token is: {tokenResponse.Token}", cancellationToken : cancellationToken);
                    }
                    else if (command.StartsWith("continue"))
                    {
                        await OAuthHelpers.ContinueAsync(step.Context, tokenResponse);
                    }
                    else if (command.StartsWith("welcome"))
                    {
                        await OAuthHelpers.SendWelcomeCardMessageAsync(step.Context, cancellationToken);
                    }

                    await _stateAccessors.CommandState.DeleteAsync(step.Context, cancellationToken);
                }
            }
            else
            {
                await step.Context.SendActivityAsync("We couldn't log you in. Please try again later.", cancellationToken : cancellationToken);
            }

            return(await step.EndDialogAsync(cancellationToken : cancellationToken));
        }
示例#3
0
        /// <summary>
        /// This controls what happens when an <see cref="Activity"/> gets sent to the bot.
        /// </summary>
        /// <param name="turnContext">A <see cref="ITurnContext"/> containing all the data needed
        /// for processing this conversation turn. </param>
        /// <param name="cancellationToken">(Optional) A <see cref="CancellationToken"/> that can be used by other objects
        /// or threads to receive notice of cancellation.</param>
        /// <returns>A <see cref="Task"/> that represents the work queued to execute.</returns>
        public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
        {
            DialogContext dc = null;

            switch (turnContext.Activity.Type)
            {
            case ActivityTypes.Message:
                await ProcessInputAsync(turnContext, cancellationToken);

                break;

            case ActivityTypes.Event:
            case ActivityTypes.Invoke:
                // This handles the Microsoft Teams Invoke Activity sent when magic code is not used.
                // See: https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/authentication/auth-oauth-card#getting-started-with-oauthcard-in-teams
                // Manifest Schema Here: https://docs.microsoft.com/en-us/microsoftteams/platform/resources/schema/manifest-schema
                // It also handles the Event Activity sent from The Emulator when the magic code is not used.
                // See: https://blog.botframework.com/2018/08/28/testing-authentication-to-your-bot-using-the-bot-framework-emulator/

                // Sanity check the activity type and channel Id.
                if (turnContext.Activity.Type == ActivityTypes.Invoke && turnContext.Activity.ChannelId != "msteams")
                {
                    throw new InvalidOperationException("The Invoke type is only valid onthe MSTeams channel.");
                }

                dc = await _dialogs.CreateContextAsync(turnContext, cancellationToken);

                await dc.ContinueDialogAsync(cancellationToken);

                if (!turnContext.Responded)
                {
                    await dc.BeginDialogAsync("graphDialog", cancellationToken : cancellationToken);
                }

                break;

            case ActivityTypes.ConversationUpdate:
                // Send a HeroCard as a welcome message when a new user joins the conversation.
                await OAuthHelpers.SendWelcomeMessageAsync(turnContext, cancellationToken : cancellationToken);

                break;
            }
        }