From 8480c8aa685cc4db9d28e78727e4589840785ef6 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Thu, 3 Oct 2024 15:05:21 -0600 Subject: [PATCH] client: make GetUserInfo work for channels Signed-off-by: Sumner Evans --- pkg/connector/api.go | 2 +- pkg/connector/client.go | 51 ++++++++++++++++++++++++++++------- pkg/connector/startnewchat.go | 4 +++ pkg/connector/telegram.go | 19 ++++++------- 4 files changed, 57 insertions(+), 19 deletions(-) diff --git a/pkg/connector/api.go b/pkg/connector/api.go index 3caa029c..2026600b 100644 --- a/pkg/connector/api.go +++ b/pkg/connector/api.go @@ -37,7 +37,7 @@ func handleUserUpdates[U hasUserUpdates](ctx context.Context, t *TelegramClient, func handleChatUpdates[U hasChatUpdates](ctx context.Context, t *TelegramClient, resp hasChatUpdates) error { for _, c := range resp.GetChats() { if channel, ok := c.(*tg.Channel); ok { - if err := t.updateChannel(ctx, channel); err != nil { + if _, err := t.updateChannel(ctx, channel); err != nil { return err } } diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 842ef305..d0ca6b39 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -457,18 +457,51 @@ func (t *TelegramClient) getSingleUser(ctx context.Context, id int64) (tg.UserCl } } -// TODO make work for channel peers (necessary for forward backfill) -func (t *TelegramClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) (*bridgev2.UserInfo, error) { - if peerType, id, err := ids.ParseUserID(ghost.ID); err != nil { +func (t *TelegramClient) getSingleChannel(ctx context.Context, id int64) (*tg.Channel, error) { + accessHash, err := t.ScopedStore.GetAccessHash(ctx, ids.PeerTypeChannel, id) + if err != nil { return nil, err - } else if peerType != ids.PeerTypeUser { - return nil, fmt.Errorf("unexpected peer type: %s", peerType) - } else if user, err := t.getSingleUser(ctx, id); err != nil { - return nil, fmt.Errorf("failed to get user %d: %w", id, err) - } else if user.TypeID() != tg.UserTypeID { + } + chats, err := APICallWithOnlyChatUpdates(ctx, t, func() (tg.MessagesChatsClass, error) { + return t.client.API().ChannelsGetChannels(ctx, []tg.InputChannelClass{ + &tg.InputChannel{ChannelID: id, AccessHash: accessHash}, + }) + }) + if err != nil { return nil, err + } else if len(chats.GetChats()) == 0 { + return nil, fmt.Errorf("failed to get channel info for channel %d", id) + } else if channel, ok := chats.GetChats()[0].(*tg.Channel); !ok { + return nil, fmt.Errorf("unexpected channel type %T", chats.GetChats()[id]) } else { - return t.updateGhost(ctx, id, user.(*tg.User)) + return channel, nil + } +} + +func (t *TelegramClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) (*bridgev2.UserInfo, error) { + peerType, id, err := ids.ParseUserID(ghost.ID) + if err != nil { + return nil, err + } + switch peerType { + case ids.PeerTypeUser: + if user, err := t.getSingleUser(ctx, id); err != nil { + return nil, fmt.Errorf("failed to get user %d: %w", id, err) + } else if user.TypeID() != tg.UserTypeID { + return nil, err + } else { + return t.updateGhost(ctx, id, user.(*tg.User)) + } + case ids.PeerTypeChannel: + if channel, err := t.getSingleChannel(ctx, id); err != nil { + return nil, fmt.Errorf("failed to get channel %d: %w", id, err) + } else if channel.TypeID() != tg.ChannelTypeID { + return nil, err + } else { + return t.updateChannel(ctx, channel) + } + default: + return nil, fmt.Errorf("unexpected peer type: %s", peerType) } } diff --git a/pkg/connector/startnewchat.go b/pkg/connector/startnewchat.go index eb00bdd8..ce39f13e 100644 --- a/pkg/connector/startnewchat.go +++ b/pkg/connector/startnewchat.go @@ -46,6 +46,10 @@ func (t *TelegramClient) getResolveIdentifierResponseForUserID(ctx context.Conte // Try to fetch the user from Telegram if user, err := t.getSingleUser(ctx, userID); err != nil { return nil, fmt.Errorf("failed to get user with ID %d: %w", userID, err) + } else if user.TypeID() != tg.UserTypeID { + return nil, err + } else if _, err := t.updateGhost(ctx, userID, user.(*tg.User)); err != nil { + return nil, fmt.Errorf("failed to update ghost: %w", err) } else { return t.getResolveIdentifierResponseForUser(ctx, user) } diff --git a/pkg/connector/telegram.go b/pkg/connector/telegram.go index 031f8da8..8b0f8835 100644 --- a/pkg/connector/telegram.go +++ b/pkg/connector/telegram.go @@ -438,19 +438,19 @@ func (t *TelegramClient) updateGhost(ctx context.Context, userID int64, user *tg return userInfo, t.maybeUpdateRemoteProfile(ctx, ghost, user) } -func (t *TelegramClient) updateChannel(ctx context.Context, channel *tg.Channel) error { +func (t *TelegramClient) updateChannel(ctx context.Context, channel *tg.Channel) (*bridgev2.UserInfo, error) { if err := t.ScopedStore.SetAccessHash(ctx, ids.PeerTypeChannel, channel.ID, channel.AccessHash); err != nil { - return err + return nil, err } if !channel.Broadcast { - return nil + return nil, nil } // Update the channel ghost if this is a broadcast channel. ghost, err := t.main.Bridge.GetGhostByID(ctx, ids.MakeChannelUserID(channel.ID)) if err != nil { - return err + return nil, err } var avatar *bridgev2.Avatar @@ -467,11 +467,11 @@ func (t *TelegramClient) updateChannel(ctx context.Context, channel *tg.Channel) if username, set := channel.GetUsername(); set { err := t.ScopedStore.SetUsername(ctx, ids.PeerTypeChannel, channel.ID, username) if err != nil { - return err + return nil, err } } - ghost.UpdateInfo(ctx, &bridgev2.UserInfo{ + userInfo := &bridgev2.UserInfo{ Name: &channel.Title, Avatar: avatar, ExtraUpdates: func(ctx context.Context, g *bridgev2.Ghost) bool { @@ -479,8 +479,9 @@ func (t *TelegramClient) updateChannel(ctx context.Context, channel *tg.Channel) g.Metadata.(*GhostMetadata).IsChannel = true return updated }, - }) - return nil + } + ghost.UpdateInfo(ctx, userInfo) + return userInfo, nil } func (t *TelegramClient) onEntityUpdate(ctx context.Context, e tg.Entities) error { @@ -490,7 +491,7 @@ func (t *TelegramClient) onEntityUpdate(ctx context.Context, e tg.Entities) erro } } for _, channel := range e.Channels { - if err := t.updateChannel(ctx, channel); err != nil { + if _, err := t.updateChannel(ctx, channel); err != nil { return err } }