async Task <TEntityReply> SendAsync(TEntityReply reply, IList <int> usersToExclude)
        {
            if (reply == null)
            {
                throw new ArgumentNullException(nameof(reply));
            }

            // Get the entity for the reply
            var entity = await _entityStore.GetByIdAsync(reply.EntityId);

            // Ensure the entity exists
            if (entity == null)
            {
                return(reply);
            }

            // We don't need to trigger notifications for hidden entities
            if (entity.IsHidden())
            {
                return(reply);
            }

            // Defer notifications
            _deferredTaskManager.AddTask(async context =>
            {
                await SendNotificationsAsync(reply, usersToExclude);
            });

            return(reply);
        }
Beispiel #2
0
        Task <TEntity> SendAsync(TEntity entity, IList <int> usersToExclude)
        {
            if (entity == null)
            {
                throw new ArgumentNullException(nameof(entity));
            }

            // We don't need to trigger notifications for hidden entities
            if (entity.IsHidden())
            {
                return(Task.FromResult(entity));
            }

            // Defer notifications to first available thread pool thread
            _deferredTaskManager.AddTask(async context =>
            {
                // Send follow for specific category returning a list of notified user ids
                var notifiedUsers = await SendNotificationsForCategoryAsync(entity, usersToExclude);

                // Append excluded users to our list of already notified users
                foreach (var userToExclude in usersToExclude)
                {
                    notifiedUsers.Add(userToExclude);
                }

                // Send notifications for all categories excluding any already notified users
                await SendNotificationsForAllCategoriesAsync(entity, notifiedUsers);
            });

            return(Task.FromResult(entity));
        }
Beispiel #3
0
        public async Task <ISpamOperatorResult <Reply> > UpdateModelAsync(ISpamOperatorContext <Reply> context)
        {
            // Perform validation
            var validation = await ValidateModelAsync(context);

            // Create result
            var result = new SpamOperatorResult <Reply>();

            // Not an operator of interest
            if (validation == null)
            {
                return(result.Success(context.Model));
            }

            // If validation succeeded no need to perform further actions
            if (validation.Succeeded)
            {
                return(result.Success(context.Model));
            }

            // Get reply author
            var user = await BuildUserAsync(context.Model);

            if (user == null)
            {
                return(null);
            }

            // Flag user as SPAM?
            if (context.Operation.FlagAsSpam)
            {
                var bot = await _platoUserStore.GetPlatoBotAsync();

                // Mark user as SPAM
                if (!user.IsSpam)
                {
                    user.IsSpam = true;
                    user.IsSpamUpdatedUserId = bot?.Id ?? 0;
                    user.IsSpamUpdatedDate   = DateTimeOffset.UtcNow;
                    await _platoUserStore.UpdateAsync(user);
                }

                // Mark reply as SPAM
                if (!context.Model.IsSpam)
                {
                    context.Model.IsSpam = true;
                    await _replyStore.UpdateAsync(context.Model);
                }
            }

            // Defer notifications for execution after request completes
            _deferredTaskManager.AddTask(async ctx =>
            {
                await NotifyAsync(context);
            });

            // Return failed with our updated model and operation
            // This provides the calling code with the operation error message
            return(result.Failed(context.Model, context.Operation));
        }
Beispiel #4
0
        public Task ReportAsync(ReportSubmission <Reply> submission)
        {
            // Defer notifications for execution after request completes
            _deferredTaskManager.AddTask(async ctx =>
            {
                // Get users to notify
                var users = await _platoUserStore.QueryAsync()
                            .Select <UserQueryParams>(q =>
                {
                    q.RoleName.IsIn(new[]
                    {
                        DefaultRoles.Administrator,
                        DefaultRoles.Staff
                    });
                })
                            .ToList();

                // No users to notify
                if (users?.Data == null)
                {
                    return;
                }

                // If anonymous use bot as sender
                var from = submission.Who ??
                           await _platoUserStore.GetPlatoBotAsync();

                // Send notifications
                foreach (var user in users.Data)
                {
                    // Web notification
                    if (user.NotificationEnabled(_userNotificationTypeDefaults, WebNotifications.ReplyReport))
                    {
                        await _notificationManager.SendAsync(new Notification(WebNotifications.ReplyReport)
                        {
                            To   = user,
                            From = from
                        }, submission);
                    }

                    // Email notification
                    if (user.NotificationEnabled(_userNotificationTypeDefaults, EmailNotifications.ReplyReport))
                    {
                        await _notificationManager.SendAsync(new Notification(EmailNotifications.ReplyReport)
                        {
                            To = user
                        }, submission);
                    }
                }
            });

            return(Task.CompletedTask);
        }
Beispiel #5
0
        Task <TEntity> SendAsync(TEntity entity, IList <int> usersToExclude)
        {
            if (entity == null)
            {
                throw new ArgumentNullException(nameof(entity));
            }

            // We don't need to trigger notifications for hidden entities
            if (entity.IsHidden())
            {
                return(Task.FromResult(entity));
            }

            // Defer notifications
            _deferredTaskManager.AddTask(async context =>
            {
                await SendNotificationsAsync(entity, usersToExclude);
            });

            return(Task.FromResult(entity));
        }
Beispiel #6
0
        // -----------

        Task <TEntityReply> SendNotificationsAsync(
            TEntityReply reply,
            IList <int> usersToExclude)
        {
            if (reply == null)
            {
                throw new ArgumentNullException(nameof(reply));
            }

            // The reply always need an entity Id
            if (reply.EntityId <= 0)
            {
                throw new ArgumentNullException(nameof(reply.EntityId));
            }

            // No need to send notifications for hidden replies
            if (reply.IsHidden())
            {
                return(Task.FromResult(reply));
            }

            // Add deferred task
            _deferredTaskManager.AddTask(async context =>
            {
                // Follow type name
                var name = FollowTypes.Idea.Name;

                // Get follow sent state for reply
                var state = reply.GetOrCreate <FollowState>();

                // Have notifications already been sent for the reply?
                var follow = state.FollowsSent.FirstOrDefault(f =>
                                                              f.Equals(name, StringComparison.InvariantCultureIgnoreCase));
                if (follow != null)
                {
                    return;
                }

                // Get entity for reply
                var entity = await _entityStore.GetByIdAsync(reply.EntityId);

                // No need to send notifications if the entity is hidden
                if (entity.IsHidden())
                {
                    return;
                }

                // Get all follows for entity
                var follows = await _followStore.QueryAsync()
                              .Select <FollowQueryParams>(q =>
                {
                    q.ThingId.Equals(reply.EntityId);
                    q.Name.Equals(name);
                    if (usersToExclude.Count > 0)
                    {
                        q.CreatedUserId.IsNotIn(usersToExclude.ToArray());
                    }
                })
                              .ToList();

                // No follows simply return
                if (follows?.Data == null)
                {
                    return;
                }

                // Get users
                var users = await ReduceUsersAsync(follows?.Data, reply);

                // We always need users
                if (users == null)
                {
                    return;
                }

                // Send notifications
                foreach (var user in users)
                {
                    // Email notifications
                    if (user.NotificationEnabled(_userNotificationTypeDefaults, EmailNotifications.NewIdeaComment))
                    {
                        await _notificationManager.SendAsync(new Notification(EmailNotifications.NewIdeaComment)
                        {
                            To = user,
                        }, reply);
                    }

                    // Web notifications
                    if (user.NotificationEnabled(_userNotificationTypeDefaults, WebNotifications.NewIdeaComment))
                    {
                        await _notificationManager.SendAsync(new Notification(WebNotifications.NewIdeaComment)
                        {
                            To   = user,
                            From = new User()
                            {
                                Id          = reply.CreatedBy.Id,
                                UserName    = reply.CreatedBy.UserName,
                                DisplayName = reply.CreatedBy.DisplayName,
                                Alias       = reply.CreatedBy.Alias,
                                PhotoUrl    = reply.CreatedBy.PhotoUrl,
                                PhotoColor  = reply.CreatedBy.PhotoColor
                            }
                        }, reply);
                    }
                }

                // Update sent state
                state.AddSent(name);
                reply.AddOrUpdate(state);

                // Persist state
                await _entityReplyStore.UpdateAsync(reply);
            });

            return(Task.FromResult(reply));
        }
Beispiel #7
0
        Task <Doc> SendNotificationsAsync(Doc entity, IList <int> usersToExclude)
        {
            if (entity == null)
            {
                throw new ArgumentNullException(nameof(entity));
            }

            // Add deferred task
            _deferredTaskManager.AddTask(async context =>
            {
                // Follow type name
                var name = FollowTypes.Doc.Name;

                // Get all follows for entity
                var follows = await _followStore.QueryAsync()
                              .Select <FollowQueryParams>(q =>
                {
                    q.ThingId.Equals(entity.Id);
                    q.Name.Equals(name);
                    if (usersToExclude.Count > 0)
                    {
                        q.CreatedUserId.IsNotIn(usersToExclude.ToArray());
                    }
                })
                              .ToList();

                // No follows simply return
                if (follows?.Data == null)
                {
                    return;
                }

                // Get users
                var users = await ReduceUsersAsync(follows?.Data, entity);

                // We always need users
                if (users == null)
                {
                    return;
                }

                // Send notifications
                foreach (var user in users)
                {
                    // Email notifications
                    if (user.NotificationEnabled(_userNotificationTypeDefaults, EmailNotifications.UpdatedDoc))
                    {
                        await _notificationManager.SendAsync(new Notification(EmailNotifications.UpdatedDoc)
                        {
                            To = user,
                        }, entity);
                    }

                    // Web notifications
                    if (user.NotificationEnabled(_userNotificationTypeDefaults, WebNotifications.UpdatedDoc))
                    {
                        await _notificationManager.SendAsync(new Notification(WebNotifications.UpdatedDoc)
                        {
                            To   = user,
                            From = new User()
                            {
                                Id          = entity.ModifiedBy.Id,
                                UserName    = entity.ModifiedBy.UserName,
                                DisplayName = entity.ModifiedBy.DisplayName,
                                Alias       = entity.ModifiedBy.Alias,
                                PhotoUrl    = entity.ModifiedBy.PhotoUrl,
                                PhotoColor  = entity.ModifiedBy.PhotoColor
                            }
                        }, entity);
                    }
                }
            });

            return(Task.FromResult(entity));
        }