Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ RUN apk add --no-cache git ca-certificates build-base su-exec olm-dev

COPY . /build
WORKDIR /build
RUN go build -o /usr/bin/mautrix-discord
RUN ./build.sh -o /usr/bin/mautrix-discord

FROM alpine:3.22

Expand Down
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh
MAUTRIX_VERSION=$(cat go.mod | grep 'maunium.net/go/mautrix ' | awk '{ print $2 }')
GO_LDFLAGS="-X main.Tag=$(git describe --exact-match --tags 2>/dev/null) -X main.Commit=$(git rev-parse HEAD) -X 'main.BuildTime=`date -Iseconds`' -X 'maunium.net/go/mautrix.GoModVersion=$MAUTRIX_VERSION'"
go build -ldflags="-s -w $GO_LDFLAGS" ./cmd/mautrix-discord "$@"
go build -ldflags="-s -w $GO_LDFLAGS" "$@" ./cmd/mautrix-discord
2 changes: 2 additions & 0 deletions cmd/mautrix-discord/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package main

import (
"maunium.net/go/mautrix/bridgev2/bridgeconfig"
"maunium.net/go/mautrix/bridgev2/matrix/mxmain"

"go.mau.fi/mautrix-discord/pkg/connector"
Expand All @@ -40,6 +41,7 @@ var m = mxmain.BridgeMain{
}

func main() {
bridgeconfig.HackyMigrateLegacyNetworkConfig = connector.MigrateLegacyConfig
m.PostInit = func() {
m.CheckLegacyDB(24, "v0.7.6", "v26.03",
m.LegacyMigrateWithAnotherUpgrader(
Expand Down
22 changes: 11 additions & 11 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ toolchain go1.26.2

require (
github.com/bwmarrin/discordgo v0.27.0
github.com/coder/websocket v1.8.14
github.com/coder/websocket v1.8.15
github.com/google/uuid v1.6.0
github.com/imroc/req/v3 v3.57.0
github.com/refraction-networking/utls v1.8.1
github.com/rs/zerolog v1.35.1
github.com/yuin/goldmark v1.8.2
go.mau.fi/util v0.9.9
golang.org/x/net v0.55.0
golang.org/x/term v0.43.0
go.mau.fi/util v0.9.10
golang.org/x/net v0.56.0
golang.org/x/term v0.44.0
gopkg.in/yaml.v3 v3.0.1
maunium.net/go/mautrix v0.28.1-0.20260519145316-34b5f49408a3
maunium.net/go/mautrix v0.28.2-0.20260702123919-bf2dbb2aa895
)

require (
Expand All @@ -30,7 +30,7 @@ require (
github.com/lib/pq v1.12.3 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.21 // indirect
github.com/mattn/go-sqlite3 v1.14.44 // indirect
github.com/mattn/go-sqlite3 v1.14.45 // indirect
github.com/petermattis/goid v0.0.0-20260330135022-df67b199bc81 // indirect
github.com/quic-go/qpack v0.6.0 // indirect
github.com/quic-go/quic-go v0.57.1 // indirect
Expand All @@ -41,11 +41,11 @@ require (
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tidwall/sjson v1.2.5 // indirect
go.mau.fi/zeroconfig v0.2.0 // indirect
golang.org/x/crypto v0.52.0 // indirect
golang.org/x/exp v0.0.0-20260508232706-74f9aab9d74a // indirect
golang.org/x/sync v0.20.0 // indirect
golang.org/x/sys v0.45.0 // indirect
golang.org/x/text v0.37.0 // indirect
golang.org/x/crypto v0.53.0 // indirect
golang.org/x/exp v0.0.0-20260611194520-c48552f49976 // indirect
golang.org/x/sync v0.21.0 // indirect
golang.org/x/sys v0.46.0 // indirect
golang.org/x/text v0.38.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
maunium.net/go/mauflag v1.0.0 // indirect
)
Expand Down
44 changes: 22 additions & 22 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ github.com/beeper/discordgo v0.0.0-20260620030032-507542c8bda5 h1:RS1pVR7FUf0nD3
github.com/beeper/discordgo v0.0.0-20260620030032-507542c8bda5/go.mod h1:s8aRVTzFZnyujER0GEVscqvjH6RwlPIzeDjOtWsrReM=
github.com/beeper/req/v3 v3.0.0-20260114152409-4c060b237f73 h1:stqCPKTpnUY5JFn6wShL4RoMnebtR+MNC9fcLvOCH1Y=
github.com/beeper/req/v3 v3.0.0-20260114152409-4c060b237f73/go.mod h1:pH5qbsMNeaNpCOlozJoLRuLfSxEYGp9uWEG5j6zogNQ=
github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g=
github.com/coder/websocket v1.8.14/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg=
github.com/coder/websocket v1.8.15 h1:6B2JPeOGlpff2Uz6vOEH1Vzpi0iUz20A+lPVhPHtNUA=
github.com/coder/websocket v1.8.15/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg=
github.com/coreos/go-systemd/v22 v22.7.0 h1:LAEzFkke61DFROc7zNLX/WA2i5J8gYqe0rSj9KI28KA=
github.com/coreos/go-systemd/v22 v22.7.0/go.mod h1:xNUYtjHu2EDXbsxz1i41wouACIwT7Ybq9o0BQhMwD0w=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
Expand All @@ -36,8 +36,8 @@ github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHP
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.21 h1:xYae+lCNBP7QuW4PUnNG61ffM4hVIfm+zUzDuSzYLGs=
github.com/mattn/go-isatty v0.0.21/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
github.com/mattn/go-sqlite3 v1.14.44 h1:3VSe+xafpbzsLbdr2AWlAZk9yRHiBhTBakioXaCKTF8=
github.com/mattn/go-sqlite3 v1.14.44/go.mod h1:pjEuOr8IwzLJP2MfGeTb0A35jauH+C2kbHKBr7yXKVQ=
github.com/mattn/go-sqlite3 v1.14.45 h1:6KA/spDguL3KV8rnybG7ezSaE4SeMR3KC9VbUoAQaIk=
github.com/mattn/go-sqlite3 v1.14.45/go.mod h1:pjEuOr8IwzLJP2MfGeTb0A35jauH+C2kbHKBr7yXKVQ=
github.com/petermattis/goid v0.0.0-20260330135022-df67b199bc81 h1:WDsQxOJDy0N1VRAjXLpi8sCEZRSGarLWQevDxpTBRrM=
github.com/petermattis/goid v0.0.0-20260330135022-df67b199bc81/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand Down Expand Up @@ -73,26 +73,26 @@ github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZ
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
github.com/yuin/goldmark v1.8.2 h1:kEGpgqJXdgbkhcOgBxkC0X0PmoPG1ZyoZ117rDVp4zE=
github.com/yuin/goldmark v1.8.2/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
go.mau.fi/util v0.9.9 h1:ujDeXCo07HBor5oQLyO1tHklupmqVmPgasc53d7q/NE=
go.mau.fi/util v0.9.9/go.mod h1:pqt4Vcrt+5gcH/CgrHZg11qSx+b34o6mknGzOEA6waY=
go.mau.fi/util v0.9.10 h1:wzvz5iDHyqDXB8vgisD4d3SzucLXNM3iNY+1O1RoHtg=
go.mau.fi/util v0.9.10/go.mod h1:YQOxySn+ZE3qSYqNxvyX7Yi3suA8YK17PS6QqBREW7A=
go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU=
go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w=
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988=
golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc=
golang.org/x/exp v0.0.0-20260508232706-74f9aab9d74a h1:+3jdDGGB8NGb1Zktc737jlt3/A5f6UlwSzmvqUuufxw=
golang.org/x/exp v0.0.0-20260508232706-74f9aab9d74a/go.mod h1:d2fgXJLVs4dYDHUk5lwMIfzRzSrWCfGZb0ZqeLa/Vcw=
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
golang.org/x/exp v0.0.0-20260611194520-c48552f49976 h1:X8Hz2ImujgbmetVuW+w2YkyZChE3cBpZi2P158rTG9M=
golang.org/x/exp v0.0.0-20260611194520-c48552f49976/go.mod h1:vnf4pv9iKZXY58sQE1L86zmNWJ4159e1RkcWiLCkeEY=
golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE=
golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand All @@ -107,5 +107,5 @@ gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M=
maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA=
maunium.net/go/mautrix v0.28.1-0.20260519145316-34b5f49408a3 h1:l86igJY8Te5JEBNPL9NSpZaGv6eHsxtCrAabXv8KPJo=
maunium.net/go/mautrix v0.28.1-0.20260519145316-34b5f49408a3/go.mod h1:/a9A7LGaqb9B3nho4tLd28n0EPcCdwpm2dxkxkLLgh0=
maunium.net/go/mautrix v0.28.2-0.20260702123919-bf2dbb2aa895 h1:oe87/mP1vo4LnA6CJDEfyg5ZiAOar2quJNypfO8eS4Y=
maunium.net/go/mautrix v0.28.2-0.20260702123919-bf2dbb2aa895/go.mod h1:mWXQNmOlrq4VTDU9f1HO03BSIswdUIyyY4wUKHqwzzY=
4 changes: 4 additions & 0 deletions pkg/connector/capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ var discordCaps = &event.RoomFeatures{
LocationMessage: event.CapLevelUnsupported,
MaxTextLength: MaxTextLength,
Thread: event.CapLevelPartialSupport,

// Relayed Matrix users are sent through Discord webhooks, so Discord can
// show the sender name per message instead of prefixing the content.
PerMessageProfileRelay: true,
}

func (d *DiscordClient) GetCapabilities(ctx context.Context, portal *bridgev2.Portal) *event.RoomFeatures {
Expand Down
10 changes: 10 additions & 0 deletions pkg/connector/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/bwmarrin/discordgo"
up "go.mau.fi/util/configupgrade"
"gopkg.in/yaml.v3"
"maunium.net/go/mautrix/bridgev2/bridgeconfig"
)

//go:embed example-config.yaml
Expand Down Expand Up @@ -147,6 +148,15 @@ func upgradeConfig(helper up.Helper) {
helper.Copy(up.Bool, "proxy_login_remoteauth")
}

func MigrateLegacyConfig(helper up.Helper) {
bridgeconfig.CopyToOtherLocation(helper, up.Str, []string{"bridge", "channel_name_template"}, []string{"network", "channel_name_template"})
bridgeconfig.CopyToOtherLocation(helper, up.Bool, []string{"bridge", "custom_emoji_reactions"}, []string{"network", "custom_emoji_reactions"})
bridgeconfig.CopyToOtherLocation(helper, up.Bool, []string{"bridge", "guild_avatars_in_rooms"}, []string{"network", "guilds", "guild_avatars_in_rooms"})
bridgeconfig.CopyToOtherLocation(helper, up.Bool, []string{"bridge", "forbid_dming_strangers"}, []string{"network", "forbid_dming_strangers"})
bridgeconfig.CopyToOtherLocation(helper, up.Bool, []string{"bridge", "log_when_dropping_messages"}, []string{"network", "log_when_dropping_messages"})
bridgeconfig.CopyToOtherLocation(helper, up.Str, []string{"bridge", "proxy"}, []string{"network", "proxy"})
}

func (d *DiscordConnector) GetConfig() (example string, data any, upgrader up.Upgrader) {
return ExampleConfig, &d.Config, up.SimpleUpgrader(upgradeConfig)
}
16 changes: 7 additions & 9 deletions pkg/connector/directmedia_test.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
package connector

import (
"encoding/binary"
"encoding/hex"
"testing"
"time"
)

func TestParseAttachmentExpiryParam(t *testing.T) {
losAngeles, err := time.LoadLocation("America/Los_Angeles")
if err != nil {
t.Fatalf("failed to load test timezone: %v", err)
}

expiry := parseAttachmentExpiryParam("69be6214").In(losAngeles)
got := expiry.String()
want := "2026-03-21 02:17:08 -0700 PDT"
want := time.Now().Add(24 * time.Hour).Truncate(time.Second)
var encoded [4]byte
binary.BigEndian.PutUint32(encoded[:], uint32(want.Unix()))

if got != want {
got := parseAttachmentExpiryParam(hex.EncodeToString(encoded[:]))
if !got.Equal(want) {
t.Fatalf("unexpected parsed expiry: got %q, want %q", got, want)
}
}
34 changes: 34 additions & 0 deletions pkg/connector/handlediscord.go
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,32 @@ func (d *DiscordClient) channelIsBridged(ctx context.Context, channelID string)
return existingPortal != nil && existingPortal.MXID != "", route
}

func (d *DiscordClient) isOwnRelayWebhookMessage(ctx context.Context, msg *discordgo.Message, route *router.Route) bool {
if msg == nil || route == nil {
return false
}
portal, err := d.connector.Bridge.GetExistingPortalByKey(ctx, route.PortalKey)
if err != nil {
zerolog.Ctx(ctx).Warn().Err(err).Msg("Failed to look up portal when checking relay webhook message")
return false
}
if portal == nil {
return false
}
meta := portal.Metadata.(*discordid.PortalMetadata)
return isRelayWebhookDiscordMessage(msg, meta.RelayWebhookID)
}

func isRelayWebhookDiscordMessage(msg *discordgo.Message, relayWebhookID string) bool {
if msg == nil || relayWebhookID == "" {
return false
}
if msg.WebhookID == relayWebhookID {
return true
}
return msg.WebhookID != "" && msg.Author != nil && msg.Author.ID == relayWebhookID
}

func (d *DiscordClient) handleUserGuildSettingsUpdate(ctx context.Context, evt *discordgo.UserGuildSettingsUpdate) {
log := zerolog.Ctx(ctx)
log.Debug().Msg("Handling user guild settings update")
Expand Down Expand Up @@ -1010,6 +1036,10 @@ func (d *DiscordClient) handleDiscordEvent(rawEvt any) {
}
return
}
if d.isOwnRelayWebhookMessage(ctx, evt.Message, route) {
log.Debug().Msg("Dropping message from own relay webhook")
return
}

if evt.Message.Type == discordgo.MessageTypeGuildMemberJoin {
d.userCache.UpdateWithMessage(evt.Message)
Expand All @@ -1030,6 +1060,10 @@ func (d *DiscordClient) handleDiscordEvent(rawEvt any) {
if !bridged {
return
}
if d.isOwnRelayWebhookMessage(ctx, evt.Message, route) {
log.Debug().Msg("Dropping message update from own relay webhook")
return
}

if err := d.upsertThreadInfoFromMessage(ctx, evt.Message); err != nil {
log.Err(err).Str("message_id", evt.ID).Msg("Failed to persist thread info from message update")
Expand Down
79 changes: 77 additions & 2 deletions pkg/connector/handlematrix.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,39 @@ func (d *DiscordClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.M
d.lastSendAttemptMutex.Unlock()
}

sentMsg, err := d.Session.ChannelMessageSendComplex(channelID, sendReq, refererOpt, discordgo.WithContext(ctx))
var sentMsg *discordgo.Message
if msg.OrigSender != nil {
if guildID == "" {
err = fmt.Errorf("Discord webhooks are not available in DMs/group DMs")
return nil, bridgev2.WrapErrorInStatus(err).
WithStatus(event.MessageStatusFail).
WithIsCertain(true).
WithMessage("Relay messages need Discord webhooks, which are only available in guild channels.").
WithSendNotice(true)
}
username, avatarURL := d.relayWebhookProfile(ctx, portal, msg.OrigSender)
if username == "" {
username = msg.OrigSender.UserID.String()
}
username = sanitizeRelayWebhookUsername(username, msg.OrigSender.UserID.String())
params := &discordgo.WebhookParams{
Content: sendReq.Content,
Username: username,
AvatarURL: avatarURL,
Embeds: sendReq.Embeds,
Components: sendReq.Components,
Files: sendReq.Files,
Attachments: sendReq.Attachments,
AllowedMentions: sendReq.AllowedMentions,
Flags: relayWebhookFlags(sendReq.Flags),
}
if sendReq.Reference != nil {
params.Embeds = prependReplyEmbed(params.Embeds, guildID, sendReq.Reference.ChannelID, sendReq.Reference.MessageID)
}
sentMsg, err = d.executeRelayWebhook(ctx, portal, parentChannelID, threadChannelID, params, refererOpt)
} else {
sentMsg, err = d.Session.ChannelMessageSendComplex(channelID, sendReq, refererOpt, discordgo.WithContext(ctx))
}
if err != nil {
return nil, d.tryWrappingError(ctx, err)
}
Expand Down Expand Up @@ -213,11 +245,14 @@ func (d *DiscordClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.Matr
if !d.IsLoggedIn() {
return bridgev2.ErrNotLoggedIn
}
if msg.EditTarget == nil {
return fmt.Errorf("missing edit target")
}

log := zerolog.Ctx(ctx).With().Str("action", "matrix message edit").Logger()
ctx = log.WithContext(ctx)

content, _ := d.connector.MsgConv.ConvertMatrixMessageContent(
content, allowedMentions := d.connector.MsgConv.ConvertMatrixMessageContent(
ctx,
msg.Portal,
msg.Content,
Expand All @@ -240,6 +275,29 @@ func (d *DiscordClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.Matr
}
}

if d.isRelayWebhookMessage(msg.Portal, msg.EditTarget) {
meta := msg.Portal.Metadata.(*discordid.PortalMetadata)
edit := &discordgo.WebhookEdit{
Content: &content,
AllowedMentions: allowedMentions,
}
if err := d.populateRelayWebhookEditMedia(ctx, edit, msg.Content); err != nil {
return err
}
_, err := d.webhookMessageEditThread(
ctx,
meta.RelayWebhookID,
meta.RelayWebhookToken,
discordid.ParseMessageID(msg.EditTarget.ID),
threadChannelID,
edit,
)
if err != nil {
return d.tryWrappingError(ctx, err)
}
return nil
}

_, err := d.Session.ChannelMessageEdit(
channelID,
discordid.ParseMessageID(msg.EditTarget.ID),
Expand Down Expand Up @@ -275,6 +333,10 @@ func (d *DiscordClient) PreHandleMatrixReaction(ctx context.Context, reaction *b
emojiID = variationselector.FullyQualify(emojiID)
}

// Relayed reactions have to use the relay login on Discord. Discord only
// allows one reaction per user/emoji, so multiple Matrix users reacting
// with the same emoji intentionally collapse into the relay user's one
// Discord reaction.
return bridgev2.MatrixReactionPreResponse{
SenderID: discordid.UserLoginIDToUserID(d.UserLogin.ID),
EmojiID: discordid.MakeEmojiID(emojiID),
Expand Down Expand Up @@ -349,6 +411,9 @@ func (d *DiscordClient) HandleMatrixMessageRemove(ctx context.Context, removal *
if !d.IsLoggedIn() {
return bridgev2.ErrNotLoggedIn
}
if removal.TargetMessage == nil {
return fmt.Errorf("missing message remove target")
}

guildID := removal.Portal.Metadata.(*discordid.PortalMetadata).GuildID
parentChannelID := discordid.ParseChannelPortalID(removal.Portal.ID)
Expand All @@ -364,6 +429,16 @@ func (d *DiscordClient) HandleMatrixMessageRemove(ctx context.Context, removal *
}
}
messageID := discordid.ParseMessageID(removal.TargetMessage.ID)
if d.isRelayWebhookMessage(removal.Portal, removal.TargetMessage) {
meta := removal.Portal.Metadata.(*discordid.PortalMetadata)
return d.tryWrappingError(ctx, d.webhookMessageDeleteThread(
ctx,
meta.RelayWebhookID,
meta.RelayWebhookToken,
messageID,
threadChannelID,
))
}
return d.tryWrappingError(ctx, d.Session.ChannelMessageDelete(channelID, messageID, makeDiscordReferer(guildID, parentChannelID, threadChannelID)))
}

Expand Down
Loading