Esempio n. 1
0
        /// <summary>
        /// Get team posts as per configured categories for preference.
        /// </summary>
        /// <param name="teamPreferenceEntity">Team preference model object.</param>
        /// <param name="teamPosts">List of team posts.</param>
        /// <returns>List of team posts as per preference categories.</returns>
        private IEnumerable <IdeaEntity> GetDataAsPerCategories(
            TeamPreferenceEntity teamPreferenceEntity,
            IEnumerable <IdeaEntity> teamPosts)
        {
            var filteredPosts             = new List <IdeaEntity>();
            var preferenceCategoryIdsList = teamPreferenceEntity.Categories.Split(";").Where(category => !string.IsNullOrWhiteSpace(category)).ToList();

            teamPosts = teamPosts.OrderByDescending(c => c.UpdatedDate);

            // Loop through the list of filtered posts.
            foreach (var teamPost in teamPosts)
            {
                // Loop through the list of preference category ids.
                foreach (var preferenceCategoryId in preferenceCategoryIdsList)
                {
                    if (teamPost.CategoryId == preferenceCategoryId && filteredPosts.Count < MaxIdeasForNotification)
                    {
                        // If preference category is present then add it in the list.
                        filteredPosts.Add(teamPost);
                        break; // break the inner loop to check for next post.
                    }
                }

                // Break the entire loop after getting top 15 posts.
                if (filteredPosts.Count >= MaxIdeasForNotification)
                {
                    break;
                }
            }

            return(filteredPosts);
        }
        /// <summary>
        /// Stores or update team preference data in storage.
        /// </summary>
        /// <param name="teamPreferenceEntity">Holds team preference detail entity data.</param>
        /// <returns>A task that represents team preference entity data is saved or updated.</returns>
        private async Task <TableResult> StoreOrUpdateTeamPreferenceAsync(TeamPreferenceEntity teamPreferenceEntity)
        {
            await this.EnsureInitializedAsync();

            TableOperation addOrUpdateOperation = TableOperation.InsertOrReplace(teamPreferenceEntity);

            return(await this.GoodReadsCloudTable.ExecuteAsync(addOrUpdateOperation));
        }
        /// <summary>
        /// Get team posts as per configured tags for preference.
        /// </summary>
        /// <param name="teamPreferenceEntity">Team preference model object.</param>
        /// <param name="teamPosts">List of team posts.</param>
        /// <returns>List of team posts as per preference tags.</returns>
        private IEnumerable <PostEntity> GetDataAsPerTags(
            TeamPreferenceEntity teamPreferenceEntity,
            IEnumerable <PostEntity> teamPosts)
        {
            var  filteredPosts     = new List <PostEntity>();
            var  preferenceTagList = teamPreferenceEntity.Tags.Split(";").Where(tag => !string.IsNullOrWhiteSpace(tag));
            bool isTagMatched      = false;

            teamPosts = teamPosts.OrderByDescending(c => c.UpdatedDate);

            // Loop through the list of filtered posts.
            foreach (var teamPost in teamPosts)
            {
                // Split the comma separated post tags.
                var postTags = teamPost.Tags.Split(";").Where(tag => !string.IsNullOrWhiteSpace(tag));
                isTagMatched = false;

                // Loop through the list of preference tags.
                foreach (var preferenceTag in preferenceTagList)
                {
                    // Loop through the post tags.
                    foreach (var postTag in postTags)
                    {
                        // Check if the post tag and preference tag is same.
                        if (postTag.Trim() == preferenceTag.Trim())
                        {
                            // Set the flag to check the preference tag is present in post tag.
                            isTagMatched = true;
                            break; // break the loop to check for next preference tag with post tag.
                        }
                    }

                    if (isTagMatched && filteredPosts.Count < ListCardPostCount)
                    {
                        // If preference tag is present in post tag then add it in the list.
                        filteredPosts.Add(teamPost);
                        break; // break the inner loop to check for next post.
                    }
                }

                // Break the entire loop after getting top {ListCardPostCount} posts.
                if (filteredPosts.Count >= ListCardPostCount)
                {
                    break;
                }
            }

            return(filteredPosts.Take(ListCardPostCount));
        }
        /// <summary>
        /// Stores or update team preference data in Microsoft Azure Table storage.
        /// </summary>
        /// <param name="teamPreferenceEntity">Holds team preference detail entity data.</param>
        /// <returns>A task that represents team preference entity data is saved or updated.</returns>
        private async Task <TableResult> StoreOrUpdateEntityAsync(TeamPreferenceEntity teamPreferenceEntity)
        {
            await this.EnsureInitializedAsync();

            teamPreferenceEntity = teamPreferenceEntity ?? throw new ArgumentNullException(nameof(teamPreferenceEntity));

            if (string.IsNullOrWhiteSpace(teamPreferenceEntity.DigestFrequency) || string.IsNullOrWhiteSpace(teamPreferenceEntity.Categories))
            {
                return(null);
            }

            TableOperation addOrUpdateOperation = TableOperation.InsertOrReplace(teamPreferenceEntity);

            return(await this.CloudTable.ExecuteAsync(addOrUpdateOperation));
        }
        /// <summary>
        /// Create team preference model data.
        /// </summary>
        /// <param name="entity">Represents team preference entity object.</param>
        /// <returns>Represents team preference entity model.</returns>
        public TeamPreferenceEntity CreateTeamPreferenceModel(TeamPreferenceEntity entity)
        {
            try
            {
                entity             = entity ?? throw new ArgumentNullException(nameof(entity));
                entity.TeamId      = entity.TeamId;
                entity.CreatedDate = DateTime.UtcNow;
                entity.UpdatedDate = DateTime.UtcNow;

                return(entity);
            }
            catch (Exception ex)
            {
                this.logger.LogError(ex, "Exception occurred while preparing the team preference entity model data");
                throw;
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Send the given attachment to the specified team.
        /// </summary>
        /// <param name="teamPreferenceEntity">Team preference model object.</param>
        /// <param name="cardToSend">The attachment card to send.</param>
        /// <param name="serviceUrl">Service URL for a particular team.</param>
        /// <returns>A task that sends notification card in channel.</returns>
        private async Task SendCardToTeamAsync(
            TeamPreferenceEntity teamPreferenceEntity,
            Attachment cardToSend,
            string serviceUrl)
        {
            MicrosoftAppCredentials.TrustServiceUrl(serviceUrl);
            string teamsChannelId = teamPreferenceEntity.TeamId;

            var conversationReference = new ConversationReference()
            {
                ChannelId = Constants.TeamsBotFrameworkChannelId,
                Bot       = new ChannelAccount()
                {
                    Id = $"28:{this.botOptions.Value.MicrosoftAppId}"
                },
                ServiceUrl   = serviceUrl,
                Conversation = new ConversationAccount()
                {
                    Id = teamsChannelId
                },
            };

            this.logger.LogInformation($"sending notification to channelId- {teamsChannelId}");

            // Retry it in addition to the original call.
            await this.retryPolicy.ExecuteAsync(async() =>
            {
                try
                {
                    await((BotFrameworkAdapter)this.adapter).ContinueConversationAsync(
                        this.botOptions.Value.MicrosoftAppId,
                        conversationReference,
                        async(conversationTurnContext, conversationCancellationToken) =>
                    {
                        await conversationTurnContext.SendActivityAsync(MessageFactory.Attachment(cardToSend));
                    },
                        CancellationToken.None);
                }
                catch (Exception ex)
                {
                    this.logger.LogError(ex, $"Error while performing retry logic to send digest notification to channel for team: {teamsChannelId}.");
                    throw;
                }
            });
        }
        /// <summary>
        /// Stores or update team preference data in Microsoft Azure Table storage.
        /// </summary>
        /// <param name="teamPreferenceEntity">Represents team preference entity object.</param>
        /// <returns>A boolean that represents team preference entity is successfully saved/updated or not.</returns>
        public async Task <bool> UpsertTeamPreferenceAsync(TeamPreferenceEntity teamPreferenceEntity)
        {
            var result = await this.StoreOrUpdateEntityAsync(teamPreferenceEntity);

            return(result.HttpStatusCode == (int)HttpStatusCode.NoContent);
        }
        /// <summary>
        /// When OnTurn method receives a submit invoke activity on bot turn, it calls this method.
        /// </summary>
        /// <param name="turnContext">Provides context for a turn of a bot.</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 represents a task module response.</returns>
        protected override async Task <TaskModuleResponse> OnTeamsTaskModuleSubmitAsync(ITurnContext <IInvokeActivity> turnContext, TaskModuleRequest taskModuleRequest, CancellationToken cancellationToken)
        {
            try
            {
                if (turnContext == null || taskModuleRequest == null)
                {
                    return(new TaskModuleResponse
                    {
                        Task = new TaskModuleContinueResponse
                        {
                            Type = "continue",
                            Value = new TaskModuleTaskInfo()
                            {
                                Url = $"{this.options.Value.AppBaseUri}/error",
                                Height = TaskModuleHeight,
                                Width = TaskModuleWidth,
                                Title = this.localizer.GetString("ApplicationName"),
                            },
                        },
                    });
                }

                var preferenceData = JsonConvert.DeserializeObject <Preference>(taskModuleRequest.Data?.ToString());

                if (preferenceData == null)
                {
                    this.logger.LogInformation($"Request data obtained on task module submit action is null.");
                    await turnContext.SendActivityAsync(Strings.ErrorMessage).ConfigureAwait(false);

                    return(null);
                }

                // If user clicks Cancel button in task module.
                if (preferenceData.Command == CloseCommand)
                {
                    return(null);
                }

                if (preferenceData.Command == SubmitCommand)
                {
                    // Save or update digest preference for team.
                    if (preferenceData.ConfigureDetails != null)
                    {
                        var currentTeamPreferenceDetail = await this.teamPreferenceStorageProvider.GetTeamPreferenceAsync(preferenceData.ConfigureDetails.TeamId);

                        TeamPreferenceEntity teamPreferenceDetail;

                        if (currentTeamPreferenceDetail == null)
                        {
                            teamPreferenceDetail = new TeamPreferenceEntity
                            {
                                CreatedDate       = DateTime.UtcNow,
                                DigestFrequency   = preferenceData.ConfigureDetails.DigestFrequency,
                                Tags              = preferenceData.ConfigureDetails.Tags,
                                TeamId            = preferenceData.ConfigureDetails.TeamId,
                                UpdatedByName     = turnContext.Activity.From.Name,
                                UpdatedByObjectId = turnContext.Activity.From.AadObjectId,
                                UpdatedDate       = DateTime.UtcNow,
                                RowKey            = preferenceData.ConfigureDetails.TeamId,
                            };
                        }
                        else
                        {
                            currentTeamPreferenceDetail.DigestFrequency = preferenceData.ConfigureDetails.DigestFrequency;
                            currentTeamPreferenceDetail.Tags            = preferenceData.ConfigureDetails.Tags;
                            teamPreferenceDetail = currentTeamPreferenceDetail;
                        }

                        var upsertResult = await this.teamPreferenceStorageProvider.UpsertTeamPreferenceAsync(teamPreferenceDetail);
                    }
                    else
                    {
                        this.logger.LogInformation("Preference details received from task module is null.");
                        return(new TaskModuleResponse
                        {
                            Task = new TaskModuleContinueResponse
                            {
                                Type = "continue",
                                Value = new TaskModuleTaskInfo()
                                {
                                    Url = $"{this.options.Value.AppBaseUri}/error",
                                    Height = TaskModuleHeight,
                                    Width = TaskModuleWidth,
                                    Title = this.localizer.GetString("ApplicationName"),
                                },
                            },
                        });
                    }
                }

                return(null);
            }
#pragma warning disable CA1031 // Catching general exception for any errors occurred during saving data to table storage.
            catch (Exception ex)
#pragma warning restore CA1031 // Catching general exception for any errors occurred during saving data to table storage.
            {
                this.logger.LogError(ex, "Error in submit action of task module.");
                return(new TaskModuleResponse
                {
                    Task = new TaskModuleContinueResponse
                    {
                        Type = "continue",
                        Value = new TaskModuleTaskInfo()
                        {
                            Url = $"{this.options.Value.AppBaseUri}/error",
                            Height = TaskModuleHeight,
                            Width = TaskModuleWidth,
                            Title = this.localizer.GetString("ApplicationName"),
                        },
                    },
                });
            }
        }