Browse Source

Bridge incoming reply embeds as replies

Tulir Asokan 2 years ago
parent
commit
102b1510f8
3 changed files with 24 additions and 4 deletions
  1. 1 1
      backfill.go
  2. 20 3
      portal.go
  3. 3 0
      portal_convert.go

+ 1 - 1
backfill.go

@@ -217,7 +217,7 @@ func (portal *Portal) convertMessageBatch(log zerolog.Logger, source *User, mess
 		puppet := portal.bridge.GetPuppetByID(msg.Author.ID)
 		puppet.UpdateInfo(source, msg.Author)
 		intent := puppet.IntentFor(portal)
-		replyTo := portal.getReplyTarget(source, msg.MessageReference, true)
+		replyTo := portal.getReplyTarget(source, "", msg.MessageReference, msg.Embeds, true)
 
 		ts, _ := discordgo.SnowflakeTimestamp(msg.ID)
 		log := log.With().

+ 20 - 3
portal.go

@@ -8,6 +8,7 @@ import (
 	"fmt"
 	"net/http"
 	"reflect"
+	"regexp"
 	"strconv"
 	"strings"
 	"sync"
@@ -637,7 +638,7 @@ func (portal *Portal) handleDiscordMessageCreate(user *User, msg *discordgo.Mess
 			lastThreadEvent = lastInThread.MXID
 		}
 	}
-	replyTo := portal.getReplyTarget(user, msg.MessageReference, false)
+	replyTo := portal.getReplyTarget(user, discordThreadID, msg.MessageReference, msg.Embeds, false)
 
 	ts, _ := discordgo.SnowflakeTimestamp(msg.ID)
 	parts := portal.convertDiscordMessage(ctx, intent, msg)
@@ -677,7 +678,23 @@ func (portal *Portal) handleDiscordMessageCreate(user *User, msg *discordgo.Mess
 	}
 }
 
-func (portal *Portal) getReplyTarget(source *User, ref *discordgo.MessageReference, allowNonExistent bool) *event.InReplyTo {
+var hackyReplyPattern = regexp.MustCompile(`^\*\*\[Replying to]\(https://discord.com/channels/(\d+)/(\d+)/(\d+)\)`)
+
+func isReplyEmbed(embed *discordgo.MessageEmbed) bool {
+	return hackyReplyPattern.MatchString(embed.Description)
+}
+
+func (portal *Portal) getReplyTarget(source *User, threadID string, ref *discordgo.MessageReference, embeds []*discordgo.MessageEmbed, allowNonExistent bool) *event.InReplyTo {
+	if ref == nil && len(embeds) > 0 {
+		match := hackyReplyPattern.FindStringSubmatch(embeds[0].Description)
+		if match != nil && match[1] == portal.GuildID && (match[2] == portal.Key.ChannelID || match[2] == threadID) {
+			ref = &discordgo.MessageReference{
+				MessageID: match[3],
+				ChannelID: match[2],
+				GuildID:   match[1],
+			}
+		}
+	}
 	if ref == nil {
 		return nil
 	}
@@ -689,7 +706,7 @@ func (portal *Portal) getReplyTarget(source *User, ref *discordgo.MessageReferen
 	crossRoomReplies := isHungry
 
 	targetPortal := portal
-	if ref.ChannelID != portal.Key.ChannelID && crossRoomReplies {
+	if ref.ChannelID != portal.Key.ChannelID && ref.ChannelID != threadID && crossRoomReplies {
 		targetPortal = portal.bridge.GetExistingPortalByID(database.PortalKey{ChannelID: ref.ChannelID, Receiver: source.DiscordID})
 		if targetPortal == nil {
 			return nil

+ 3 - 0
portal_convert.go

@@ -542,6 +542,9 @@ func (portal *Portal) convertDiscordTextMessage(ctx context.Context, intent *app
 	}
 	previews := make([]*BeeperLinkPreview, 0)
 	for i, embed := range msg.Embeds {
+		if i == 0 && msg.MessageReference == nil && isReplyEmbed(embed) {
+			continue
+		}
 		with := log.With().
 			Str("embed_type", string(embed.Type)).
 			Int("embed_index", i)