package telegram import ( "context" "errors" "fmt" "path/filepath" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/pj_errors" "penahub.gitlab.yandexcloud.net/backend/tdlib/client" "sync" "time" ) type TelegramClient struct { repo *dal.DAL TgClients map[int64]*client.Client WaitingClients map[string]WaitingClient mu sync.Mutex } type WaitingClient struct { TdLibClient *client.Client PreviousReq AuthTgUserReq Authorizer *client.ClientAuthorizer } // todo come back saved tg accs to slice for check this status func NewTelegramClient(ctx context.Context, repo *dal.DAL) (*TelegramClient, error) { tgClient := &TelegramClient{ repo: repo, TgClients: make(map[int64]*client.Client), WaitingClients: make(map[string]WaitingClient), } allTgAccounts, err := repo.TgRepo.GetAllTgAccounts(ctx) if err != nil { if errors.Is(err, pj_errors.ErrNotFound) { return tgClient, nil } return nil, err } for _, account := range allTgAccounts { if account.Status == model.ActiveTg { authorizer := client.ClientAuthorizerr() authorizer.TdlibParameters <- &client.SetTdlibParametersRequest{ UseTestDc: false, DatabaseDirectory: filepath.Join(".tdlib", "database"), FilesDirectory: filepath.Join(".tdlib", "files"), UseFileDatabase: false, UseChatInfoDatabase: false, UseMessageDatabase: false, UseSecretChats: false, ApiId: account.ApiID, ApiHash: account.ApiHash, SystemLanguageCode: "en", DeviceModel: "Server", SystemVersion: "1.0.0", ApplicationVersion: "1.0.0", } _, err := client.SetLogVerbosityLevel(&client.SetLogVerbosityLevelRequest{ NewVerbosityLevel: 1, }) if err != nil { return nil, err } var tdlibClient *client.Client var goErr error go func() { tdlibClient, goErr = client.NewClient(authorizer) if goErr != nil { fmt.Println("new client failed", err) return } fmt.Println("i am down") }() if goErr != nil { return nil, goErr } for { state, ok := <-authorizer.State if !ok { break } fmt.Println("currnet state:", state) switch state.AuthorizationStateType() { case client.TypeAuthorizationStateWaitPhoneNumber: authorizer.PhoneNumber <- account.PhoneNumber case client.TypeAuthorizationStateWaitCode: err := tgClient.repo.TgRepo.UpdateStatusTg(ctx, account.ID, model.InactiveTg) if err != nil { return nil, err } case client.TypeAuthorizationStateLoggingOut, client.TypeAuthorizationStateClosing, client.TypeAuthorizationStateClosed: err := tgClient.repo.TgRepo.UpdateStatusTg(ctx, account.ID, model.InactiveTg) if err != nil { return nil, err } case client.TypeAuthorizationStateReady: // костыль так как в либе тож костыль стоит пока там ьд обновиться будет ниловый всегда клиент time.Sleep(3 * time.Second) me, err := tdlibClient.GetMe() if err != nil { return nil, err } fmt.Printf("Me: %s %s [%v]", me.FirstName, me.LastName, me.Usernames) tgClient.mu.Lock() tgClient.TgClients[account.ID] = tdlibClient tgClient.mu.Unlock() break case client.TypeAuthorizationStateWaitPassword: authorizer.Password <- account.Password } } } } return tgClient, nil } type AuthTgUserReq struct { ApiID int32 `json:"api_id"` ApiHash string `json:"api_hash"` PhoneNumber string `json:"phone_number"` Password string `json:"password"` } func (tg *TelegramClient) AddedToMap(data WaitingClient, id string) { fmt.Println("AddedToMap") tg.mu.Lock() defer tg.mu.Unlock() tg.WaitingClients[id] = data } func (tg *TelegramClient) GetFromMap(id string) (WaitingClient, bool) { fmt.Println("GetFromMap") tg.mu.Lock() defer tg.mu.Unlock() if data, ok := tg.WaitingClients[id]; ok { delete(tg.WaitingClients, id) return data, true } return WaitingClient{}, false } func (tg *TelegramClient) SaveTgAccount(ctx context.Context, tdLibClient *client.Client, account model.TgAccount) (int64, error) { tg.mu.Lock() defer tg.mu.Unlock() id, err := tg.repo.TgRepo.CreateTgAccount(ctx, account) if err != nil { return 0, err } tg.TgClients[id] = tdLibClient return id, nil } func (tg *TelegramClient) CreateChannel(channelName string, botID int64) (string, error) { return "", nil }