diff --git a/example-config.yaml b/example-config.yaml index 9530a2b..ea392bb 100644 --- a/example-config.yaml +++ b/example-config.yaml @@ -91,7 +91,7 @@ bridge: # .System - Whether the user is an official system user # .Webhook - Whether the user is a webhook and is not an application # .Application - Whether the user is an application - displayname_template: '{{or .GlobalName .Username}}{{if .Bot}} (bot){{end}}' + displayname_template: '{{if .Webhook}}Webhook{{else}}{{or .GlobalName .Username}}{{if .Bot}} (bot){{end}}{{end}}' # Displayname template for Discord channels (bridged as rooms, or spaces when type=4). # Available variables: # .Name - Channel name, or user displayname (pre-formatted with displayname_template) in DMs. @@ -161,9 +161,12 @@ bridge: federate_rooms: true # Prefix messages from webhooks with the profile info? This can be used along with a custom displayname_template # to better handle webhooks that change their name all the time (like ones used by bridges). - prefix_webhook_messages: false + # + # This will use the fallback mode in MSC4144, which means clients that support MSC4144 will not show the prefix + # (and will instead show the name and avatar as the message sender). + prefix_webhook_messages: true # Bridge webhook avatars? - enable_webhook_avatars: true + enable_webhook_avatars: false # Should the bridge upload media to the Discord CDN directly before sending the message when using a user token, # like the official client does? The other option is sending the media in the message send request as a form part # (which is always used by bots and webhooks). diff --git a/portal_convert.go b/portal_convert.go index 26df0a5..6823e2c 100644 --- a/portal_convert.go +++ b/portal_convert.go @@ -403,10 +403,20 @@ func (puppet *Puppet) addWebhookMeta(part *ConvertedMessage, msg *discordgo.Mess "avatar_mxc": avatarURL.String(), } profileID := sha256.Sum256(fmt.Appendf(nil, "%s:%s", msg.Author.Username, msg.Author.Avatar)) + hasFallback := false + if msg.ApplicationID == "" && + puppet.bridge.Config.Bridge.PrefixWebhookMessages && + (part.Content.MsgType == event.MsgText || part.Content.MsgType == event.MsgNotice || (part.Content.FileName != "" && part.Content.FileName != part.Content.Body)) { + part.Content.EnsureHasHTML() + part.Content.Body = fmt.Sprintf("%s: %s", msg.Author.Username, part.Content.Body) + part.Content.FormattedBody = fmt.Sprintf("%s: %s", html.EscapeString(msg.Author.Username), part.Content.FormattedBody) + hasFallback = true + } part.Extra["com.beeper.per_message_profile"] = map[string]any{ - "id": hex.EncodeToString(profileID[:]), - "avatar_url": avatarURL.String(), - "displayname": msg.Author.Username, + "id": hex.EncodeToString(profileID[:]), + "avatar_url": avatarURL.String(), + "displayname": msg.Author.Username, + "has_fallback": hasFallback, } } @@ -765,11 +775,5 @@ func (portal *Portal) convertDiscordTextMessage(ctx context.Context, intent *app "com.beeper.linkpreviews": previews, } - if msg.WebhookID != "" && msg.ApplicationID == "" && portal.bridge.Config.Bridge.PrefixWebhookMessages { - content.EnsureHasHTML() - content.Body = fmt.Sprintf("%s: %s", msg.Author.Username, content.Body) - content.FormattedBody = fmt.Sprintf("%s: %s", html.EscapeString(msg.Author.Username), content.FormattedBody) - } - return &ConvertedMessage{Type: event.EventMessage, Content: &content, Extra: extraContent} }