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 formatterContextPortalKey = "fi.mau.discord.portal"
|
||||||
const formatterContextAllowedMentionsKey = "fi.mau.discord.allowed_mentions"
|
const formatterContextAllowedMentionsKey = "fi.mau.discord.allowed_mentions"
|
||||||
const formatterContextInputAllowedMentionsKey = "fi.mau.discord.input_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 {
|
func appendIfNotContains(arr []string, newItem string) []string {
|
||||||
for _, item := range arr {
|
for _, item := range arr {
|
||||||
@@ -221,16 +222,24 @@ var matrixHTMLParser = &format.HTMLParser{
|
|||||||
return fmt.Sprintf("||%s||", text)
|
return fmt.Sprintf("||%s||", text)
|
||||||
},
|
},
|
||||||
LinkConverter: func(text, href string, ctx format.Context) string {
|
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 text == href {
|
||||||
|
if !allowPreview {
|
||||||
|
return fmt.Sprintf("<%s>", text)
|
||||||
|
}
|
||||||
return text
|
return text
|
||||||
} else if !discordLinkRegexFull.MatchString(href) {
|
} else if !discordLinkRegexFull.MatchString(href) {
|
||||||
return fmt.Sprintf("%s (%s)", escapeDiscordMarkdown(text), escapeDiscordMarkdown(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)
|
||||||
}
|
}
|
||||||
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{
|
allowedMentions := &discordgo.MessageAllowedMentions{
|
||||||
Parse: []discordgo.AllowedMentionType{},
|
Parse: []discordgo.AllowedMentionType{},
|
||||||
Users: []string{},
|
Users: []string{},
|
||||||
@@ -238,6 +247,7 @@ func (portal *Portal) parseMatrixHTML(content *event.MessageEventContent) (strin
|
|||||||
}
|
}
|
||||||
if content.Format == event.FormatHTML && len(content.FormattedBody) > 0 {
|
if content.Format == event.FormatHTML && len(content.FormattedBody) > 0 {
|
||||||
ctx := format.NewContext()
|
ctx := format.NewContext()
|
||||||
|
ctx.ReturnData[formatterContextInputAllowedLinkPreviewsKey] = allowedLinkPreviews
|
||||||
ctx.ReturnData[formatterContextPortalKey] = portal
|
ctx.ReturnData[formatterContextPortalKey] = portal
|
||||||
ctx.ReturnData[formatterContextAllowedMentionsKey] = allowedMentions
|
ctx.ReturnData[formatterContextAllowedMentionsKey] = allowedMentions
|
||||||
if content.Mentions != nil {
|
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 {
|
if editMXID := content.GetRelatesTo().GetReplaceID(); editMXID != "" && content.NewContent != nil {
|
||||||
edits := portal.bridge.DB.Message.GetByMXID(portal.Key, editMXID)
|
edits := portal.bridge.DB.Message.GetByMXID(portal.Key, editMXID)
|
||||||
if edits != nil {
|
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 err error
|
||||||
var msg *discordgo.Message
|
var msg *discordgo.Message
|
||||||
if !isWebhookSend {
|
if !isWebhookSend {
|
||||||
@@ -1623,7 +1624,7 @@ func (portal *Portal) handleMatrixMessage(sender *User, evt *event.Event) {
|
|||||||
}
|
}
|
||||||
switch content.MsgType {
|
switch content.MsgType {
|
||||||
case event.MsgText, event.MsgEmote, event.MsgNotice:
|
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 {
|
if content.MsgType == event.MsgEmote {
|
||||||
sendReq.Content = fmt.Sprintf("_%s_", sendReq.Content)
|
sendReq.Content = fmt.Sprintf("_%s_", sendReq.Content)
|
||||||
}
|
}
|
||||||
@@ -1636,7 +1637,7 @@ func (portal *Portal) handleMatrixMessage(sender *User, evt *event.Event) {
|
|||||||
filename := content.Body
|
filename := content.Body
|
||||||
if content.FileName != "" && content.FileName != content.Body {
|
if content.FileName != "" && content.FileName != content.Body {
|
||||||
filename = content.FileName
|
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 {
|
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) {
|
func (portal *Portal) sendDeliveryReceipt(eventID id.EventID) {
|
||||||
if portal.bridge.Config.Bridge.DeliveryReceipts {
|
if portal.bridge.Config.Bridge.DeliveryReceipts {
|
||||||
err := portal.bridge.Bot.MarkRead(portal.MXID, eventID)
|
err := portal.bridge.Bot.MarkRead(portal.MXID, eventID)
|
||||||
|
|||||||
Reference in New Issue
Block a user