From 39fd6967a98abd22c7c78e5117c4288a363d90fb Mon Sep 17 00:00:00 2001 From: cynicalwork <160782862+cynicalwork@users.noreply.github.com> Date: Wed, 21 Feb 2024 20:20:25 +0000 Subject: [PATCH] Add support for logging in using tdesktop session data (TDATA) (#58) * Added TDATA session support * Added example to authenticate with TDATA --- examples/auth-using-tdata/main.go | 54 ++++++++++++++++++++++++++++++ sessionMaker/sessionConstructor.go | 37 ++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 examples/auth-using-tdata/main.go diff --git a/examples/auth-using-tdata/main.go b/examples/auth-using-tdata/main.go new file mode 100644 index 0000000..d6590a5 --- /dev/null +++ b/examples/auth-using-tdata/main.go @@ -0,0 +1,54 @@ +package main + +import ( + "fmt" + "log" + "os" + "path/filepath" + + "github.com/celestix/gotgproto" + "github.com/celestix/gotgproto/sessionMaker" + "github.com/gotd/td/session/tdesktop" +) + +func main() { + home, err := os.UserHomeDir() + if err != nil { + log.Fatalln(err) + } + telegramDir := filepath.Join(home, ".local/share/TelegramDesktop") + accounts, err := tdesktop.Read(telegramDir, nil) + if err != nil { + log.Fatalln(err) + } + + // Type of client to login to, can be of 2 types: + // 1.) Bot (Fill BotToken in this case) + // 2.) User (Fill Phone in this case) + clientType := gotgproto.ClientType{ + Phone: "PHONE_NUMBER_HERE", + } + + client, err := gotgproto.NewClient( + // Get AppID from https://my.telegram.org/apps + 123456, + // Get ApiHash from https://my.telegram.org/apps + "API_HASH_HERE", + // ClientType, as we defined above + clientType, + // Optional parameters of client + &gotgproto.ClientOpts{ + // There can be up to 3 tdesktop.Account, we consider here there is + // at least a single on, you can loop through them with + // for _, account := range accounts {// your code} + Session: sessionMaker.TdataSession(accounts[0]).Name("tdata"), + }, + ) + if err != nil { + log.Fatalln("failed to start client:", err) + } + + fmt.Printf("client (@%s) has been started...\n", client.Self.Username) + + client.Idle() +} diff --git a/sessionMaker/sessionConstructor.go b/sessionMaker/sessionConstructor.go index de71f5a..36be8be 100644 --- a/sessionMaker/sessionConstructor.go +++ b/sessionMaker/sessionConstructor.go @@ -1,12 +1,14 @@ package sessionMaker import ( + "context" "encoding/json" "errors" "github.com/celestix/gotgproto/functions" "github.com/celestix/gotgproto/storage" "github.com/gotd/td/session" + "github.com/gotd/td/session/tdesktop" ) type SessionConstructor interface { @@ -111,3 +113,38 @@ func (s *StringSessionConstructor) loadSession() (string, []byte, error) { } return s.name, sd.Data, err } + +type TdataSessionConstructor struct { + Account tdesktop.Account + name string +} + +func TdataSession(account tdesktop.Account) *TdataSessionConstructor { + return &TdataSessionConstructor{Account: account} +} + +func (s *TdataSessionConstructor) Name(name string) *TdataSessionConstructor { + s.name = name + return s +} + +func (s *TdataSessionConstructor) loadSession() (string, []byte, error) { + sd, err := session.TDesktopSession(s.Account) + if err != nil { + return s.name, nil, err + } + ctx := context.Background() + var ( + gotdstorage = new(session.StorageMemory) + loader = session.Loader{Storage: gotdstorage} + ) + // Save decoded Telegram Desktop session as gotd session. + if err := loader.Save(ctx, sd); err != nil { + return s.name, nil, err + } + data, err := json.Marshal(jsonData{ + Version: storage.LatestVersion, + Data: *sd, + }) + return s.name, data, err +}