From c3fc77c2a8295c9a6583d53773f3aa4c7737bc51 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Thu, 9 Jan 2025 12:52:43 -0700 Subject: [PATCH] connector: always use channel sender in broadcast rooms and add per-message profile Signed-off-by: Sumner Evans --- go.mod | 18 +++++++++--------- go.sum | 36 ++++++++++++++++++------------------ pkg/connector/backfill.go | 2 +- pkg/connector/telegram.go | 26 ++++++++++++++++++++------ pkg/connector/tomatrix.go | 17 +++++++++++++++++ 5 files changed, 65 insertions(+), 34 deletions(-) diff --git a/go.mod b/go.mod index dce874a4..356db58c 100644 --- a/go.mod +++ b/go.mod @@ -10,12 +10,12 @@ require ( github.com/gotd/td v0.111.0 github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.10.0 - go.mau.fi/util v0.8.2 + go.mau.fi/util v0.8.4-0.20250106152331-30b8c95e7d7a go.mau.fi/zerozap v0.1.1 go.uber.org/zap v1.27.0 - golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f - golang.org/x/net v0.31.0 - maunium.net/go/mautrix v0.22.1-0.20241202131110-166ba04aae02 + golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 + golang.org/x/net v0.33.0 + maunium.net/go/mautrix v0.22.2-0.20250109192415-9748015309bd ) require ( @@ -34,7 +34,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.24 // indirect - github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274 // indirect + github.com/petermattis/goid v0.0.0-20241211131331-93ee7e083c43 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rs/xid v1.6.0 // indirect github.com/segmentio/asm v1.2.0 // indirect @@ -49,10 +49,10 @@ require ( go.opentelemetry.io/otel/trace v1.32.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.29.0 // indirect - golang.org/x/sync v0.9.0 // indirect - golang.org/x/sys v0.27.0 // indirect - golang.org/x/text v0.20.0 // indirect + golang.org/x/crypto v0.32.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/text v0.21.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect maunium.net/go/mauflag v1.0.0 // indirect diff --git a/go.sum b/go.sum index 766c5fab..f74d66c7 100644 --- a/go.sum +++ b/go.sum @@ -46,8 +46,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274 h1:qli3BGQK0tYDkSEvZ/FzZTi9ZrOX86Q6CIhKLGc489A= -github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/petermattis/goid v0.0.0-20241211131331-93ee7e083c43 h1:ah1dvbqPMN5+ocrg/ZSgZ6k8bOk+kcZQ7fnyx6UvOm4= +github.com/petermattis/goid v0.0.0-20241211131331-93ee7e083c43/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -76,8 +76,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.8.2 h1:zWbVHwdRKwI6U9AusmZ8bwgcLosikwbb4GGqLrNr1YE= -go.mau.fi/util v0.8.2/go.mod h1:BHHC9R2WLMJd1bwTZfTcFxUgRFmUgUmiWcT4RbzUgiA= +go.mau.fi/util v0.8.4-0.20250106152331-30b8c95e7d7a h1:D9RCHBFjxah9F/YB7amvRJjT2IEOFWcz8jpcEY8dBV0= +go.mau.fi/util v0.8.4-0.20250106152331-30b8c95e7d7a/go.mod h1:MOfGTs1CBuK6ERTcSL4lb5YU7/ujz09eOPVEDckuazY= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= go.mau.fi/zerozap v0.1.1 h1:mxE/dW4wtkqBYOXOEEzXldk5qKB+ahsZXjoTGnvEhZQ= @@ -94,22 +94,22 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= -golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo= -golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 h1:9kj3STMvgqy3YA4VQXBrN7925ICMxD5wzMRcgA30588= +golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -119,8 +119,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 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.22.1-0.20241202131110-166ba04aae02 h1:g8L4GpOhyg5EuXtASDKyU9Cg79ZjATlUnh+giFumQgc= -maunium.net/go/mautrix v0.22.1-0.20241202131110-166ba04aae02/go.mod h1:oqwf9WYC/brqucM+heYk4gX11O59nP+ljvyxVhndFIM= +maunium.net/go/mautrix v0.22.2-0.20250109192415-9748015309bd h1:v83tY7Tp8vF1/dOH8nP762eDwm5cAuijnj3sjrjYzvc= +maunium.net/go/mautrix v0.22.2-0.20250109192415-9748015309bd/go.mod h1:FmwzK7RSzrd1OfGDgJzFWXl7nYmYm8/P0Y77sy/A1Uw= nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y= nhooyr.io/websocket v1.8.17/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY= diff --git a/pkg/connector/backfill.go b/pkg/connector/backfill.go index 4fa732ac..6c04efbd 100644 --- a/pkg/connector/backfill.go +++ b/pkg/connector/backfill.go @@ -268,7 +268,7 @@ func (t *TelegramClient) FetchMessages(ctx context.Context, fetchParams bridgev2 continue } - sender := t.getEventSender(message) + sender := t.getEventSender(message, !portal.Metadata.(*PortalMetadata).IsSuperGroup) intent := portal.GetIntentFor(ctx, sender, t.userLogin, bridgev2.RemoteEventBackfill) converted, err := t.convertToMatrix(ctx, portal, intent, message) if err != nil { diff --git a/pkg/connector/telegram.go b/pkg/connector/telegram.go index 21a3ef69..2480162d 100644 --- a/pkg/connector/telegram.go +++ b/pkg/connector/telegram.go @@ -92,8 +92,7 @@ func (t *TelegramClient) onUpdateNewMessage(ctx context.Context, entities tg.Ent log := zerolog.Ctx(ctx) switch msg := update.GetMessage().(type) { case *tg.Message: - sender := t.getEventSender(msg) - + var isBroadcastChannel bool switch peer := msg.PeerID.(type) { case *tg.PeerChannel: log := log.With().Int64("channel_id", peer.ChannelID).Logger() @@ -103,6 +102,8 @@ func (t *TelegramClient) onUpdateNewMessage(ctx context.Context, entities tg.Ent } else if c, ok := entities.Channels[peer.ChannelID]; ok && c.Left { log.Debug().Msg("Received message in left channel, ignoring") return nil + } else if ok && !c.GetMegagroup() { + isBroadcastChannel = true } case *tg.PeerChat: log := log.With().Int64("chat_id", peer.ChatID).Logger() @@ -115,6 +116,8 @@ func (t *TelegramClient) onUpdateNewMessage(ctx context.Context, entities tg.Ent } } + sender := t.getEventSender(msg, isBroadcastChannel) + go t.handleTelegramReactions(ctx, msg) if media, ok := msg.GetMedia(); ok && media.TypeID() == tg.MessageMediaContactTypeID { @@ -145,7 +148,7 @@ func (t *TelegramClient) onUpdateNewMessage(ctx context.Context, entities tg.Ent ConvertMessageFunc: t.convertToMatrix, }) case *tg.MessageService: - sender := t.getEventSender(msg) + sender := t.getEventSender(msg, false) eventMeta := simplevent.EventMeta{ PortalKey: t.makePortalKeyFromPeer(msg.PeerID), @@ -498,7 +501,13 @@ func (t *TelegramClient) getEventSender(msg interface { GetOut() bool GetFromID() (tg.PeerClass, bool) GetPeerID() tg.PeerClass -}) bridgev2.EventSender { +}, isBroadcastChannel bool) bridgev2.EventSender { + if isBroadcastChannel && msg.GetPeerID().TypeID() == tg.PeerChannelTypeID { + // Always send as the channel in broadcast channels. We set a + // per-message profile to indicate the actual user it was from. + return t.getPeerSender(msg.GetPeerID()) + } + if msg.GetOut() { return t.mySender() } @@ -721,7 +730,12 @@ func (t *TelegramClient) onMessageEdit(ctx context.Context, update IGetMessage) t.handleTelegramReactions(ctx, msg) - sender := t.getEventSender(msg) + portalKey := t.makePortalKeyFromPeer(msg.PeerID) + portal, err := t.main.Bridge.GetPortalByKey(ctx, portalKey) + if err != nil { + return err + } + sender := t.getEventSender(msg, !portal.Metadata.(*PortalMetadata).IsSuperGroup) // Check if this edit was a data export request acceptance message if sender.Sender == networkid.UserID("777000") { @@ -743,7 +757,7 @@ func (t *TelegramClient) onMessageEdit(ctx context.Context, update IGetMessage) Int("message_id", msg.ID) }, Sender: sender, - PortalKey: t.makePortalKeyFromPeer(msg.PeerID), + PortalKey: portalKey, Timestamp: time.Unix(int64(msg.EditDate), 0), }, ID: ids.GetMessageIDFromMessage(msg), diff --git a/pkg/connector/tomatrix.go b/pkg/connector/tomatrix.go index f716c52f..50b6d199 100644 --- a/pkg/connector/tomatrix.go +++ b/pkg/connector/tomatrix.go @@ -109,6 +109,22 @@ func (c *TelegramClient) convertToMatrix(ctx context.Context, portal *bridgev2.P return nil, fmt.Errorf("telegram client is nil, we are likely logged out") } + var perMessageProfile *event.BeeperPerMessageProfile + if peerType, _, err := ids.ParsePortalID(portal.ID); err != nil { + return nil, err + } else if peerType == ids.PeerTypeChannel && !portal.Metadata.(*PortalMetadata).IsSuperGroup { + var profile event.BeeperPerMessageProfile + if msg.Out { + profile, err = portal.PerMessageProfileForSender(ctx, c.userID) + } else { + profile, err = portal.PerMessageProfileForSender(ctx, c.getPeerSender(msg.FromID).Sender) + } + if err != nil { + return nil, err + } + perMessageProfile = &profile + } + cm = &bridgev2.ConvertedMessage{} hasher := sha256.New() if len(msg.Message) > 0 { @@ -153,6 +169,7 @@ func (c *TelegramClient) convertToMatrix(ctx context.Context, portal *bridgev2.P cm.Disappear = *disappearingSetting } } + cm.Parts[0].Content.BeeperPerMessageProfile = perMessageProfile cm.Parts[0].DBMetadata = &MessageMetadata{ ContentHash: hasher.Sum(nil), ContentURI: contentURI,