diff --git a/go.mod b/go.mod index 3fe2f530..a8b10a62 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( go.uber.org/zap v1.27.0 golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 golang.org/x/net v0.29.0 - maunium.net/go/mautrix v0.20.1-0.20240913182028-ff4126b5d04d + maunium.net/go/mautrix v0.20.1-0.20240914094516-d89dac594db0 ) require ( diff --git a/go.sum b/go.sum index 8c92712b..b99b144e 100644 --- a/go.sum +++ b/go.sum @@ -117,8 +117,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.20.1-0.20240913182028-ff4126b5d04d h1:7YIv1Lmtbpx0cPzyELwGcnhLW+a1EFDRnMW/WGeZ73E= -maunium.net/go/mautrix v0.20.1-0.20240913182028-ff4126b5d04d/go.mod h1:amzKPIZVO7v1piD2JhKG1RvGZoV+5wEZfoHaEXOjjqA= +maunium.net/go/mautrix v0.20.1-0.20240914094516-d89dac594db0 h1:fTX1P8TPv+oUqHGu08jj6FYH+Q/fC9jtmvkXcAw+KTo= +maunium.net/go/mautrix v0.20.1-0.20240914094516-d89dac594db0/go.mod h1:amzKPIZVO7v1piD2JhKG1RvGZoV+5wEZfoHaEXOjjqA= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/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 ab8fbd2b..985a32c1 100644 --- a/pkg/connector/backfill.go +++ b/pkg/connector/backfill.go @@ -115,7 +115,7 @@ func (t *TelegramClient) takeoutDialogs(ctx context.Context, takeoutID int64) er return fmt.Errorf("failed to handle dialogs: %w", err) } - portalKey := ids.MakePortalKey(dialogs.GetDialogs()[len(dialogs.GetDialogs())-1].GetPeer(), t.userLogin.ID) + portalKey := t.makePortalKeyFromPeer(dialogs.GetDialogs()[len(dialogs.GetDialogs())-1].GetPeer()) if t.userLogin.Metadata.(*UserLoginMetadata).TakeoutDialogCrawlCursor == portalKey.ID { t.userLogin.Metadata.(*UserLoginMetadata).TakeoutDialogCrawlDone = true diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 52c32f00..25a28a1c 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -148,26 +148,26 @@ func NewTelegramClient(ctx context.Context, tc *TelegramConnector, login *bridge return client.onMessageEdit(ctx, update) }) dispatcher.OnUserTyping(func(ctx context.Context, e tg.Entities, update *tg.UpdateUserTyping) error { - return client.handleTyping(ids.PeerTypeUser.AsPortalKey(update.UserID, login.ID), update.UserID, update.Action) + return client.handleTyping(client.makePortalKeyFromID(ids.PeerTypeUser, update.UserID), update.UserID, update.Action) }) dispatcher.OnChatUserTyping(func(ctx context.Context, e tg.Entities, update *tg.UpdateChatUserTyping) error { if update.FromID.TypeID() != tg.PeerUserTypeID { log.Warn().Str("from_id_type", update.FromID.TypeName()).Msg("unsupported from_id type") return nil } - return client.handleTyping(ids.PeerTypeChat.AsPortalKey(update.ChatID, login.ID), update.FromID.(*tg.PeerUser).UserID, update.Action) + return client.handleTyping(client.makePortalKeyFromID(ids.PeerTypeChat, update.ChatID), update.FromID.(*tg.PeerUser).UserID, update.Action) }) dispatcher.OnChannelUserTyping(func(ctx context.Context, e tg.Entities, update *tg.UpdateChannelUserTyping) error { - return client.handleTyping(ids.PeerTypeChannel.AsPortalKey(update.ChannelID, ""), update.FromID.(*tg.PeerUser).UserID, update.Action) + return client.handleTyping(client.makePortalKeyFromID(ids.PeerTypeChannel, update.ChannelID), update.FromID.(*tg.PeerUser).UserID, update.Action) }) dispatcher.OnReadHistoryOutbox(func(ctx context.Context, e tg.Entities, update *tg.UpdateReadHistoryOutbox) error { return client.updateReadReceipt(update) }) dispatcher.OnReadHistoryInbox(func(ctx context.Context, e tg.Entities, update *tg.UpdateReadHistoryInbox) error { - return client.onOwnReadReceipt(ids.MakePortalKey(update.Peer, login.ID), update.MaxID) + return client.onOwnReadReceipt(client.makePortalKeyFromPeer(update.Peer), update.MaxID) }) dispatcher.OnReadChannelInbox(func(ctx context.Context, e tg.Entities, update *tg.UpdateReadChannelInbox) error { - return client.onOwnReadReceipt(ids.PeerTypeChannel.AsPortalKey(update.ChannelID, ""), update.MaxID) + return client.onOwnReadReceipt(client.makePortalKeyFromID(ids.PeerTypeChannel, update.ChannelID), update.MaxID) }) client.ScopedStore = tc.Store.GetScopedStore(telegramUserID) @@ -180,7 +180,7 @@ func NewTelegramClient(ctx context.Context, tc *TelegramConnector, login *bridge LogContext: func(c zerolog.Context) zerolog.Context { return c.Str("update", "channel_too_long").Int64("channel_id", channelID) }, - PortalKey: ids.PeerTypeChannel.AsPortalKey(channelID, login.ID), + PortalKey: client.makePortalKeyFromID(ids.PeerTypeChannel, channelID), }, CheckNeedsBackfillFunc: func(ctx context.Context, latestMessage *database.Message) (bool, error) { return true, nil }, }) @@ -264,14 +264,14 @@ func NewTelegramClient(ctx context.Context, tc *TelegramConnector, login *bridge log.Err(err).Msg("error parsing channel ID") return url } - portalKey = ids.PeerTypeChannel.AsPortalKey(chatID, "") + portalKey = client.makePortalKeyFromID(ids.PeerTypeChannel, chatID) } else { userID, err := strconv.ParseInt(submatches[1], 10, 64) if err != nil { log.Err(err).Msg("error parsing user ID") return url } - portalKey = ids.PeerTypeUser.AsPortalKey(userID, login.ID) + portalKey = client.makePortalKeyFromID(ids.PeerTypeUser, userID) } portal, err := tc.Bridge.DB.Portal.GetByKey(ctx, portalKey) diff --git a/pkg/connector/directdownload.go b/pkg/connector/directdownload.go index 6363d275..eb0b740f 100644 --- a/pkg/connector/directdownload.go +++ b/pkg/connector/directdownload.go @@ -38,7 +38,7 @@ func (tc *TelegramConnector) Download(ctx context.Context, mediaID networkid.Med return nil, fmt.Errorf("failed to get user login: %w", err) } - logins, err := tc.Bridge.GetUserLoginsInPortal(ctx, ids.PeerTypeChannel.AsPortalKey(info.ChatID, "")) + logins, err := tc.Bridge.GetUserLoginsInPortal(ctx, ids.PeerTypeChannel.InternalAsPortalKey(info.ChatID, "")) if err != nil { return nil, err } else if len(logins) == 0 { diff --git a/pkg/connector/ids.go b/pkg/connector/ids.go new file mode 100644 index 00000000..ae25f881 --- /dev/null +++ b/pkg/connector/ids.go @@ -0,0 +1,24 @@ +package connector + +import ( + "github.com/gotd/td/tg" + "maunium.net/go/mautrix/bridgev2/networkid" + + "go.mau.fi/mautrix-telegram/pkg/connector/ids" +) + +func (t *TelegramClient) makePortalKeyFromPeer(peer tg.PeerClass) networkid.PortalKey { + key := ids.InternalMakePortalKey(peer, t.loginID) + if t.main.Bridge.Config.SplitPortals { + key.Receiver = t.userLogin.ID + } + return key +} + +func (t *TelegramClient) makePortalKeyFromID(peerType ids.PeerType, chatID int64) networkid.PortalKey { + key := peerType.InternalAsPortalKey(chatID, t.loginID) + if t.main.Bridge.Config.SplitPortals { + key.Receiver = t.userLogin.ID + } + return key +} diff --git a/pkg/connector/ids/ids.go b/pkg/connector/ids/ids.go index e20c4e39..505e5f97 100644 --- a/pkg/connector/ids/ids.go +++ b/pkg/connector/ids/ids.go @@ -119,7 +119,7 @@ func (pt PeerType) AsByte() byte { } } -func (pt PeerType) AsPortalKey(chatID int64, receiver networkid.UserLoginID) networkid.PortalKey { +func (pt PeerType) InternalAsPortalKey(chatID int64, receiver networkid.UserLoginID) networkid.PortalKey { portalKey := networkid.PortalKey{ ID: networkid.PortalID(fmt.Sprintf("%s:%d", pt, chatID)), } @@ -142,7 +142,7 @@ func GetChatID(peer tg.PeerClass) int64 { } } -func MakePortalKey(peer tg.PeerClass, receiver networkid.UserLoginID) networkid.PortalKey { +func InternalMakePortalKey(peer tg.PeerClass, receiver networkid.UserLoginID) networkid.PortalKey { switch v := peer.(type) { case *tg.PeerUser: return networkid.PortalKey{ diff --git a/pkg/connector/reactions.go b/pkg/connector/reactions.go index 0eb1b64a..f9fad240 100644 --- a/pkg/connector/reactions.go +++ b/pkg/connector/reactions.go @@ -48,7 +48,7 @@ func (t *TelegramClient) computeReactionsList(ctx context.Context, msg *tg.Messa // return // TODO should calls to this be limited? - } else if peer, err := t.inputPeerForPortalID(ctx, ids.MakePortalKey(msg.PeerID, t.loginID).ID); err != nil { + } else if peer, err := t.inputPeerForPortalID(ctx, t.makePortalKeyFromPeer(msg.PeerID).ID); err != nil { return nil, false, nil, fmt.Errorf("failed to get input peer: %w", err) } else { reactions, err := APICallWithUpdates(ctx, t, func() (*tg.MessagesMessageReactionsList, error) { diff --git a/pkg/connector/startnewchat.go b/pkg/connector/startnewchat.go index 13d09850..bc87caf6 100644 --- a/pkg/connector/startnewchat.go +++ b/pkg/connector/startnewchat.go @@ -27,7 +27,7 @@ func (t *TelegramClient) getResolveIdentifierResponseForUser(ctx context.Context UserID: networkUserID, UserInfo: userInfo, Chat: &bridgev2.CreateChatResponse{ - PortalKey: ids.PeerTypeUser.AsPortalKey(user.GetID(), t.loginID), + PortalKey: t.makePortalKeyFromID(ids.PeerTypeUser, user.GetID()), }, }, nil } @@ -38,7 +38,7 @@ func (t *TelegramClient) getResolveIdentifierResponseForUserID(ctx context.Conte resp = &bridgev2.ResolveIdentifierResponse{ UserID: networkUserID, Chat: &bridgev2.CreateChatResponse{ - PortalKey: ids.PeerTypeUser.AsPortalKey(userID, t.loginID), + PortalKey: t.makePortalKeyFromID(ids.PeerTypeUser, userID), }, } resp.Ghost, err = t.main.Bridge.GetExistingGhostByID(ctx, networkUserID) @@ -232,7 +232,7 @@ func (t *TelegramClient) CreateGroup(ctx context.Context, name string, users ... return nil, fmt.Errorf("unexpected chat type: %T", chats[0]) } else { return &bridgev2.CreateChatResponse{ - PortalKey: ids.PeerTypeChat.AsPortalKey(chat.ID, t.loginID), + PortalKey: t.makePortalKeyFromID(ids.PeerTypeChat, chat.ID), }, nil } } diff --git a/pkg/connector/sync.go b/pkg/connector/sync.go index eac7bed7..f4506acd 100644 --- a/pkg/connector/sync.go +++ b/pkg/connector/sync.go @@ -66,7 +66,7 @@ func (t *TelegramClient) handleDialogs(ctx context.Context, dialogs tg.ModifiedM Logger() log.Debug().Msg("Syncing dialog") - portalKey := ids.MakePortalKey(dialog.GetPeer(), t.loginID) + portalKey := t.makePortalKeyFromPeer(dialog.GetPeer()) portal, err := t.main.Bridge.GetPortalByKey(ctx, portalKey) if err != nil { log.Err(err).Msg("Failed to get portal") diff --git a/pkg/connector/telegram.go b/pkg/connector/telegram.go index a378c793..035551de 100644 --- a/pkg/connector/telegram.go +++ b/pkg/connector/telegram.go @@ -58,7 +58,7 @@ func (t *TelegramClient) onUpdateNewMessage(ctx context.Context, update IGetMess Stringer("peer_id", msg.PeerID) }, Sender: sender, - PortalKey: ids.MakePortalKey(msg.PeerID, t.loginID), + PortalKey: t.makePortalKeyFromPeer(msg.PeerID), CreatePortal: true, Timestamp: time.Unix(int64(msg.Date), 0), }, @@ -72,7 +72,7 @@ func (t *TelegramClient) onUpdateNewMessage(ctx context.Context, update IGetMess chatInfoChange := simplevent.ChatInfoChange{ EventMeta: simplevent.EventMeta{ Type: bridgev2.RemoteEventChatInfoChange, - PortalKey: ids.MakePortalKey(msg.PeerID, t.loginID), + PortalKey: t.makePortalKeyFromPeer(msg.PeerID), Sender: sender, Timestamp: time.Unix(int64(msg.Date), 0), LogContext: func(c zerolog.Context) zerolog.Context { @@ -292,7 +292,7 @@ func (t *TelegramClient) onDeleteMessages(ctx context.Context, channelID int64, // TODO can deletes happen across rooms? portalKey = parts[0].Room } else { - portalKey = ids.MakePortalKey(&tg.PeerChannel{ChannelID: channelID}, t.loginID) + portalKey = t.makePortalKeyFromPeer(&tg.PeerChannel{ChannelID: channelID}) } t.main.Bridge.QueueRemoteEvent(t.userLogin, &simplevent.MessageRemove{ EventMeta: simplevent.EventMeta{ @@ -406,7 +406,7 @@ func (t *TelegramClient) onMessageEdit(ctx context.Context, update IGetMessage) Int("message_id", msg.ID) }, Sender: sender, - PortalKey: ids.MakePortalKey(msg.PeerID, t.loginID), + PortalKey: t.makePortalKeyFromPeer(msg.PeerID), Timestamp: time.Unix(int64(msg.EditDate), 0), }, ID: ids.GetMessageIDFromMessage(msg), @@ -466,7 +466,7 @@ func (t *TelegramClient) updateReadReceipt(update *tg.UpdateReadHistoryOutbox) e t.main.Bridge.QueueRemoteEvent(t.userLogin, &simplevent.Receipt{ EventMeta: simplevent.EventMeta{ Type: bridgev2.RemoteEventReadReceipt, - PortalKey: ids.MakePortalKey(update.Peer, t.loginID), + PortalKey: t.makePortalKeyFromPeer(update.Peer), Sender: bridgev2.EventSender{ SenderLogin: ids.MakeUserLoginID(user.UserID), Sender: ids.MakeUserID(user.UserID),