Esempio n. 1
0
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            graphics.IsFullScreen          = true;
            graphics.SupportedOrientations = DisplayOrientation.LandscapeRight;
            Content.RootDirectory          = "Content";

            Statistics.maxMushrooms = 0;
            Statistics.maxBloobs    = 0;
            Statistics.maxSpecials  = 0;
            Statistics.maxCombo     = 0;
            Statistics.maxJumps     = 0;
            Statistics.maxPoints    = 0;


            infoCard      = new InfoCard();
            statisticCard = new StatisticsCard();
            devInfoCard   = new DevelopInfoCard();
            helpCard      = new HelpCard();
            // var wbt = new WebBrowserTask();
            // wbt.URL = "http://stackoverflow.com/";
            // wbt.Show();
            // Facebook.HttpMethod
            // Facebook.FacebookClient face = new Facebook.FacebookClient();
            // face.
        }
Esempio n. 2
0
        /// <summary>
        /// Send help card containing commands recognized by bot.
        /// </summary>
        /// <param name="stepContext">Context object passed in to a WaterfallStep.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        private async Task ShowHelpCardAsync(WaterfallStepContext stepContext)
        {
            var reply = stepContext.Context.Activity.CreateReply();

            reply.AttachmentLayout = AttachmentLayoutTypes.Carousel;
            reply.Attachments      = HelpCard.GetHelpAttachments();
            await stepContext.Context.SendActivityAsync(reply).ConfigureAwait(false);
        }
Esempio n. 3
0
        protected void RelationClickedHandler(object sender, DynamicCardControl.RelationClickedEventArgs e)
        {
            TeplatesFilters.Visible    = false;
            SaveObjects.Visible        = false;
            DeleteImage.Visible        = false;
            DeleteInstance.Visible     = false;
            ListEntity.Visible         = false;
            RecordsNumberLabel.Visible = false;


            var relation = e.Relation;

            var reader = new DatabaseReader(Teleform.ProjectMonitoring.HttpApplication.Global.ConnectionString);

            var entID = int.Parse(e.Relation.Entity.ID.ToString());

            var instanceID = reader.GetInstanceID(relation);

            InitializeDynamicCards(HelpCard, entID, instanceID, null);

            HelpCard.Recreate();

            AdditionalViews.SetActiveView(ObjectView);
        }
        /// <inheritdoc/>
        protected override async Task OnMessageActivityAsync(ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            try
            {
                await this.SendTypingIndicatorAsync(turnContext);

                var    conversationType = turnContext.Activity.Conversation.ConversationType;
                string conversationId   = turnContext.Activity.Conversation.Id;

                if (string.Compare(conversationType, "groupChat", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    if (turnContext.Activity.Type.Equals(ActivityTypes.Message))
                    {
                        turnContext.Activity.RemoveRecipientMention();

                        switch (turnContext.Activity.Text.Trim().ToLower())
                        {
                        case Constants.Start:
                            this.telemetryClient.TrackTrace($"scrum {conversationId} started by {turnContext.Activity.From.Id}");

                            var scrum = await this.scrumProvider.GetScrumAsync(conversationId);

                            if (scrum != null && scrum.IsScrumRunning)
                            {
                                // check if member in scrum exists.
                                // A user is added during a running scrum and tries to start a new scrum.
                                var activityId = this.GetActivityIdToMatch(scrum.MembersActivityIdMap, turnContext.Activity.From.Id);
                                if (activityId == null)
                                {
                                    await turnContext.SendActivityAsync(string.Format(Resources.NoPartOfScrumStartText, turnContext.Activity.From.Name));

                                    this.telemetryClient.TrackTrace($"Member who is updating the scrum is not the part of scrum for : {conversationId}");
                                }
                                else
                                {
                                    this.telemetryClient.TrackTrace($"Scrum is already running for conversation id {conversationId}");
                                    await turnContext.SendActivityAsync(Resources.RunningScrumMessage);
                                }
                            }
                            else
                            {
                                // start a new scrum
                                this.telemetryClient.TrackTrace($"Scrum start for : {conversationId}");
                                await this.StartScrumAsync(turnContext, cancellationToken);
                            }

                            break;

                        case Constants.TakeATour:
                            var tourCards = TourCard.GetTourCards(this.configuration["AppBaseURL"]);
                            await turnContext.SendActivityAsync(MessageFactory.Carousel(tourCards));

                            break;

                        case Constants.CompleteScrum:
                            var scrumInfo = await this.scrumProvider.GetScrumAsync(conversationId);

                            if (scrumInfo.IsScrumRunning)
                            {
                                var activityId = this.GetActivityIdToMatch(scrumInfo.MembersActivityIdMap, turnContext.Activity.From.Id);

                                // check if member in scrum exists.
                                // A user is added during a running scrum and tries to complete the running scrum.
                                if (activityId == null)
                                {
                                    await turnContext.SendActivityAsync(string.Format(Resources.NoPartOfCompleteScrumText, turnContext.Activity.From.Name));

                                    this.telemetryClient.TrackTrace($"Member who is updating the scrum is not the part of scrum for : {conversationId}");
                                }
                                else
                                {
                                    var cardId   = scrumInfo.ScrumStartActivityId;
                                    var activity = MessageFactory.Attachment(ScrumCompleteCard.GetScrumCompleteCard());
                                    activity.Id           = cardId;
                                    activity.Conversation = turnContext.Activity.Conversation;
                                    await turnContext.UpdateActivityAsync(activity, cancellationToken);

                                    // Update the trail card
                                    var    dateString       = string.Format("{{{{TIME({0})}}}}", DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"));
                                    string cardTrailMessage = string.Format(Resources.ScrumCompletedByText, turnContext.Activity.From.Name, dateString);
                                    await this.UpdateTrailCard(cardTrailMessage, turnContext, cancellationToken);

                                    scrumInfo.IsScrumRunning       = false;
                                    scrumInfo.ThreadConversationId = conversationId;
                                    var savedData = await this.scrumProvider.SaveOrUpdateScrumAsync(scrumInfo);

                                    if (!savedData)
                                    {
                                        await turnContext.SendActivityAsync(Resources.ErrorMessage);

                                        return;
                                    }

                                    this.telemetryClient.TrackTrace($"Scrum completed by: {turnContext.Activity.From.Name} for {conversationId}");
                                }
                            }
                            else
                            {
                                await turnContext.SendActivityAsync(Resources.CompleteScrumErrorText);
                            }

                            break;

                        default:
                            await turnContext.SendActivityAsync(MessageFactory.Attachment(HelpCard.GetHelpCard()), cancellationToken);

                            break;
                        }
                    }
                }
                else
                {
                    await turnContext.SendActivityAsync(Resources.ScopeErrorMessage);
                }
            }
            catch (Exception ex)
            {
                this.telemetryClient.TrackTrace($"For {turnContext.Activity.Conversation.Id} : Message Activity failed: {ex.Message}");
                this.telemetryClient.TrackException(ex);
            }
        }
        /// <summary>
        /// Handle when a message is addressed to the bot.
        /// </summary>
        /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param>
        /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param>
        /// <returns>A Task resolving to either a login card or the adaptive card of the Reddit post.</returns>
        /// <remarks>
        /// For more information on bot messaging in Teams, see the documentation
        /// https://docs.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/conversation-basics?tabs=dotnet#receive-a-message .
        /// </remarks>
        protected override async Task OnMessageActivityAsync(ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            turnContext = turnContext ?? throw new ArgumentNullException(nameof(turnContext));

            this.RecordEvent(nameof(this.OnMessageActivityAsync), turnContext);
            var activity = turnContext.Activity;
            var command  = activity.Text.ToUpperInvariant().Trim();

            await this.SendTypingIndicatorAsync(turnContext);

            if (activity.Conversation.ConversationType == CardConstants.PersonalConversationType)
            {
                var userGraphAccessToken = await this.tokenHelper.GetUserTokenAsync(activity.From.Id);

                if (userGraphAccessToken == null)
                {
                    await this.dialog.RunAsync(turnContext, this.conversationState.CreateProperty <DialogState>(nameof(DialogState)), cancellationToken);

                    return;
                }

                // Command to send feedback card.
                if (command.Equals(this.localizer.GetString("ShareFeedbackText").ToString(), StringComparison.InvariantCultureIgnoreCase))
                {
                    var shareFeedbackCardActivity = MessageFactory.Attachment(FeedbackCard.GetFeedbackCardAttachment(this.localizer));
                    await turnContext.SendActivityAsync(shareFeedbackCardActivity, cancellationToken);

                    return;
                }

                // Command to save feedback.
                else if (command.Equals(this.localizer.GetString("SubmitFeedbackCommandText").ToString(), StringComparison.InvariantCultureIgnoreCase))
                {
                    await this.activityHelper.SubmitFeedbackAsync(turnContext);

                    return;
                }

                // Command to send on-boarding checklist card.
                else if (command.Equals(this.localizer.GetString("OnBoardingCheckListText").ToString(), StringComparison.InvariantCultureIgnoreCase))
                {
                    var userDetail = await this.userStorageProvider.GetUserDetailAsync(activity.From.AadObjectId);

                    bool isNewHire = userDetail?.UserRole == (int)UserRole.NewHire;

                    // Learning plan bot command supports only for new hire.
                    if (!isNewHire)
                    {
                        await turnContext.SendActivityAsync(MessageFactory.Attachment(OnBoardingCheckListCard.GetCard(this.localizer, this.botOptions.Value.ManifestId)));

                        return;
                    }

                    await this.learningPlanHelper.GetWeeklyLearningPlanCardAsync(turnContext, userDetail.BotInstalledOn);
                }

                // Bot sign-out command.
                else if (command.Equals(this.localizer.GetString("LogoutText").ToString(), StringComparison.InvariantCultureIgnoreCase))
                {
                    await this.dialog.RunAsync(turnContext, this.conversationState.CreateProperty <DialogState>(nameof(DialogState)), cancellationToken);

                    return;
                }

                // Command to send more info card to new hire employee.
                else if (command.Equals(this.localizer.GetString("RequestMoreInfoText").ToString(), StringComparison.InvariantCultureIgnoreCase))
                {
                    var valuesfromCard = ((JObject)activity.Value).ToObject <AdaptiveSubmitActionData>();
                    await this.activityHelper.RequestMoreInfoActionAsync(turnContext, valuesfromCard, cancellationToken);

                    return;
                }

                // Command to send user tour based on his role.
                else if (command.Equals(this.localizer.GetString("HelpText").ToString(), StringComparison.InvariantCultureIgnoreCase))
                {
                    var userDetail = await this.userStorageProvider.GetUserDetailAsync(activity.From.AadObjectId);

                    bool isManager = userDetail?.UserRole == (int)UserRole.HiringManager;

                    // Send help cards based on their role.
                    await turnContext.SendActivityAsync(MessageFactory.Carousel(CarouselCard.GetUserHelpCards(
                                                                                    this.botOptions.Value.AppBaseUri,
                                                                                    this.localizer,
                                                                                    this.botOptions.Value.ManifestId,
                                                                                    isManager)));

                    return;
                }

                // Command to send pending review introduction list card.
                else if (command.Equals(this.localizer.GetString("ReviewIntroductionText").ToString(), StringComparison.InvariantCultureIgnoreCase))
                {
                    var user = await this.userStorageProvider.GetUserDetailAsync(activity.From.AadObjectId);

                    if (user != null && user.UserRole != (int)UserRole.HiringManager)
                    {
                        await turnContext.SendActivityAsync(MessageFactory.Attachment(HelpCard.GetCard(this.localizer)));

                        return;
                    }

                    var introductionEntities = await this.introductionStorageProvider.GetFilteredIntroductionsAsync(activity.From.AadObjectId);

                    if (!introductionEntities.Any())
                    {
                        await turnContext.SendActivityAsync(this.localizer.GetString("NoPendingIntroductionText"));

                        return;
                    }

                    var batchCount = (int)Math.Ceiling((double)introductionEntities.Count() / ListCardItemsLimit);
                    for (int batchIndex = 0; batchIndex < batchCount; batchIndex++)
                    {
                        var batchWiseIntroductionEntities = introductionEntities
                                                            .Skip(batchIndex * ListCardItemsLimit)
                                                            .Take(ListCardItemsLimit);

                        var listCardAttachment = await this.introductionCardHelper.GetReviewIntroductionListCardAsync(batchWiseIntroductionEntities, userGraphAccessToken);

                        await turnContext.SendActivityAsync(MessageFactory.Attachment(listCardAttachment));
                    }

                    return;
                }

                // Command to send week wise learning plan cards.
                else if (command.Equals(this.localizer.GetString("ViewLearningText").ToString(), StringComparison.InvariantCultureIgnoreCase))
                {
                    var userDetail = await this.userStorageProvider.GetUserDetailAsync(activity.From.AadObjectId);

                    await this.learningPlanHelper.GetWeeklyLearningPlanCardAsync(turnContext, userDetail.BotInstalledOn);
                }

                // Command to resume/pause all matches.
                else if (command.Equals(BotCommandConstants.ResumeAllMatches, StringComparison.InvariantCultureIgnoreCase) ||
                         command.Equals(BotCommandConstants.PauseAllMatches, StringComparison.InvariantCultureIgnoreCase))
                {
                    await this.activityHelper.GetUpdatedMatchesStatusAsync(turnContext, command, cancellationToken);
                }
                else
                {
                    // If message is from complete learning plan list item tap event.
                    if (command.StartsWith(this.localizer.GetString("ViewWeeklyLearningPlanCommandText"), StringComparison.InvariantCultureIgnoreCase))
                    {
                        // Get learning plan card selected from complete learning plan list card.
                        var learningCard = await this.learningPlanHelper.GetLearningPlanCardAsync(command);

                        // Send learning plan data card.
                        await turnContext.SendActivityAsync(MessageFactory.Attachment(learningCard));
                    }
                    else if (command.StartsWith(this.localizer.GetString("ReviewIntroductionCommandText"), StringComparison.InvariantCultureIgnoreCase))
                    {
                        // Get all Introductions for given Azure Active directory id.
                        if (command.Split(":").Length != 2 || string.IsNullOrWhiteSpace(command.Split(":")[1]))
                        {
                            await turnContext.SendActivityAsync(this.localizer.GetString("ReviewIntroductionInvalidCommandText"));

                            return;
                        }

                        var result = await this.introductionStorageProvider.GetAllIntroductionsAsync(activity.From.AadObjectId);

                        var introductionEntity = result.Where(entity => entity.NewHireName.ToUpperInvariant() == command.Split(":")[1].ToUpperInvariant()).FirstOrDefault();
                        if (introductionEntity != null && (introductionEntity.ApprovalStatus == (int)IntroductionStatus.Approved))
                        {
                            // Send already approved message to hiring manager.
                            await turnContext.SendActivityAsync(this.localizer.GetString("ManagerApprovalValidationText"));
                        }
                        else
                        {
                            await turnContext.SendActivityAsync(MessageFactory.Attachment(HiringManagerNotificationCard.GetNewEmployeeIntroductionCard(this.botOptions.Value.AppBaseUri, this.localizer, introductionEntity)));
                        }
                    }
                    else
                    {
                        // Send help card for un supported bot command.
                        await turnContext.SendActivityAsync(MessageFactory.Attachment(HelpCard.GetCard(this.localizer)));
                    }

                    return;
                }
            }
            else
            {
                await turnContext.SendActivityAsync(this.localizer.GetString("UnSupportedBotCommand"));
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Handle message activity in channel.
        /// </summary>
        /// <param name="message">A message in a conversation.</param>
        /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param>
        /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        private async Task OnMessageActivityInChannelAsync(
            IMessageActivity message,
            ITurnContext <IMessageActivity> turnContext,
            CancellationToken cancellationToken)
        {
            try
            {
                if (message.Type.Equals(ActivityTypes.Message, StringComparison.OrdinalIgnoreCase))
                {
                    string actionType = message.Value != null?JObject.Parse(message.Value.ToString())["AdaptiveActionType"]?.ToString() : null;

                    string scrumMembers = message.Value != null?JObject.Parse(message.Value.ToString())["ScrumMembers"]?.ToString() : null;

                    message.RemoveRecipientMention();
                    string text = string.IsNullOrEmpty(message.Text) ? actionType : message.Text;

                    switch (text.ToUpperInvariant().Trim())
                    {
                    case Constants.EndScrum:
                        string conversationId = message.Conversation.Id;
                        string scrumMasterId  = JObject.Parse(message.Value.ToString())["ScrumMasterId"].ToString();
                        var    scrumInfo      = await this.scrumHelper.GetActiveScrumAsync(scrumMasterId);

                        var activitySummary = await this.activityHelper.GetEndScrumSummaryActivityAsync(scrumInfo, conversationId, scrumMembers, turnContext, cancellationToken);

                        if (activitySummary != null)
                        {
                            this.logger.LogInformation($"Scrum completed by: {turnContext.Activity.From.Name} for {conversationId} with ScrumStartCardResponseId: {scrumInfo.ScrumStartCardResponseId}");
                            await turnContext.UpdateActivityAsync(activitySummary, cancellationToken);

                            await turnContext.SendActivityAsync(this.localizer.GetString("SuccessMessageAfterEndingScrum"), cancellationToken : cancellationToken);
                        }

                        break;

                    case Constants.Help:
                        this.logger.LogInformation("Sending help card");
                        var helpAttachment = HelpCard.GetHelpCard(this.localizer);
                        await turnContext.SendActivityAsync(MessageFactory.Attachment(helpAttachment), cancellationToken);

                        break;

                    case Constants.Settings:
                        this.logger.LogInformation("Sending settings button card");
                        var settingsAttachment = SettingsCard.GetSettingsCard(this.localizer);
                        await turnContext.SendActivityAsync(MessageFactory.Attachment(settingsAttachment), cancellationToken);

                        break;

                    default:
                        this.logger.LogInformation("Invalid command text entered in channel. Sending help card");
                        var helpAttachmentcard = HelpCard.GetHelpCard(this.localizer);
                        await turnContext.SendActivityAsync(MessageFactory.Attachment(helpAttachmentcard), cancellationToken);

                        break;
                    }
                }
                else
                {
                    await turnContext.SendActivityAsync(this.localizer.GetString("InformationAboutBotInstallationLimitation"), cancellationToken : cancellationToken);
                }
            }
            catch (Exception ex)
            {
                await turnContext.SendActivityAsync(this.localizer.GetString("ErrorMessage"), cancellationToken : cancellationToken);

                this.logger.LogError(ex, $"Error processing message: {ex.Message}", SeverityLevel.Error);
            }
        }
        /// <summary>
        /// When OnTurn method receives a message activity on bot turn, it calls this method.
        /// </summary>
        /// <param name="turnContext">Provides context for a turn of a bot.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        protected override async Task OnMessageActivityAsync(ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            try
            {
                var activity = turnContext.Activity;

                // if card from messaging extension is sent to the bot conversation.
                if (activity.Attachments != null)
                {
                    return;
                }
                else
                {
                    var command = activity.Text;
                    await this.SendTypingIndicatorAsync(turnContext).ConfigureAwait(false);

                    if (activity.Text == null && activity.Value != null && activity.Type == ActivityTypes.Message)
                    {
                        command = JToken.Parse(activity.Value.ToString()).SelectToken("command").ToString();
                    }

                    switch (command.ToUpperInvariant().Trim())
                    {
                    case Constants.MyProfile:
                        await this.dialog.RunAsync(turnContext, this.conversationState.CreateProperty <DialogState>(nameof(DialogState)), cancellationToken).ConfigureAwait(false);

                        break;

                    case Constants.Search:
                        await this.dialog.RunAsync(turnContext, this.conversationState.CreateProperty <DialogState>(nameof(DialogState)), cancellationToken).ConfigureAwait(false);

                        break;

                    default:
                        await turnContext.SendActivityAsync(MessageFactory.Attachment(HelpCard.GetHelpCard())).ConfigureAwait(false);

                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                this.logger.LogError(ex, $"Error in message activity of bot for {turnContext.Activity.Conversation.Id}");
            }
        }
        /// <summary>
        /// Check for unknown input, and show the help prompt.
        /// </summary>
        /// <param name="stepContext">Provides context for a step in a bot dialog.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <returns>Tracking task.</returns>
        private async Task <DialogTurnResult> CheckForUnknownInputAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var activity = stepContext.Context.Activity;

            if (activity.Type == ActivityTypes.Message)
            {
                if (activity.Text == null)
                {
                    return(await stepContext.NextAsync());
                }
                else if (activity.Text.Trim().Equals(Strings.BotCommandMyProfile, StringComparison.CurrentCultureIgnoreCase) ||
                         activity.Text.Trim().Equals(Strings.BotCommandSearch, StringComparison.CurrentCultureIgnoreCase))
                {
                    return(await stepContext.NextAsync());
                }
                else
                {
                    await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(HelpCard.GetHelpCard())).ConfigureAwait(false);

                    return(await stepContext.EndDialogAsync().ConfigureAwait(false));
                }
            }

            return(await stepContext.NextAsync());
        }
        /// <summary>
        /// Get user profile or search or edit profile based on activity type.
        /// </summary>
        /// <param name="stepContext">Provides context for a step in a bot dialog.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <returns>Tracking task.</returns>
        private async Task <DialogTurnResult> MyProfileAndSearchAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var activity = stepContext.Context.Activity;

            var tokenResponse = (TokenResponse)stepContext.Result;

            if (tokenResponse == null)
            {
                this.logger.LogInformation($"User is not authenticated and token is null for: {activity.Conversation.Id}.");
                await stepContext.Context.SendActivityAsync(Strings.NotLoggedInText).ConfigureAwait(false);

                return(await stepContext.EndDialogAsync().ConfigureAwait(false));
            }

            var token = tokenResponse.Token;

            // signin/verifyState activity name used here to send my profile card after successful sign in.
            if ((activity.Type == MessageActivityType) || (activity.Name == SignInActivityName))
            {
                var command = ((string)stepContext.Values["command"]).Trim();

                if (command.Equals(Strings.BotCommandMyProfile, StringComparison.CurrentCultureIgnoreCase) || command.Equals(Constants.MyProfile))
                {
                    this.logger.LogInformation("My profile command triggered", new Dictionary <string, string>()
                    {
                        { "User", activity.From.Id }, { "AADObjectId", activity.From.AadObjectId }
                    });
                    await this.MyProfileAsync(token, stepContext, cancellationToken).ConfigureAwait(false);
                }
                else if (command.Equals(Strings.BotCommandSearch, StringComparison.CurrentCultureIgnoreCase) || command.Equals(Constants.Search))
                {
                    this.logger.LogInformation("Search command triggered", new Dictionary <string, string>()
                    {
                        { "User", activity.From.Id }, { "AADObjectId", activity.From.AadObjectId }
                    });
                    await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(SearchCard.GetSearchCard())).ConfigureAwait(false);
                }
                else
                {
                    await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(HelpCard.GetHelpCard())).ConfigureAwait(false);
                }
            }

            // submit-invoke request at edit profile
            else if (activity.Type == InvokeActivityType)
            {
                await this.EditProfileAsync(token, stepContext, cancellationToken).ConfigureAwait(false);
            }

            return(await stepContext.EndDialogAsync().ConfigureAwait(false));
        }
        /// <summary>
        /// Check for unknown input, and show the help prompt.
        /// </summary>
        /// <param name="stepContext">Provides context for a step in a bot dialog.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <returns>Tracking task.</returns>
        private async Task <DialogTurnResult> CheckForUnknownInputAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var activity = stepContext.Context.Activity;

            if (activity.Type == ActivityTypes.Message)
            {
                switch (activity.Text?.Trim())
                {
                case Constants.MyProfile:
                case Constants.Search:
                case null:
                    return(await stepContext.NextAsync());

                default:
                    await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(HelpCard.GetHelpCard())).ConfigureAwait(false);

                    return(await stepContext.EndDialogAsync().ConfigureAwait(false));
                }
            }

            return(await stepContext.NextAsync());
        }
        /// <summary>
        /// Handle message activity in channel.
        /// </summary>
        /// <param name="message">A message in a conversation.</param>
        /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param>
        /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        private async Task OnMessageActivityInChannelAsync(
            IMessageActivity message,
            ITurnContext <IMessageActivity> turnContext,
            CancellationToken cancellationToken)
        {
            string actionType = message.Value != null?JObject.Parse(message.Value.ToString())["AdaptiveActionType"]?.ToString() : null;

            string scrumMembers = message.Value != null?JObject.Parse(message.Value.ToString())["ScrumMembers"]?.ToString() : null;

            message.RemoveRecipientMention();
            string text = string.IsNullOrEmpty(message.Text) ? actionType : message.Text;

            switch (text.ToUpperInvariant().Trim())
            {
            case Constants.EndScrum:     // command to handle end scrum.
                string conversationId    = message.Conversation.Id;
                string scrumTeamConfigId = JObject.Parse(message.Value.ToString())["ScrumTeamConfigId"].ToString();
                string aadGroupId        = await this.activityHelper.GetTeamAadGroupIdAsync(turnContext, cancellationToken);

                var scrumInfo = await this.scrumHelper.GetActiveScrumAsync(scrumTeamConfigId, aadGroupId);

                if (scrumInfo == null || scrumInfo.IsCompleted)
                {
                    await turnContext.SendActivityAsync(string.Format(CultureInfo.CurrentCulture, this.localizer.GetString("ErrorScrumDoesNotExist"), turnContext.Activity.From.Name), cancellationToken : cancellationToken);

                    break;
                }

                scrumInfo.IsCompleted          = true;
                scrumInfo.ThreadConversationId = conversationId;
                var scrumSaveResponse = await this.scrumStorageProvider.CreateOrUpdateScrumAsync(scrumInfo);

                if (!scrumSaveResponse)
                {
                    this.logger.LogError("Error in saving scrum information in storage.");
                    await turnContext.SendActivityAsync(this.localizer.GetString("ErrorSavingScrumData"), cancellationToken : cancellationToken);

                    break;
                }

                var activitySummary = await this.activityHelper.GetEndScrumSummaryActivityAsync(scrumInfo, conversationId, scrumMembers, turnContext, cancellationToken);

                if (activitySummary != null)
                {
                    this.logger.LogInformation($"Scrum completed by: {turnContext.Activity.From.AadObjectId} for {conversationId} with ScrumStartCardResponseId: {scrumInfo.ScrumStartCardResponseId}");
                    await turnContext.UpdateActivityAsync(activitySummary, cancellationToken);

                    await turnContext.SendActivityAsync(this.localizer.GetString("SuccessMessageAfterEndingScrum"), cancellationToken : cancellationToken);
                }

                break;

            case Constants.Help:     // command to show help card.
                this.logger.LogInformation("Sending help card");
                var helpAttachment = HelpCard.GetHelpCard(this.localizer);
                await turnContext.SendActivityAsync(MessageFactory.Attachment(helpAttachment), cancellationToken);

                break;

            case Constants.Settings:     // Command to show adaptive card with settings CTA button.
                this.logger.LogInformation("Sending settings button card");
                var settingsAttachment = SettingsCard.GetSettingsCard(this.localizer);
                await turnContext.SendActivityAsync(MessageFactory.Attachment(settingsAttachment), cancellationToken);

                break;

            default:
                this.logger.LogInformation("Invalid command text entered in channel. Sending help card");
                var helpAttachmentcard = HelpCard.GetHelpCard(this.localizer);
                await turnContext.SendActivityAsync(MessageFactory.Attachment(helpAttachmentcard), cancellationToken);

                break;
            }
        }