diff --git a/bridge/config/config.go b/bridge/config/config.go index 994b83488c..76deee6b0b 100644 --- a/bridge/config/config.go +++ b/bridge/config/config.go @@ -35,19 +35,20 @@ const ( const ParentIDNotFound = "msg-parent-not-found" type Message struct { - Text string `json:"text"` - Channel string `json:"channel"` - Username string `json:"username"` - UserID string `json:"userid"` // userid on the bridge - Avatar string `json:"avatar"` - Account string `json:"account"` - Event string `json:"event"` - Protocol string `json:"protocol"` - Gateway string `json:"gateway"` - ParentID string `json:"parent_id"` - Timestamp time.Time `json:"timestamp"` - ID string `json:"id"` - Extra map[string][]interface{} + Text string `json:"text"` + Channel string `json:"channel"` + Username string `json:"username"` + OriginalUsername string `json:"original_username"` // Username before RemoteNickFormat gets applied + UserID string `json:"userid"` // userid on the bridge + Avatar string `json:"avatar"` + Account string `json:"account"` + Event string `json:"event"` + Protocol string `json:"protocol"` + Gateway string `json:"gateway"` + ParentID string `json:"parent_id"` + Timestamp time.Time `json:"timestamp"` + ID string `json:"id"` + Extra map[string][]interface{} } func (m Message) ParentNotFound() bool { diff --git a/bridge/discord/webhook.go b/bridge/discord/webhook.go index 8dadf5f23e..1a68cfb138 100644 --- a/bridge/discord/webhook.go +++ b/bridge/discord/webhook.go @@ -33,7 +33,7 @@ func (b *Bdiscord) maybeGetLocalAvatar(msg *config.Message) string { continue } - member, err := b.getGuildMemberByNick(msg.Username) + member, err := b.getGuildMemberByNick(msg.OriginalUsername) if err != nil { return "" } @@ -51,7 +51,7 @@ func (b *Bdiscord) webhookSendTextOnly(msg *config.Message, channelID string) (s channelID, &discordgo.WebhookParams{ Content: msgPart, - Username: msg.Username, + Username: msg.OriginalUsername, AvatarURL: msg.Avatar, AllowedMentions: b.getAllowedMentions(), }, @@ -81,7 +81,7 @@ func (b *Bdiscord) webhookSendFilesOnly(msg *config.Message, channelID string) e _, err := b.transmitter.Send( channelID, &discordgo.WebhookParams{ - Username: msg.Username, + Username: msg.OriginalUsername, AvatarURL: msg.Avatar, Files: []*discordgo.File{&file}, Content: content, @@ -137,8 +137,8 @@ func (b *Bdiscord) handleEventWebhook(msg *config.Message, channelID string) (st } // discord username must be [0..32] max - if len(msg.Username) > 32 { - msg.Username = msg.Username[0:32] + if len(msg.OriginalUsername) > 32 { + msg.OriginalUsername = msg.OriginalUsername[0:32] } if msg.ID != "" { @@ -155,7 +155,7 @@ func (b *Bdiscord) handleEventWebhook(msg *config.Message, channelID string) (st // TODO: Optimize away noop-updates of un-edited messages editErr = b.transmitter.Edit(channelID, msgIds[i], &discordgo.WebhookParams{ Content: msgParts[i], - Username: msg.Username, + Username: msg.OriginalUsername, AllowedMentions: b.getAllowedMentions(), }) if editErr != nil { diff --git a/changelog.md b/changelog.md index a61154562d..b3e1694011 100644 --- a/changelog.md +++ b/changelog.md @@ -27,6 +27,7 @@ ## New Features - general + - The original username of a message is carried internally beside the version modified by `RemoteNickFormat` ([#135](https://github.com/matterbridge-org/matterbridge/pull/135)) for bridges that can make use of it. - matterbridge output now colors log level for easier log reading ([#25](https://github.com/matterbridge-org/matterbridge/pull/25)) - new HTTP helpers are common to all bridges, and allow overriding specific settings ([#59](https://github.com/matterbridge-org/matterbridge/pull/59)) - matterbridge is now built with whatsappmulti backend enabled by default, unless the `nowhatsappmulti` build tag is passed @@ -41,6 +42,7 @@ - Can now upload files from bytes in addition to sharing attachement URLs ([#23](https://github.com/matterbridge-org/matterbridge/pull/23/)) - Can now receive and download OOB attachments from XMPP channels to share with other bridges ([#23](https://github.com/matterbridge-org/matterbridge/pull/23/)) - discord + - Messages that use the username-spoofing webhook API always use the original username instead of applying `RemoteNickFormat`. - Replies will be included inline ([#124](https://github.com/matterbridge-org/matterbridge/pull/124), thanks @lekoOwO), by default like "(re name: message)". This is useful when bridging to destinations that do not understand replies, but distracting when the destination does. Can be disabled with `QuoteDisable=true` under your `[discord]` config. - whatsapp - legacy `whatsapp` backend has been deprecated in favor of `whatsappmulti` ([#32](https://github.com/matterbridge-org/matterbridge/issues/32)) ; this is not a breaking change and will not affect your existing settings diff --git a/docs/protocols/discord/README.md b/docs/protocols/discord/README.md index cb4d978e02..bc9212c98e 100644 --- a/docs/protocols/discord/README.md +++ b/docs/protocols/discord/README.md @@ -32,6 +32,8 @@ See [account.md](account.md). [Creating a message](https://discordapp.com/developers/docs/resources/channel#create-message) via a user's API token (the basic configuration above) only lets Matterbridge post with the user/avatar that generated the token. But [executing a webhook](https://discordapp.com/developers/docs/resources/webhook#execute-webhook) can set any username and avatar URL. +However, _replies_ [cannot spo](https://github.com/discord/discord-api-docs/issues/2251)[oof usernames](https://github.com/discord/discord-api-docs/discussions/3282), so unfortunately replies always fall back to embedding the sender's username with `RemoteNickFormat`. + If you grant the bot the "Manage Webhooks" permission, it will automatically load and create webhooks in every bridged channel. You can even grant that permission on specific channels, if you don't want to give it global permission. 1. Server Settings -> Roles diff --git a/gateway/gateway.go b/gateway/gateway.go index 7ca84e4f49..d58e04d1f5 100644 --- a/gateway/gateway.go +++ b/gateway/gateway.go @@ -476,6 +476,7 @@ func (gw *Gateway) SendMessage( msg.Channel = channel.Name msg.Avatar = gw.modifyAvatar(rmsg, dest) + msg.OriginalUsername = msg.Username msg.Username = gw.modifyUsername(rmsg, dest) // exclude file delete event as the msg ID here is the native file ID that needs to be deleted