Эх сурвалжийг харах

Handle link preview and gif embeds appearing as edits

Tulir Asokan 2 жил өмнө
parent
commit
68b82c4d1b
3 өөрчлөгдсөн 42 нэмэгдсэн , 9 устгасан
  1. 1 1
      go.mod
  2. 2 2
      go.sum
  3. 39 6
      portal.go

+ 1 - 1
go.mod

@@ -13,7 +13,7 @@ require (
 	github.com/stretchr/testify v1.8.1
 	github.com/yuin/goldmark v1.5.3
 	maunium.net/go/maulogger/v2 v2.3.2
-	maunium.net/go/mautrix v0.13.1-0.20230127212324-870a2cfb9406
+	maunium.net/go/mautrix v0.13.1-0.20230128124647-7d98a9f8e3a6
 )
 
 require (

+ 2 - 2
go.sum

@@ -75,5 +75,5 @@ maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M=
 maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA=
 maunium.net/go/maulogger/v2 v2.3.2 h1:1XmIYmMd3PoQfp9J+PaHhpt80zpfmMqaShzUTC7FwY0=
 maunium.net/go/maulogger/v2 v2.3.2/go.mod h1:TYWy7wKwz/tIXTpsx8G3mZseIRiC5DoMxSZazOHy68A=
-maunium.net/go/mautrix v0.13.1-0.20230127212324-870a2cfb9406 h1:b3RgrN/RYTW643k+DJfeaonTiOTK+Pxfg2sTEGzpFow=
-maunium.net/go/mautrix v0.13.1-0.20230127212324-870a2cfb9406/go.mod h1:gYMQPsZ9lQpyKlVp+DGwOuc9LIcE/c8GZW2CvKHISgM=
+maunium.net/go/mautrix v0.13.1-0.20230128124647-7d98a9f8e3a6 h1:c2HKxT3wYxWS213BXaWDY3UkHGfXGmhzOv4h1OKZm20=
+maunium.net/go/mautrix v0.13.1-0.20230128124647-7d98a9f8e3a6/go.mod h1:gYMQPsZ9lQpyKlVp+DGwOuc9LIcE/c8GZW2CvKHISgM=

+ 39 - 6
portal.go

@@ -14,6 +14,7 @@ import (
 	"maunium.net/go/mautrix/bridge/status"
 	"maunium.net/go/mautrix/crypto/attachment"
 	"maunium.net/go/mautrix/format"
+	"maunium.net/go/mautrix/util"
 	"maunium.net/go/mautrix/util/variationselector"
 
 	"github.com/bwmarrin/discordgo"
@@ -58,10 +59,14 @@ type Portal struct {
 	discordMessages chan portalDiscordMessage
 	matrixMessages  chan portalMatrixMessage
 
+	recentMessages *util.RingBuffer[string, *discordgo.Message]
+
 	currentlyTyping     []id.UserID
 	currentlyTypingLock sync.Mutex
 }
 
+const recentMessageBufferSize = 32
+
 var _ bridge.Portal = (*Portal)(nil)
 var _ bridge.ReadReceiptHandlingPortal = (*Portal)(nil)
 var _ bridge.MembershipHandlingPortal = (*Portal)(nil)
@@ -226,6 +231,8 @@ func (br *DiscordBridge) NewPortal(dbPortal *database.Portal) *Portal {
 
 		discordMessages: make(chan portalDiscordMessage, br.Config.Bridge.PortalMessageBuffer),
 		matrixMessages:  make(chan portalMatrixMessage, br.Config.Bridge.PortalMessageBuffer),
+
+		recentMessages: util.NewRingBuffer[string, *discordgo.Message](recentMessageBufferSize),
 	}
 
 	go portal.messageLoop()
@@ -931,6 +938,8 @@ func (portal *Portal) handleDiscordMessageCreate(user *User, msg *discordgo.Mess
 		return
 	}
 
+	portal.recentMessages.Push(msg.ID, msg)
+
 	// Handle normal message
 	existing := portal.bridge.DB.Message.GetByDiscordID(portal.Key, msg.ID)
 	if existing != nil {
@@ -1085,12 +1094,25 @@ func (portal *Portal) handleDiscordMessageUpdate(user *User, msg *discordgo.Mess
 	}
 
 	if msg.Author == nil {
-		if len(msg.Embeds) > 0 {
-			portal.log.Debugln("ignoring update for opengraph attachment")
-
+		creationMessage, ok := portal.recentMessages.Get(msg.ID)
+		if !ok {
+			portal.log.Debugfln("Dropping edit with no author of non-recent message %s", msg.ID)
 			return
 		}
-		return
+		portal.log.Debugfln("Found original message %s in cache for edit without author", msg.ID)
+		if len(msg.Embeds) > 0 {
+			creationMessage.Embeds = msg.Embeds
+		}
+		if len(msg.Attachments) > 0 {
+			creationMessage.Attachments = msg.Attachments
+		}
+		if len(msg.Components) > 0 {
+			creationMessage.Components = msg.Components
+		}
+		// TODO are there other fields that need copying?
+		msg = creationMessage
+	} else {
+		portal.recentMessages.Replace(msg.ID, msg)
 	}
 
 	intent := portal.bridge.GetPuppetByID(msg.Author.ID).IntentFor(portal)
@@ -1123,7 +1145,18 @@ func (portal *Portal) handleDiscordMessageUpdate(user *User, msg *discordgo.Mess
 		portal.log.Debugfln("Dropping non-text edit to %s (message on matrix: %t, text on discord: %t)", msg.ID, existing[0].AttachmentID == "", len(msg.Content) > 0)
 		return
 	}
-	content := portal.renderDiscordMarkdown(msg.Content)
+	var content event.MessageEventContent
+	var extraContent map[string]any
+	if isPlainGifMessage(msg) {
+		converted := portal.convertDiscordVideoEmbed(intent, msg.Embeds[0])
+		content = *converted.Content
+		extraContent = converted.Extra
+	} else {
+		content = portal.renderDiscordMarkdown(msg.Content)
+		extraContent = map[string]any{
+			"com.beeper.linkpreviews": portal.convertDiscordLinkEmbedsToBeeper(intent, msg.Embeds),
+		}
+	}
 	content.SetEdit(existing[0].MXID)
 
 	var editTS int64
@@ -1131,7 +1164,7 @@ func (portal *Portal) handleDiscordMessageUpdate(user *User, msg *discordgo.Mess
 		editTS = msg.EditedTimestamp.UnixMilli()
 	}
 	// TODO figure out some way to deduplicate outgoing edits
-	resp, err := portal.sendMatrixMessage(intent, event.EventMessage, &content, nil, editTS)
+	resp, err := portal.sendMatrixMessage(intent, event.EventMessage, &content, extraContent, editTS)
 	if err != nil {
 		portal.log.Warnfln("Failed to send message %s to matrix: %v", msg.ID, err)
 		return