From 18288b5ea5d1d02b619df979d11aa56f375bd304 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 15 Aug 2023 11:05:21 +0300 Subject: [PATCH] Don't send notifications from batch sending if last message is old --- backfill.go | 21 ++++++++++++--------- commands.go | 2 +- portal.go | 5 +++-- provisioning.go | 2 +- user.go | 2 +- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/backfill.go b/backfill.go index 607749c..f7abe5b 100644 --- a/backfill.go +++ b/backfill.go @@ -32,7 +32,7 @@ import ( "go.mau.fi/mautrix-gmessages/database" ) -func (portal *Portal) initialForwardBackfill(user *User, markRead bool) { +func (portal *Portal) initialForwardBackfill(user *User, markRead, allowNotify bool) { // This is only called from CreateMatrixRoom which locks forwardBackfillLock defer portal.forwardBackfillLock.Unlock() log := portal.zlog.With(). @@ -40,7 +40,7 @@ func (portal *Portal) initialForwardBackfill(user *User, markRead bool) { Logger() ctx := log.WithContext(context.TODO()) - portal.forwardBackfill(ctx, user, time.Time{}, portal.bridge.Config.Bridge.Backfill.InitialLimit, markRead) + portal.forwardBackfill(ctx, user, time.Time{}, portal.bridge.Config.Bridge.Backfill.InitialLimit, markRead, allowNotify) } const recentBackfillDelay = 15 * time.Second @@ -111,7 +111,7 @@ func (portal *Portal) missedForwardBackfill(user *User, lastMessageTS time.Time, Str("latest_message_id", lastMessageID). Time("last_bridged_ts", portal.lastMessageTS). Msg("Backfilling missed messages") - portal.forwardBackfill(ctx, user, portal.lastMessageTS, portal.bridge.Config.Bridge.Backfill.MissedLimit, markRead) + portal.forwardBackfill(ctx, user, portal.lastMessageTS, portal.bridge.Config.Bridge.Backfill.MissedLimit, markRead, true) } func (portal *Portal) deterministicEventID(messageID string, part int) id.EventID { @@ -120,7 +120,7 @@ func (portal *Portal) deterministicEventID(messageID string, part int) id.EventI return id.EventID(fmt.Sprintf("$%s:messages.google.com", base64.RawURLEncoding.EncodeToString(sum[:]))) } -func (portal *Portal) forwardBackfill(ctx context.Context, user *User, after time.Time, limit int, markRead bool) bool { +func (portal *Portal) forwardBackfill(ctx context.Context, user *User, after time.Time, limit int, markRead, allowNotify bool) bool { if limit == 0 { return false } @@ -138,7 +138,7 @@ func (portal *Portal) forwardBackfill(ctx context.Context, user *User, after tim batchSending := portal.bridge.SpecVersions.Supports(mautrix.BeeperFeatureBatchSending) converted := make([]*ConvertedMessage, 0, len(resp.Messages)) - maxTS := portal.lastMessageTS + maxTS := time.Time{} for i := len(resp.Messages) - 1; i >= 0; i-- { evt := resp.Messages[i] isTooOld := !time.UnixMicro(evt.Timestamp).After(after) @@ -167,7 +167,8 @@ func (portal *Portal) forwardBackfill(ctx context.Context, user *User, after tim if markRead { markReadBy = user.MXID } - portal.backfillSendBatch(ctx, converted, markReadBy) + allowNotify = allowNotify && time.Since(maxTS) < 24*time.Hour + portal.backfillSendBatch(ctx, converted, markReadBy, allowNotify) } else { lastEventID := portal.backfillSendLegacy(ctx, converted) if markRead && user.DoublePuppetIntent != nil { @@ -177,11 +178,13 @@ func (portal *Portal) forwardBackfill(ctx context.Context, user *User, after tim } } } - portal.lastMessageTS = maxTS + if maxTS.After(portal.lastMessageTS) { + portal.lastMessageTS = maxTS + } return true } -func (portal *Portal) backfillSendBatch(ctx context.Context, converted []*ConvertedMessage, markReadBy id.UserID) { +func (portal *Portal) backfillSendBatch(ctx context.Context, converted []*ConvertedMessage, markReadBy id.UserID, allowNotify bool) { log := zerolog.Ctx(ctx) events := make([]*event.Event, 0, len(converted)) dbMessages := make([]*database.Message, 0, len(converted)) @@ -250,7 +253,7 @@ func (portal *Portal) backfillSendBatch(ctx context.Context, converted []*Conver _, err := portal.MainIntent().BeeperBatchSend(portal.MXID, &mautrix.ReqBeeperBatchSend{ Forward: forward, MarkReadBy: markReadBy, - SendNotification: forward && markReadBy == "", + SendNotification: forward && markReadBy == "" && allowNotify, Events: events, }) if err != nil { diff --git a/commands.go b/commands.go index dd2b2b7..19c4785 100644 --- a/commands.go +++ b/commands.go @@ -354,7 +354,7 @@ func fnPM(ce *WrappedCommandEvent) { ce.Reply("Failed to start chat: no conversation in response") } else if portal := ce.User.GetPortalByID(resp.Conversation.ConversationID); portal.MXID != "" { ce.Reply("Chat already exists at [%s](https://matrix.to/#/%s)", portal.MXID, portal.MXID) - } else if err = portal.CreateMatrixRoom(ce.User, resp.Conversation); err != nil { + } else if err = portal.CreateMatrixRoom(ce.User, resp.Conversation, false); err != nil { ce.ZLog.Err(err).Msg("Failed to create matrix room") ce.Reply("Failed to create portal room for conversation") } else { diff --git a/portal.go b/portal.go index b199014..632bff6 100644 --- a/portal.go +++ b/portal.go @@ -1278,7 +1278,7 @@ func (portal *Portal) GetEncryptionEventContent() (evt *event.EncryptionEventCon return } -func (portal *Portal) CreateMatrixRoom(user *User, conv *gmproto.Conversation) error { +func (portal *Portal) CreateMatrixRoom(user *User, conv *gmproto.Conversation, isFromSync bool) error { portal.roomCreateLock.Lock() defer portal.roomCreateLock.Unlock() if len(portal.MXID) > 0 { @@ -1418,7 +1418,8 @@ func (portal *Portal) CreateMatrixRoom(user *User, conv *gmproto.Conversation) e portal.ensureUserInvited(user) } user.syncChatDoublePuppetDetails(portal, conv, true) - go portal.initialForwardBackfill(user, !conv.GetUnread()) + allowNotify := !isFromSync + go portal.initialForwardBackfill(user, !conv.GetUnread(), allowNotify) go portal.addToPersonalSpace(user, true) return nil } diff --git a/provisioning.go b/provisioning.go index 0e5483c..2b069ef 100644 --- a/provisioning.go +++ b/provisioning.go @@ -242,7 +242,7 @@ func (prov *ProvisioningAPI) StartChat(w http.ResponseWriter, r *http.Request) { convCopy.LatestMessage = nil prov.zlog.Debug().Any("conversation_data", convCopy).Msg("Got conversation data for start chat") portal := user.GetPortalByID(resp.Conversation.ConversationID) - err = portal.CreateMatrixRoom(user, resp.Conversation) + err = portal.CreateMatrixRoom(user, resp.Conversation, false) if err != nil { prov.zlog.Err(err).Msg("Failed to create matrix room") jsonResponse(w, http.StatusInternalServerError, Error{ diff --git a/user.go b/user.go index 8005ed4..6ecae7a 100644 --- a/user.go +++ b/user.go @@ -828,7 +828,7 @@ func (user *User) syncConversation(v *gmproto.Conversation, source string) { return } log.Debug().Msg("Creating portal for conversation") - err := portal.CreateMatrixRoom(user, v) + err := portal.CreateMatrixRoom(user, v, source == "sync") if err != nil { log.Err(err).Msg("Error creating Matrix room from conversation event") }