mention notifications working

This commit is contained in:
tsmethurst 2021-05-27 15:44:00 +02:00
parent 6eaeaa4d18
commit 4d5c150f9f
8 changed files with 88 additions and 17 deletions

View File

@ -80,7 +80,7 @@ type Status struct {
*/
// Account that created this status
GTSAccount *Account `pg:"-"`
GTSAuthorAccount *Account `pg:"-"`
// Mentions created in this status
GTSMentions []*Mention `pg:"-"`
// Hashtags used in this status

View File

@ -112,9 +112,9 @@ func (p *processor) federateStatus(status *gtsmodel.Status) error {
return fmt.Errorf("federateStatus: error converting status to as format: %s", err)
}
outboxIRI, err := url.Parse(status.GTSAccount.OutboxURI)
outboxIRI, err := url.Parse(status.GTSAuthorAccount.OutboxURI)
if err != nil {
return fmt.Errorf("federateStatus: error parsing outboxURI %s: %s", status.GTSAccount.OutboxURI, err)
return fmt.Errorf("federateStatus: error parsing outboxURI %s: %s", status.GTSAuthorAccount.OutboxURI, err)
}
_, err = p.federator.FederatingActor().Send(context.Background(), outboxIRI, asStatus)

View File

@ -26,6 +26,69 @@ import (
)
func (p *processor) notifyStatus(status *gtsmodel.Status) error {
// if there are no mentions in this status then just bail
if len(status.Mentions) == 0 {
return nil
}
if status.GTSMentions == nil {
// there are mentions but they're not fully populated on the status yet so do this
menchies := []*gtsmodel.Mention{}
for _, m := range status.Mentions {
gtsm := &gtsmodel.Mention{}
if err := p.db.GetByID(m, gtsm); err != nil {
return fmt.Errorf("notifyStatus: error getting mention with id %s from the db: %s", m, err)
}
menchies = append(menchies, gtsm)
}
status.GTSMentions = menchies
}
// now we have mentions as full gtsmodel.Mention structs on the status we can continue
for _, m := range status.GTSMentions {
// make sure this is a local account, otherwise we don't need to create a notification for it
if m.GTSAccount == nil {
a := &gtsmodel.Account{}
if err := p.db.GetByID(m.TargetAccountID, a); err != nil {
// we don't have the account or there's been an error
return fmt.Errorf("notifyStatus: error getting account with id %s from the db: %s", m.TargetAccountID, err)
}
m.GTSAccount = a
}
if m.GTSAccount.Domain != "" {
// not a local account so skip it
continue
}
// make sure a notif doesn't already exist for this mention
err := p.db.GetWhere([]db.Where{
{Key: "notification_type", Value: gtsmodel.NotificationMention},
{Key: "target_account_id", Value: m.TargetAccountID},
{Key: "origin_account_id", Value: status.AccountID},
{Key: "status_id", Value: status.ID},
}, &gtsmodel.Notification{})
if err == nil {
// notification exists already so just continue
continue
}
if _, ok := err.(db.ErrNoEntries); !ok {
// there's a real error in the db
return fmt.Errorf("notifyStatus: error checking existence of notification for mention with id %s : %s", m.ID, err)
}
// if we've reached this point we know the mention is for a local account, and the notification doesn't exist, so create it
notif := &gtsmodel.Notification{
NotificationType: gtsmodel.NotificationMention,
TargetAccountID: m.TargetAccountID,
OriginAccountID: status.AccountID,
StatusID: status.ID,
}
if err := p.db.Put(notif); err != nil {
return fmt.Errorf("notifyStatus: error putting notification in database: %s", err)
}
}
return nil
}

View File

@ -249,8 +249,8 @@ func (p *processor) dereferenceStatusFields(status *gtsmodel.Status) error {
}
m.StatusID = status.ID
m.OriginAccountID = status.GTSAccount.ID
m.OriginAccountURI = status.GTSAccount.URI
m.OriginAccountID = status.GTSAuthorAccount.ID
m.OriginAccountURI = status.GTSAuthorAccount.URI
targetAccount := &gtsmodel.Account{}
if err := p.db.GetWhere([]db.Where{{Key: "uri", Value: uri.String()}}, targetAccount); err != nil {

View File

@ -226,7 +226,7 @@ func (c *converter) ASStatusToStatus(statusable Statusable) (*gtsmodel.Status, e
return nil, fmt.Errorf("couldn't get status owner from db: %s", err)
}
status.AccountID = statusOwner.ID
status.GTSAccount = statusOwner
status.GTSAuthorAccount = statusOwner
// check if there's a post that this is a reply to
inReplyToURI, err := extractInReplyToURI(statusable)

View File

@ -65,7 +65,7 @@ type TypeConverter interface {
// TagToMasto converts a gts model tag into its mastodon (frontend) representation for serialization on the API.
TagToMasto(t *gtsmodel.Tag) (model.Tag, error)
// StatusToMasto converts a gts model status into its mastodon (frontend) representation for serialization on the API.
StatusToMasto(s *gtsmodel.Status, targetAccount *gtsmodel.Account, requestingAccount *gtsmodel.Account, boostOfAccount *gtsmodel.Account, replyToAccount *gtsmodel.Account, reblogOfStatus *gtsmodel.Status) (*model.Status, error)
StatusToMasto(s *gtsmodel.Status, statusAuthor *gtsmodel.Account, requestingAccount *gtsmodel.Account, boostOfAccount *gtsmodel.Account, replyToAccount *gtsmodel.Account, reblogOfStatus *gtsmodel.Status) (*model.Status, error)
// VisToMasto converts a gts visibility into its mastodon equivalent
VisToMasto(m gtsmodel.Visibility) model.Visibility
// InstanceToMasto converts a gts instance into its mastodon equivalent for serving at /api/v1/instance

View File

@ -262,12 +262,12 @@ func (c *converter) StatusToAS(s *gtsmodel.Status) (vocab.ActivityStreamsNote, e
// check if author account is already attached to status and attach it if not
// if we can't retrieve this, bail here already because we can't attribute the status to anyone
if s.GTSAccount == nil {
if s.GTSAuthorAccount == nil {
a := &gtsmodel.Account{}
if err := c.db.GetByID(s.AccountID, a); err != nil {
return nil, fmt.Errorf("StatusToAS: error retrieving author account from db: %s", err)
}
s.GTSAccount = a
s.GTSAuthorAccount = a
}
// create the Note!
@ -328,9 +328,9 @@ func (c *converter) StatusToAS(s *gtsmodel.Status) (vocab.ActivityStreamsNote, e
}
// attributedTo
authorAccountURI, err := url.Parse(s.GTSAccount.URI)
authorAccountURI, err := url.Parse(s.GTSAuthorAccount.URI)
if err != nil {
return nil, fmt.Errorf("StatusToAS: error parsing url %s: %s", s.GTSAccount.URI, err)
return nil, fmt.Errorf("StatusToAS: error parsing url %s: %s", s.GTSAuthorAccount.URI, err)
}
attributedToProp := streams.NewActivityStreamsAttributedToProperty()
attributedToProp.AppendIRI(authorAccountURI)
@ -357,9 +357,9 @@ func (c *converter) StatusToAS(s *gtsmodel.Status) (vocab.ActivityStreamsNote, e
status.SetActivityStreamsTag(tagProp)
// parse out some URIs we need here
authorFollowersURI, err := url.Parse(s.GTSAccount.FollowersURI)
authorFollowersURI, err := url.Parse(s.GTSAuthorAccount.FollowersURI)
if err != nil {
return nil, fmt.Errorf("StatusToAS: error parsing url %s: %s", s.GTSAccount.FollowersURI, err)
return nil, fmt.Errorf("StatusToAS: error parsing url %s: %s", s.GTSAuthorAccount.FollowersURI, err)
}
publicURI, err := url.Parse(asPublicURI)

View File

@ -270,7 +270,7 @@ func (c *converter) TagToMasto(t *gtsmodel.Tag) (model.Tag, error) {
func (c *converter) StatusToMasto(
s *gtsmodel.Status,
targetAccount *gtsmodel.Account,
statusAuthor *gtsmodel.Account,
requestingAccount *gtsmodel.Account,
boostOfAccount *gtsmodel.Account,
replyToAccount *gtsmodel.Account,
@ -382,7 +382,7 @@ func (c *converter) StatusToMasto(
}
}
mastoTargetAccount, err := c.AccountToMastoPublic(targetAccount)
mastoAuthorAccount, err := c.AccountToMastoPublic(statusAuthor)
if err != nil {
return nil, fmt.Errorf("error parsing account of status author: %s", err)
}
@ -520,7 +520,7 @@ func (c *converter) StatusToMasto(
Content: s.Content,
Reblog: mastoRebloggedStatus,
Application: mastoApplication,
Account: mastoTargetAccount,
Account: mastoAuthorAccount,
MediaAttachments: mastoAttachments,
Mentions: mastoMentions,
Tags: mastoTags,
@ -639,8 +639,16 @@ func (c *converter) NotificationToMasto(n *gtsmodel.Notification) (*model.Notifi
replyToAccount = r
}
if n.GTSStatus.GTSAuthorAccount == nil {
if n.GTSStatus.AccountID == n.GTSTargetAccount.ID {
n.GTSStatus.GTSAuthorAccount = n.GTSTargetAccount
} else if n.GTSStatus.AccountID == n.GTSOriginAccount.ID {
n.GTSStatus.GTSAuthorAccount = n.GTSOriginAccount
}
}
var err error
mastoStatus, err = c.StatusToMasto(n.GTSStatus, n.GTSTargetAccount, n.GTSTargetAccount, nil, replyToAccount, nil)
mastoStatus, err = c.StatusToMasto(n.GTSStatus, n.GTSStatus.GTSAuthorAccount, n.GTSTargetAccount, nil, replyToAccount, nil)
if err != nil {
return nil, fmt.Errorf("NotificationToMasto: error converting status to masto: %s", err)
}