ids: add support for split portals

This commit is contained in:
Tulir Asokan
2024-09-14 12:50:31 +03:00
parent 7ed3c46f23
commit ff48398430
11 changed files with 49 additions and 25 deletions
+1 -1
View File
@@ -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 (
+2 -2
View File
@@ -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=
+1 -1
View File
@@ -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
+8 -8
View File
@@ -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)
+1 -1
View File
@@ -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 {
+24
View File
@@ -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
}
+2 -2
View File
@@ -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{
+1 -1
View File
@@ -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) {
+3 -3
View File
@@ -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
}
}
+1 -1
View File
@@ -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")
+5 -5
View File
@@ -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),