From 7e25e2c2da8dbcb1223ef812e2b95e3971c01fe0 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 16 Oct 2023 13:07:06 +0300 Subject: [PATCH] Fix legacy backfill not checking if conversations have messages Fixes #631 --- CHANGELOG.md | 1 + database/historysync.go | 13 +++++++++++++ historysync.go | 19 ++++++++++--------- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bc2951..de5616f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ * Added basic support for channels. * Added default mime type for outgoing attachments when the origin Matrix client forgets to specify the mime type. +* Fixed legacy backfill creating portals for chats without messages. * Updated libwebp version used for encoding. # v0.10.2 (security update) diff --git a/database/historysync.go b/database/historysync.go index 2f88139..d896bbc 100644 --- a/database/historysync.go +++ b/database/historysync.go @@ -322,6 +322,19 @@ func (hsq *HistorySyncQuery) DeleteAllMessagesForPortal(userID id.UserID, portal } } +func (hsq *HistorySyncQuery) ConversationHasMessages(userID id.UserID, portalKey PortalKey) (exists bool) { + err := hsq.db.QueryRow(` + SELECT EXISTS( + SELECT 1 FROM history_sync_message + WHERE user_mxid=$1 AND conversation_id=$2 + ) + `, userID, portalKey.JID).Scan(&exists) + if err != nil { + hsq.log.Warnfln("Failed to check if any messages are stored for %s/%s: %v", userID, portalKey.JID, err) + } + return +} + func (hsq *HistorySyncQuery) DeleteConversation(userID id.UserID, jid string) { // This will also clear history_sync_message as there's a foreign key constraint _, err := hsq.db.Exec(` diff --git a/historysync.go b/historysync.go index 578629d..bd16077 100644 --- a/historysync.go +++ b/historysync.go @@ -20,6 +20,7 @@ import ( "crypto/sha256" "encoding/base64" "fmt" + "strings" "time" "github.com/rs/zerolog" @@ -138,8 +139,9 @@ func (user *User) backfillAll() { Int("conversation_count", len(conversations)). Msg("Probably received all history sync blobs, now backfilling conversations") limit := user.bridge.Config.Bridge.HistorySync.MaxInitialConversations + bridgedCount := 0 // Find the portals for all the conversations. - for i, conv := range conversations { + for _, conv := range conversations { jid, err := types.ParseJID(conv.ConversationID) if err != nil { user.zlog.Warn().Err(err). @@ -153,7 +155,12 @@ func (user *User) backfillAll() { Str("portal_jid", portal.Key.JID.String()). Msg("Chat already has a room, deleting messages from database") user.bridge.DB.HistorySync.DeleteConversation(user.MXID, portal.Key.JID.String()) - } else if limit < 0 || i < limit { + bridgedCount++ + } else if !user.bridge.DB.HistorySync.ConversationHasMessages(user.MXID, portal.Key) { + user.zlog.Debug().Str("portal_jid", portal.Key.JID.String()).Msg("Skipping chat with no messages in history sync") + user.bridge.DB.HistorySync.DeleteConversation(user.MXID, portal.Key.JID.String()) + } else if limit < 0 || bridgedCount < limit { + bridgedCount++ err = portal.CreateMatrixRoom(user, nil, nil, true, true) if err != nil { user.zlog.Err(err).Msg("Failed to create Matrix room for backfill") @@ -491,13 +498,7 @@ func (user *User) storeHistorySync(evt *waProto.HistorySync) { } msgType := getMessageType(msgEvt.Message) - if msgType == "unknown" || msgType == "ignore" || msgType == "unknown_protocol" { - unsupportedTypes++ - continue - } - - // Don't store unsupported messages. - if !containsSupportedMessage(msgEvt.Message) { + if msgType == "unknown" || msgType == "ignore" || strings.HasPrefix(msgType, "unknown_protocol_") || !containsSupportedMessage(msgEvt.Message) { unsupportedTypes++ continue }