/// <summary>
 /// Gets validation message details card.
 /// </summary>
 /// <param name="message">Message to show in card as validation.</param>
 /// <returns>Envelope for Task Module Response.</returns>
 public TaskModuleResponse GetValidationErrorCard(string message)
 {
     return(new TaskModuleResponse
     {
         Task = new TaskModuleContinueResponse
         {
             Value = new TaskModuleTaskInfo()
             {
                 Card = HiringManagerNotificationCard.GetValidationMessageCard(message),
                 Height = ValidationMessageTaskModuleHeight,
                 Width = ValidationMessageTaskModuleWidth,
                 Title = this.localizer.GetString("AppTitle"),
             },
         },
     });
 }
 /// <summary>
 /// Get team confirmation adaptive card.
 /// </summary>
 /// <param name="teamChannelMapping">Teams/Channel mappings.</param>
 /// <param name="introductionEntity">New hire introduction details.</param>
 /// <param name="isTeamSelected">false if not team has selected.</param>
 /// <returns>Envelope for Task Module Response.</returns>
 public TaskModuleResponse GetApproveDetailCard(List <Models.TeamDetail> teamChannelMapping, IntroductionEntity introductionEntity, bool isTeamSelected = true)
 {
     return(new TaskModuleResponse
     {
         Task = new TaskModuleContinueResponse
         {
             Value = new TaskModuleTaskInfo()
             {
                 Card = HiringManagerNotificationCard.GetTeamConfirmationCard(teamChannelMapping, this.localizer, introductionEntity, isTeamSelected),
                 Height = ApproveDetailTaskModuleHeight,
                 Width = ApproveDetailTaskModuleWidth,
                 Title = this.localizer.GetString("AppTitle"),
             },
         },
     });
 }
        /// <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"));
            }
        }
Пример #4
0
        /// <summary>
        /// Submit introduction card action.
        /// </summary>
        /// <param name="userGraphAccessToken">User access token.</param>
        /// <param name="turnContext">Provides context for a step in a bot dialog.</param>
        /// <param name="taskModuleRequest">Task module invoke request value payload.</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 returns submitted introduction card attachment as task module response.</returns>
        public async Task <TaskModuleResponse> SubmitIntroductionActionAsync(
            string userGraphAccessToken,
            ITurnContext <IInvokeActivity> turnContext,
            TaskModuleRequest taskModuleRequest,
            CancellationToken cancellationToken)
        {
            turnContext       = turnContext ?? throw new ArgumentNullException(nameof(turnContext));
            taskModuleRequest = taskModuleRequest ?? throw new ArgumentNullException(nameof(taskModuleRequest));

            var userDetails = await this.GetUserDetailAsync(turnContext, cancellationToken);

            IntroductionEntity introductionEntity = await this.GenerateIntroductionEntityAsync(
                turnContext,
                taskModuleRequest,
                userDetails);

            var questionnaire = JsonConvert.DeserializeObject <List <IntroductionDetail> >(introductionEntity.NewHireQuestionnaire);

            if (!questionnaire.Where(row => string.IsNullOrEmpty(row.Answer)).ToList().Any() &&
                !string.IsNullOrWhiteSpace(introductionEntity.NewHireProfileNote))
            {
                // Get Manager details from Microsoft Graph API.
                var myManager = await this.userProfileGraphApiHelper.GetMyManagerAsync(userGraphAccessToken);

                if (myManager == null)
                {
                    this.logger.LogWarning($"Error in getting manager details from Microsoft Graph API for user {turnContext.Activity.From.Id}.");
                    await turnContext.SendActivityAsync(this.localizer.GetString("UserNotMappedWithManagerMessageText"));

                    return(null);
                }

                // Get Manager's conversation id from storage.
                var userConversationDetails = await this.userStorageProvider.GetUserDetailAsync(myManager.Id);

                if (userConversationDetails == null)
                {
                    this.logger.LogWarning($"Error in getting user conversation details from storage for user {myManager.Id}.");
                    await turnContext.SendActivityAsync(this.localizer.GetString("ManagerUnavailableText"));

                    return(null);
                }

                introductionEntity.ManagerAadObjectId    = myManager.Id;
                introductionEntity.ManagerConversationId = userConversationDetails.ConversationId;

                await this.introductionStorageProvider.StoreOrUpdateIntroductionDetailAsync(introductionEntity);

                await turnContext.SendActivityAsync(this.localizer.GetString("IntroSubmittedMessage"));

                this.logger.LogInformation($"Introduction submitted by: {turnContext.Activity.From.Id}.");

                var hiringMangerNotification = MessageFactory.Attachment(HiringManagerNotificationCard.GetNewEmployeeIntroductionCard(this.botOptions.Value.AppBaseUri, this.localizer, introductionEntity));
                hiringMangerNotification.Conversation = new ConversationAccount {
                    Id = introductionEntity.ManagerConversationId
                };
                await turnContext.Adapter.SendActivitiesAsync(turnContext, new Activity[] { (Activity)hiringMangerNotification }, cancellationToken);

                return(null);
            }
            else
            {
                // send back introduction card with corresponding validation message.
                return(this.introductionCardHelper.GetNewHireIntroductionCard(introductionEntity, isAllQuestionAnswered: false));
            }
        }