Add support for disabling link previews via MSC4095
This commit is contained in:
14
formatter.go
14
formatter.go
@@ -98,6 +98,7 @@ func (portal *Portal) renderDiscordMarkdownOnlyHTML(text string, allowInlineLink
|
||||
const formatterContextPortalKey = "fi.mau.discord.portal"
|
||||
const formatterContextAllowedMentionsKey = "fi.mau.discord.allowed_mentions"
|
||||
const formatterContextInputAllowedMentionsKey = "fi.mau.discord.input_allowed_mentions"
|
||||
const formatterContextInputAllowedLinkPreviewsKey = "fi.mau.discord.input_allowed_link_previews"
|
||||
|
||||
func appendIfNotContains(arr []string, newItem string) []string {
|
||||
for _, item := range arr {
|
||||
@@ -221,16 +222,24 @@ var matrixHTMLParser = &format.HTMLParser{
|
||||
return fmt.Sprintf("||%s||", text)
|
||||
},
|
||||
LinkConverter: func(text, href string, ctx format.Context) string {
|
||||
linkPreviews := ctx.ReturnData[formatterContextInputAllowedLinkPreviewsKey].([]string)
|
||||
allowPreview := linkPreviews == nil || slices.Contains(linkPreviews, href)
|
||||
if text == href {
|
||||
if !allowPreview {
|
||||
return fmt.Sprintf("<%s>", text)
|
||||
}
|
||||
return text
|
||||
} else if !discordLinkRegexFull.MatchString(href) {
|
||||
return fmt.Sprintf("%s (%s)", escapeDiscordMarkdown(text), escapeDiscordMarkdown(href))
|
||||
}
|
||||
} else if !allowPreview {
|
||||
return fmt.Sprintf("[%s](<%s>)", escapeDiscordMarkdown(text), href)
|
||||
} else {
|
||||
return fmt.Sprintf("[%s](%s)", escapeDiscordMarkdown(text), href)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func (portal *Portal) parseMatrixHTML(content *event.MessageEventContent) (string, *discordgo.MessageAllowedMentions) {
|
||||
func (portal *Portal) parseMatrixHTML(content *event.MessageEventContent, allowedLinkPreviews []string) (string, *discordgo.MessageAllowedMentions) {
|
||||
allowedMentions := &discordgo.MessageAllowedMentions{
|
||||
Parse: []discordgo.AllowedMentionType{},
|
||||
Users: []string{},
|
||||
@@ -238,6 +247,7 @@ func (portal *Portal) parseMatrixHTML(content *event.MessageEventContent) (strin
|
||||
}
|
||||
if content.Format == event.FormatHTML && len(content.FormattedBody) > 0 {
|
||||
ctx := format.NewContext()
|
||||
ctx.ReturnData[formatterContextInputAllowedLinkPreviewsKey] = allowedLinkPreviews
|
||||
ctx.ReturnData[formatterContextPortalKey] = portal
|
||||
ctx.ReturnData[formatterContextAllowedMentionsKey] = allowedMentions
|
||||
if content.Mentions != nil {
|
||||
|
||||
29
portal.go
29
portal.go
@@ -1544,7 +1544,8 @@ func (portal *Portal) handleMatrixMessage(sender *User, evt *event.Event) {
|
||||
if editMXID := content.GetRelatesTo().GetReplaceID(); editMXID != "" && content.NewContent != nil {
|
||||
edits := portal.bridge.DB.Message.GetByMXID(portal.Key, editMXID)
|
||||
if edits != nil {
|
||||
discordContent, allowedMentions := portal.parseMatrixHTML(content.NewContent)
|
||||
newContentRaw, _ := evt.Content.Raw["m.new_content"].(map[string]any)
|
||||
discordContent, allowedMentions := portal.parseMatrixHTML(content.NewContent, parseAllowedLinkPreviews(newContentRaw))
|
||||
var err error
|
||||
var msg *discordgo.Message
|
||||
if !isWebhookSend {
|
||||
@@ -1623,7 +1624,7 @@ func (portal *Portal) handleMatrixMessage(sender *User, evt *event.Event) {
|
||||
}
|
||||
switch content.MsgType {
|
||||
case event.MsgText, event.MsgEmote, event.MsgNotice:
|
||||
sendReq.Content, sendReq.AllowedMentions = portal.parseMatrixHTML(content)
|
||||
sendReq.Content, sendReq.AllowedMentions = portal.parseMatrixHTML(content, parseAllowedLinkPreviews(evt.Content.Raw))
|
||||
if content.MsgType == event.MsgEmote {
|
||||
sendReq.Content = fmt.Sprintf("_%s_", sendReq.Content)
|
||||
}
|
||||
@@ -1636,7 +1637,7 @@ func (portal *Portal) handleMatrixMessage(sender *User, evt *event.Event) {
|
||||
filename := content.Body
|
||||
if content.FileName != "" && content.FileName != content.Body {
|
||||
filename = content.FileName
|
||||
sendReq.Content, sendReq.AllowedMentions = portal.parseMatrixHTML(content)
|
||||
sendReq.Content, sendReq.AllowedMentions = portal.parseMatrixHTML(content, parseAllowedLinkPreviews(evt.Content.Raw))
|
||||
}
|
||||
|
||||
if evt.Content.Raw["page.codeberg.everypizza.msc4193.spoiler"] == true {
|
||||
@@ -1744,6 +1745,28 @@ func (portal *Portal) handleMatrixMessage(sender *User, evt *event.Event) {
|
||||
}
|
||||
}
|
||||
|
||||
func parseAllowedLinkPreviews(raw map[string]any) []string {
|
||||
if raw == nil {
|
||||
return nil
|
||||
}
|
||||
linkPreviews, ok := raw["com.beeper.linkpreviews"].([]any)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
allowedLinkPreviews := make([]string, 0, len(linkPreviews))
|
||||
for _, preview := range linkPreviews {
|
||||
previewMap, ok := preview.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
matchedURL, _ := previewMap["matched_url"].(string)
|
||||
if matchedURL != "" {
|
||||
allowedLinkPreviews = append(allowedLinkPreviews, matchedURL)
|
||||
}
|
||||
}
|
||||
return allowedLinkPreviews
|
||||
}
|
||||
|
||||
func (portal *Portal) sendDeliveryReceipt(eventID id.EventID) {
|
||||
if portal.bridge.Config.Bridge.DeliveryReceipts {
|
||||
err := portal.bridge.Bot.MarkRead(portal.MXID, eventID)
|
||||
|
||||
Reference in New Issue
Block a user