[feature] Notify accounts when a status they've interacted with has been edited (#4157)

This pull request adds sending notifications to local accounts that have interacted with a status, if we receive or create a new edit for that status.

closes https://codeberg.org/superseriousbusiness/gotosocial/issues/3991
Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4157
Co-authored-by: tobi <tobi.smethurst@protonmail.com>
Co-committed-by: tobi <tobi.smethurst@protonmail.com>
This commit is contained in:
tobi
2025-05-11 13:38:13 +00:00
committed by kim
parent 6b6946f42a
commit 8480a75808
19 changed files with 375 additions and 81 deletions

View File

@ -2055,60 +2055,43 @@ func (c *Converter) NotificationToAPINotification(
filters []*gtsmodel.Filter,
mutes *usermute.CompiledUserMuteList,
) (*apimodel.Notification, error) {
if n.TargetAccount == nil {
tAccount, err := c.state.DB.GetAccountByID(ctx, n.TargetAccountID)
if err != nil {
return nil, fmt.Errorf("NotificationToapi: error getting target account with id %s from the db: %s", n.TargetAccountID, err)
}
n.TargetAccount = tAccount
}
if n.OriginAccount == nil {
ogAccount, err := c.state.DB.GetAccountByID(ctx, n.OriginAccountID)
if err != nil {
return nil, fmt.Errorf("NotificationToapi: error getting origin account with id %s from the db: %s", n.OriginAccountID, err)
}
n.OriginAccount = ogAccount
// Ensure notif populated.
if err := c.state.DB.PopulateNotification(ctx, n); err != nil {
return nil, gtserror.Newf("error populating notification: %w", err)
}
// Get account that triggered this notif.
apiAccount, err := c.AccountToAPIAccountPublic(ctx, n.OriginAccount)
if err != nil {
return nil, fmt.Errorf("NotificationToapi: error converting account to api: %s", err)
return nil, gtserror.Newf("error converting account to api: %w", err)
}
// Get status that triggered this notif, if set.
var apiStatus *apimodel.Status
if n.StatusID != "" {
if n.Status == nil {
status, err := c.state.DB.GetStatusByID(ctx, n.StatusID)
if err != nil {
return nil, fmt.Errorf("NotificationToapi: error getting status with id %s from the db: %s", n.StatusID, err)
}
n.Status = status
if n.Status != nil {
apiStatus, err = c.StatusToAPIStatus(
ctx, n.Status,
n.TargetAccount,
statusfilter.FilterContextNotifications,
filters, mutes,
)
if err != nil && !errors.Is(err, statusfilter.ErrHideStatus) {
return nil, gtserror.Newf("error converting status to api: %w", err)
}
if n.Status.Account == nil {
if n.Status.AccountID == n.TargetAccount.ID {
n.Status.Account = n.TargetAccount
} else if n.Status.AccountID == n.OriginAccount.ID {
n.Status.Account = n.OriginAccount
}
if apiStatus == nil {
// Notif filtered for this
// status, nothing to do.
return nil, err
}
var err error
apiStatus, err = c.StatusToAPIStatus(ctx, n.Status, n.TargetAccount, statusfilter.FilterContextNotifications, filters, mutes)
if err != nil {
if errors.Is(err, statusfilter.ErrHideStatus) {
return nil, err
}
return nil, fmt.Errorf("NotificationToapi: error converting status to api: %s", err)
if apiStatus.Reblog != nil {
// Use the actual reblog status
// for the notifications endpoint.
apiStatus = apiStatus.Reblog.Status
}
}
if apiStatus != nil && apiStatus.Reblog != nil {
// use the actual reblog status for the notifications endpoint
apiStatus = apiStatus.Reblog.Status
}
return &apimodel.Notification{
ID: n.ID,
Type: n.NotificationType.String(),