summaryrefslogtreecommitdiff
path: root/internal/processing/workers/surfacenotify.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/processing/workers/surfacenotify.go')
-rw-r--r--internal/processing/workers/surfacenotify.go234
1 files changed, 175 insertions, 59 deletions
diff --git a/internal/processing/workers/surfacenotify.go b/internal/processing/workers/surfacenotify.go
index b99fa3ad3..2dc60023c 100644
--- a/internal/processing/workers/surfacenotify.go
+++ b/internal/processing/workers/surfacenotify.go
@@ -35,12 +35,25 @@ func (s *surface) notifyMentions(
ctx context.Context,
status *gtsmodel.Status,
) error {
- var (
- mentions = status.Mentions
- errs = gtserror.NewMultiError(len(mentions))
- )
+ var errs gtserror.MultiError
+
+ for _, mention := range status.Mentions {
+ // Set status on the mention (stops
+ // the below function populating it).
+ mention.Status = status
+
+ // Beforehand, ensure the passed mention is fully populated.
+ if err := s.state.DB.PopulateMention(ctx, mention); err != nil {
+ errs.Appendf("error populating mention %s: %w", mention.ID, err)
+ continue
+ }
+
+ if mention.TargetAccount.IsRemote() {
+ // no need to notify
+ // remote accounts.
+ continue
+ }
- for _, mention := range mentions {
// Ensure thread not muted
// by mentioned account.
muted, err := s.state.DB.IsThreadMutedByAccount(
@@ -48,9 +61,8 @@ func (s *surface) notifyMentions(
status.ThreadID,
mention.TargetAccountID,
)
-
if err != nil {
- errs.Append(err)
+ errs.Appendf("error checking status thread mute %s: %w", status.ThreadID, err)
continue
}
@@ -61,14 +73,16 @@ func (s *surface) notifyMentions(
continue
}
- if err := s.notify(
- ctx,
+ // notify mentioned
+ // by status author.
+ if err := s.notify(ctx,
gtsmodel.NotificationMention,
- mention.TargetAccountID,
- mention.OriginAccountID,
+ mention.TargetAccount,
+ mention.OriginAccount,
mention.StatusID,
); err != nil {
- errs.Append(err)
+ errs.Appendf("error notifying mention target %s: %w", mention.TargetAccountID, err)
+ continue
}
}
@@ -79,15 +93,30 @@ func (s *surface) notifyMentions(
// follow request that they have a new follow request.
func (s *surface) notifyFollowRequest(
ctx context.Context,
- followRequest *gtsmodel.FollowRequest,
+ followReq *gtsmodel.FollowRequest,
) error {
- return s.notify(
- ctx,
+ // Beforehand, ensure the passed follow request is fully populated.
+ if err := s.state.DB.PopulateFollowRequest(ctx, followReq); err != nil {
+ return gtserror.Newf("error populating follow request %s: %w", followReq.ID, err)
+ }
+
+ if followReq.TargetAccount.IsRemote() {
+ // no need to notify
+ // remote accounts.
+ return nil
+ }
+
+ // Now notify the follow request itself.
+ if err := s.notify(ctx,
gtsmodel.NotificationFollowRequest,
- followRequest.TargetAccountID,
- followRequest.AccountID,
+ followReq.TargetAccount,
+ followReq.Account,
"",
- )
+ ); err != nil {
+ return gtserror.Newf("error notifying follow target %s: %w", followReq.TargetAccountID, err)
+ }
+
+ return nil
}
// notifyFollow notifies the target of the given follow that
@@ -98,6 +127,17 @@ func (s *surface) notifyFollow(
ctx context.Context,
follow *gtsmodel.Follow,
) error {
+ // Beforehand, ensure the passed follow is fully populated.
+ if err := s.state.DB.PopulateFollow(ctx, follow); err != nil {
+ return gtserror.Newf("error populating follow %s: %w", follow.ID, err)
+ }
+
+ if follow.TargetAccount.IsRemote() {
+ // no need to notify
+ // remote accounts.
+ return nil
+ }
+
// Check if previous follow req notif exists.
prevNotif, err := s.state.DB.GetNotification(
gtscontext.SetBarebones(ctx),
@@ -107,24 +147,28 @@ func (s *surface) notifyFollow(
"",
)
if err != nil && !errors.Is(err, db.ErrNoEntries) {
- return gtserror.Newf("db error checking for previous follow request notification: %w", err)
+ return gtserror.Newf("error getting notification: %w", err)
}
if prevNotif != nil {
- // Previous notif existed, delete it.
- if err := s.state.DB.DeleteNotificationByID(ctx, prevNotif.ID); err != nil {
- return gtserror.Newf("db error removing previous follow request notification %s: %w", prevNotif.ID, err)
+ // Previous follow request notif existed, delete it before creating new.
+ if err := s.state.DB.DeleteNotificationByID(ctx, prevNotif.ID); // nocollapse
+ err != nil && !errors.Is(err, db.ErrNoEntries) {
+ return gtserror.Newf("error deleting notification %s: %w", prevNotif.ID, err)
}
}
// Now notify the follow itself.
- return s.notify(
- ctx,
+ if err := s.notify(ctx,
gtsmodel.NotificationFollow,
- follow.TargetAccountID,
- follow.AccountID,
+ follow.TargetAccount,
+ follow.Account,
"",
- )
+ ); err != nil {
+ return gtserror.Newf("error notifying follow target %s: %w", follow.TargetAccountID, err)
+ }
+
+ return nil
}
// notifyFave notifies the target of the given
@@ -138,6 +182,17 @@ func (s *surface) notifyFave(
return nil
}
+ // Beforehand, ensure the passed status fave is fully populated.
+ if err := s.state.DB.PopulateStatusFave(ctx, fave); err != nil {
+ return gtserror.Newf("error populating fave %s: %w", fave.ID, err)
+ }
+
+ if fave.TargetAccount.IsRemote() {
+ // no need to notify
+ // remote accounts.
+ return nil
+ }
+
// Ensure favee hasn't
// muted the thread.
muted, err := s.state.DB.IsThreadMutedByAccount(
@@ -145,24 +200,28 @@ func (s *surface) notifyFave(
fave.Status.ThreadID,
fave.TargetAccountID,
)
-
if err != nil {
- return err
+ return gtserror.Newf("error checking status thread mute %s: %w", fave.StatusID, err)
}
if muted {
- // Boostee doesn't want
+ // Favee doesn't want
// notifs for this thread.
return nil
}
- return s.notify(
- ctx,
+ // notify status author
+ // of fave by account.
+ if err := s.notify(ctx,
gtsmodel.NotificationFave,
- fave.TargetAccountID,
- fave.AccountID,
+ fave.TargetAccount,
+ fave.Account,
fave.StatusID,
- )
+ ); err != nil {
+ return gtserror.Newf("error notifying status author %s: %w", fave.TargetAccountID, err)
+ }
+
+ return nil
}
// notifyAnnounce notifies the status boost target
@@ -176,14 +235,19 @@ func (s *surface) notifyAnnounce(
return nil
}
- if status.BoostOf == nil {
- // No boosted status
- // set, nothing to do.
+ if status.BoostOfAccountID == status.AccountID {
+ // Self-boost, nothing to do.
return nil
}
- if status.BoostOfAccountID == status.AccountID {
- // Self-boost, nothing to do.
+ // Beforehand, ensure the passed status is fully populated.
+ if err := s.state.DB.PopulateStatus(ctx, status); err != nil {
+ return gtserror.Newf("error populating status %s: %w", status.ID, err)
+ }
+
+ if status.BoostOfAccount.IsRemote() {
+ // no need to notify
+ // remote accounts.
return nil
}
@@ -196,7 +260,7 @@ func (s *surface) notifyAnnounce(
)
if err != nil {
- return err
+ return gtserror.Newf("error checking status thread mute %s: %w", status.BoostOfID, err)
}
if muted {
@@ -205,13 +269,68 @@ func (s *surface) notifyAnnounce(
return nil
}
- return s.notify(
- ctx,
+ // notify status author
+ // of boost by account.
+ if err := s.notify(ctx,
gtsmodel.NotificationReblog,
- status.BoostOfAccountID,
- status.AccountID,
+ status.BoostOfAccount,
+ status.Account,
status.ID,
- )
+ ); err != nil {
+ return gtserror.Newf("error notifying status author %s: %w", status.BoostOfAccountID, err)
+ }
+
+ return nil
+}
+
+func (s *surface) notifyPollClose(ctx context.Context, status *gtsmodel.Status) error {
+ // Beforehand, ensure the passed status is fully populated.
+ if err := s.state.DB.PopulateStatus(ctx, status); err != nil {
+ return gtserror.Newf("error populating status %s: %w", status.ID, err)
+ }
+
+ // Fetch all votes in the attached status poll.
+ votes, err := s.state.DB.GetPollVotes(ctx, status.PollID)
+ if err != nil {
+ return gtserror.Newf("error getting poll %s votes: %w", status.PollID, err)
+ }
+
+ var errs gtserror.MultiError
+
+ if status.Account.IsLocal() {
+ // Send a notification to the status
+ // author that their poll has closed!
+ if err := s.notify(ctx,
+ gtsmodel.NotificationPoll,
+ status.Account,
+ status.Account,
+ status.ID,
+ ); err != nil {
+ errs.Appendf("error notifying poll author: %w", err)
+ }
+ }
+
+ for _, vote := range votes {
+ if vote.Account.IsRemote() {
+ // no need to notify
+ // remote accounts.
+ continue
+ }
+
+ // notify voter that
+ // poll has been closed.
+ if err := s.notify(ctx,
+ gtsmodel.NotificationMention,
+ vote.Account,
+ status.Account,
+ status.ID,
+ ); err != nil {
+ errs.Appendf("error notifying poll voter %s: %w", vote.AccountID, err)
+ continue
+ }
+ }
+
+ return errs.Combine()
}
// notify creates, inserts, and streams a new
@@ -228,17 +347,12 @@ func (s *surface) notifyAnnounce(
func (s *surface) notify(
ctx context.Context,
notificationType gtsmodel.NotificationType,
- targetAccountID string,
- originAccountID string,
+ targetAccount *gtsmodel.Account,
+ originAccount *gtsmodel.Account,
statusID string,
) error {
- targetAccount, err := s.state.DB.GetAccountByID(ctx, targetAccountID)
- if err != nil {
- return gtserror.Newf("error getting target account %s: %w", targetAccountID, err)
- }
-
- if !targetAccount.IsLocal() {
- // Nothing to do.
+ if targetAccount.IsRemote() {
+ // nothing to do.
return nil
}
@@ -247,8 +361,8 @@ func (s *surface) notify(
if _, err := s.state.DB.GetNotification(
gtscontext.SetBarebones(ctx),
notificationType,
- targetAccountID,
- originAccountID,
+ targetAccount.ID,
+ originAccount.ID,
statusID,
); err == nil {
// Notification exists;
@@ -264,8 +378,10 @@ func (s *surface) notify(
notif := &gtsmodel.Notification{
ID: id.NewULID(),
NotificationType: notificationType,
- TargetAccountID: targetAccountID,
- OriginAccountID: originAccountID,
+ TargetAccountID: targetAccount.ID,
+ TargetAccount: targetAccount,
+ OriginAccountID: originAccount.ID,
+ OriginAccount: originAccount,
StatusID: statusID,
}