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}
}