From 62efa2e7b90ead95f4e73d711646fd7e171b64d6 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 15 Mar 2026 12:48:20 +0200 Subject: [PATCH] userinfo: add support for getting user info via InputUserFromMessage --- go.mod | 2 +- go.sum | 4 +-- pkg/connector/userinfo.go | 53 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 28a7acd4..18e2419c 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,7 @@ require ( golang.org/x/sync v0.19.0 golang.org/x/tools v0.42.0 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.4-0.20260306185818-df24fb96e2e5 + maunium.net/go/mautrix v0.26.4-0.20260315103917-1953538cb6e3 rsc.io/qr v0.2.0 ) diff --git a/go.sum b/go.sum index 205b9b65..8818599b 100644 --- a/go.sum +++ b/go.sum @@ -243,7 +243,7 @@ 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.26.4-0.20260306185818-df24fb96e2e5 h1:hIzC9BvmDOlCEAF/TxcB29LBJOD6FIaqldxvn0+wz2k= -maunium.net/go/mautrix v0.26.4-0.20260306185818-df24fb96e2e5/go.mod h1:lJvXCZya2dGT2KW7LUO7Ucna7Ohs6hl2+7v8Ji6R3iM= +maunium.net/go/mautrix v0.26.4-0.20260315103917-1953538cb6e3 h1:z+FW+/RgSFITgb1P028tYtFjdOs/KKB6wx08Galg89w= +maunium.net/go/mautrix v0.26.4-0.20260315103917-1953538cb6e3/go.mod h1:lJvXCZya2dGT2KW7LUO7Ucna7Ohs6hl2+7v8Ji6R3iM= rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY= rsc.io/qr v0.2.0/go.mod h1:IF+uZjkb9fqyeF/4tlBoynqmQxUoPfWEKh921coOuXs= diff --git a/pkg/connector/userinfo.go b/pkg/connector/userinfo.go index 6a761106..13a78e8f 100644 --- a/pkg/connector/userinfo.go +++ b/pkg/connector/userinfo.go @@ -2,13 +2,17 @@ package connector import ( "context" + "errors" "fmt" "slices" "strings" + "github.com/rs/zerolog" "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/simplevent" "go.mau.fi/mautrix-telegram/pkg/connector/ids" + "go.mau.fi/mautrix-telegram/pkg/connector/store" "go.mau.fi/mautrix-telegram/pkg/connector/util" "go.mau.fi/mautrix-telegram/pkg/gotd/tg" ) @@ -36,9 +40,50 @@ func (t *TelegramClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) } } -func (t *TelegramClient) getInputUser(ctx context.Context, id int64) (*tg.InputUser, error) { +func (t *TelegramClient) getInputUserFromContext(ctx context.Context, id int64) (*tg.InputUserFromMessage, error) { + msg, ok := bridgev2.GetRemoteEventFromContext(ctx).(*simplevent.Message[*tg.Message]) + if !ok { + return nil, nil + } + fromUser, ok := msg.Data.FromID.(*tg.PeerUser) + if !ok || fromUser.UserID != id { + return nil, nil + } + var inputPeer tg.InputPeerClass + switch typedChat := msg.Data.PeerID.(type) { + case *tg.PeerUser: + // We don't have the user's access hash + return nil, nil + case *tg.PeerChat: + inputPeer = &tg.InputPeerChat{ChatID: typedChat.ChatID} + case *tg.PeerChannel: + accessHash, err := t.ScopedStore.GetAccessHash(ctx, ids.PeerTypeChannel, typedChat.ChannelID) + if err != nil { + return nil, err + } + inputPeer = &tg.InputPeerChannel{ChannelID: typedChat.ChannelID, AccessHash: accessHash} + } + return &tg.InputUserFromMessage{ + Peer: inputPeer, + MsgID: msg.Data.ID, + UserID: fromUser.UserID, + }, nil +} + +func (t *TelegramClient) getInputUser(ctx context.Context, id int64) (tg.InputUserClass, error) { accessHash, err := t.ScopedStore.GetAccessHash(ctx, ids.PeerTypeUser, id) - if err != nil { + if errors.Is(err, store.ErrNoAccessHash) { + fromMsg, fromMsgErr := t.getInputUserFromContext(ctx, id) + if fromMsgErr != nil { + return nil, fmt.Errorf("%w, also failed to get from message: %w", err, fromMsgErr) + } else if fromMsg == nil { + return nil, err + } + zerolog.Ctx(ctx).Trace(). + Any("input_peer", fromMsg). + Msg("Using InputUserFromMessage as access hash wasn't found") + return fromMsg, nil + } else if err != nil { return nil, fmt.Errorf("failed to get access hash for user %d: %w", id, err) } return &tg.InputUser{UserID: id, AccessHash: accessHash}, nil @@ -46,7 +91,9 @@ func (t *TelegramClient) getInputUser(ctx context.Context, id int64) (*tg.InputU func (t *TelegramClient) getInputPeerUser(ctx context.Context, id int64) (*tg.InputPeerUser, error) { accessHash, err := t.ScopedStore.GetAccessHash(ctx, ids.PeerTypeUser, id) - if err != nil { + if errors.Is(err, store.ErrNoAccessHash) { + return nil, err + } else if err != nil { return nil, fmt.Errorf("failed to get access hash for user %d: %w", id, err) } return &tg.InputPeerUser{UserID: id, AccessHash: accessHash}, nil