Stable work, added some examples

This commit is contained in:
Arman 2018-04-05 12:47:29 +04:30
parent e6e7359fec
commit d393342cb0
8 changed files with 21224 additions and 247 deletions

5
.gitignore vendored
View File

@ -22,3 +22,8 @@
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
.glide/
tdlib-db
tdlib-files
errors.txt

View File

@ -0,0 +1,68 @@
package main
import (
"fmt"
"tg-tdlib/tdlib"
)
func main() {
tdlib.SetLogVerbosityLevel(1)
tdlib.SetFilePath("./errors.txt")
// Create new instance of client
client := tdlib.NewClient(tdlib.Config{
APIID: "187786",
APIHash: "e782045df67ba48e441ccb105da8fc85",
SystemLanguageCode: "en",
DeviceModel: "Server",
SystemVersion: "1.0.0",
ApplicationVersion: "1.0.0",
UseMessageDatabase: true,
UseFileDatabase: true,
UseChatInfoDatabase: true,
UseTestDataCenter: false,
DatabaseDirectory: "./tdlib-db",
FileDirectory: "./tdlib-files",
IgnoreFileNames: false,
})
for {
currentState, _ := client.Authorize()
if currentState.GetAuthorizationStateEnum() == tdlib.AuthorizationStateWaitPhoneNumberType {
fmt.Print("Enter phone: ")
var number string
fmt.Scanln(&number)
_, err := client.SendPhoneNumber(number)
if err != nil {
fmt.Printf("Error sending phone number: %v", err)
}
} else if currentState.GetAuthorizationStateEnum() == tdlib.AuthorizationStateWaitCodeType {
fmt.Print("Enter code: ")
var code string
fmt.Scanln(&code)
_, err := client.SendAuthCode(code)
if err != nil {
fmt.Printf("Error sending auth code : %v", err)
}
} else if currentState.GetAuthorizationStateEnum() == tdlib.AuthorizationStateWaitPasswordType {
fmt.Print("Enter Password: ")
var password string
fmt.Scanln(&password)
_, err := client.SendAuthPassword(password)
if err != nil {
fmt.Printf("Error sending auth password: %v", err)
}
} else if currentState.GetAuthorizationStateEnum() == tdlib.AuthorizationStateReadyType {
fmt.Println("Authorization Ready! Let's rock")
break
}
}
// Main loop
for update := range client.RawUpdates {
// Show all updates
fmt.Println(update.Data)
fmt.Print("\n\n")
}
}

View File

@ -0,0 +1,78 @@
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"tg-tdlib/tdlib"
"time"
)
func main() {
tdlib.SetLogVerbosityLevel(1)
tdlib.SetFilePath("./errors.txt")
// Create new instance of client
client := tdlib.NewClient(tdlib.Config{
APIID: "187786",
APIHash: "e782045df67ba48e441ccb105da8fc85",
SystemLanguageCode: "en",
DeviceModel: "Server",
SystemVersion: "1.0.0",
ApplicationVersion: "1.0.0",
UseMessageDatabase: true,
UseFileDatabase: true,
UseChatInfoDatabase: true,
UseTestDataCenter: false,
DatabaseDirectory: "./tdlib-db",
FileDirectory: "./tdlib-files",
IgnoreFileNames: false,
})
// Handle Ctrl+C
ch := make(chan os.Signal, 2)
signal.Notify(ch, os.Interrupt, syscall.SIGTERM)
go func() {
<-ch
client.DestroyInstance()
os.Exit(1)
}()
// Wait while we get AuthorizationReady!
currentState, _ := client.Authorize()
for ; currentState.GetAuthorizationStateEnum() != tdlib.AuthorizationStateReadyType; currentState, _ = client.Authorize() {
time.Sleep(300 * time.Millisecond)
}
go func() {
// Create an filter function which will be used to filter out unwanted tdlib messages
eventFilter := func(msg *tdlib.TdMessage) bool {
updateMsg := (*msg).(*tdlib.UpdateNewMessage)
// For example, we want incomming messages from user with below id:
if updateMsg.Message.SenderUserID == 41507975 {
return true
}
return false
}
// Here we can add a receiver to retreive any message type we want
// We like to get UpdateNewMessage events and with a specific FilterFunc
receiver := client.AddEventReceiver(&tdlib.UpdateNewMessage{}, eventFilter, 5)
for newMsg := range receiver.Chan {
fmt.Println(newMsg)
updateMsg := (newMsg).(*tdlib.UpdateNewMessage)
// We assume the message content is simple text: (should be more sophosticated for general use)
msgText := updateMsg.Message.Content.(*tdlib.MessageText)
fmt.Println("MsgText: ", msgText.Text)
fmt.Print("\n\n")
}
}()
// Just fetch updates so the Updates channel won't cause the main routine to get blocked
for update := range client.RawUpdates {
_ = update
}
}

View File

@ -0,0 +1,78 @@
package main
import (
"fmt"
"math"
"os"
"os/signal"
"syscall"
"tg-tdlib/tdlib"
"time"
)
var allChats []tdlib.Chat
func main() {
tdlib.SetLogVerbosityLevel(1)
tdlib.SetFilePath("./errors.txt")
// Create new instance of client
client := tdlib.NewClient(tdlib.Config{
APIID: "187786",
APIHash: "e782045df67ba48e441ccb105da8fc85",
SystemLanguageCode: "en",
DeviceModel: "Server",
SystemVersion: "1.0.0",
ApplicationVersion: "1.0.0",
UseMessageDatabase: true,
UseFileDatabase: true,
UseChatInfoDatabase: true,
UseTestDataCenter: false,
DatabaseDirectory: "./tdlib-db",
FileDirectory: "./tdlib-files",
IgnoreFileNames: false,
})
// Handle Ctrl+C , Gracefully exit and shutdown tdlib
ch := make(chan os.Signal, 2)
signal.Notify(ch, os.Interrupt, syscall.SIGTERM)
go func() {
<-ch
client.DestroyInstance()
os.Exit(1)
}()
// Wait while we get AuthorizationReady!
currentState, _ := client.Authorize()
for ; currentState.GetAuthorizationStateEnum() != tdlib.AuthorizationStateReadyType; currentState, _ = client.Authorize() {
time.Sleep(300 * time.Millisecond)
}
// Main loop
go func() {
// Just fetch updates so the Updates channel won't cause the main routine to get blocked
for update := range client.RawUpdates {
_ = update
}
}()
// Get chats
// see https://stackoverflow.com/questions/37782348/how-to-use-getchats-in-tdlib
chats, err := client.GetChats(math.MaxInt64, 0, 100)
allChats = make([]tdlib.Chat, 0, 1)
if err != nil {
fmt.Printf("Error getting chats, err: %v\n", err)
} else {
for _, chatID := range chats.ChatIDs {
chat, err := client.GetChat(chatID)
if err == nil {
fmt.Println("Got chat info: ", *chat)
allChats = append(allChats, *chat)
}
}
}
for {
time.Sleep(1 * time.Second)
}
}

138
main.go
View File

@ -1,22 +1,23 @@
package main
import (
"encoding/json"
"fmt"
"math"
"os"
"os/signal"
"syscall"
"tg-tdlib/tdjson"
"tg-tdlib/types"
"tg-tdlib/tdlib"
"time"
)
var allChats []tdlib.Chat
func main() {
tdjson.SetLogVerbosityLevel(1)
tdjson.SetFilePath("./errors.txt")
tdlib.SetLogVerbosityLevel(1)
tdlib.SetFilePath("./errors.txt")
// Create new instance of client
client := tdjson.NewClient(tdjson.TdlibConfig{
client := tdlib.NewClient(tdlib.Config{
APIID: "187786",
APIHash: "e782045df67ba48e441ccb105da8fc85",
SystemLanguageCode: "en",
@ -27,8 +28,8 @@ func main() {
UseFileDatabase: true,
UseChatInfoDatabase: true,
UseTestDataCenter: false,
DatabaseDirectory: "tdlib-db",
FileDirectory: "tdlib-files",
DatabaseDirectory: "./tdlib-db",
FileDirectory: "./tdlib-files",
IgnoreFileNames: false,
})
@ -37,93 +38,88 @@ func main() {
signal.Notify(ch, os.Interrupt, syscall.SIGTERM)
go func() {
<-ch
client.Destroy()
client.DestroyInstance()
os.Exit(1)
}()
for {
currentState, _ := client.Authorize()
if currentState == tdjson.AuthorizationStateWaitPhoneNumber {
if currentState.GetAuthorizationStateEnum() == tdlib.AuthorizationStateWaitPhoneNumberType {
fmt.Print("Enter phone: ")
var number string
fmt.Scanln(&number)
client.SendPhoneNumber(number)
} else if currentState == tdjson.AuthorizationStateWaitCode {
_, err := client.SendPhoneNumber(number)
if err != nil {
fmt.Printf("Error sending phone number: %v", err)
}
} else if currentState.GetAuthorizationStateEnum() == tdlib.AuthorizationStateWaitCodeType {
fmt.Print("Enter code: ")
var code string
fmt.Scanln(&code)
client.SendAuthCode(code)
} else if currentState == tdjson.AuthorizationStateWaitPassword {
_, err := client.SendAuthCode(code)
if err != nil {
fmt.Printf("Error sending auth code : %v", err)
}
} else if currentState.GetAuthorizationStateEnum() == tdlib.AuthorizationStateWaitPasswordType {
fmt.Print("Enter Password: ")
var password string
fmt.Scanln(&password)
client.SendAuthPassword(password)
} else if currentState == tdjson.AuthorizationStateReady {
_, err := client.SendAuthPassword(password)
if err != nil {
fmt.Printf("Error sending auth password: %v", err)
}
} else if currentState.GetAuthorizationStateEnum() == tdlib.AuthorizationStateReadyType {
fmt.Println("Authorization Ready! Let's rock")
break
}
}
go func() {
time.Sleep(1 * time.Second)
for {
res, err := client.SendAndCatch(tdjson.Update{
"@type": "getAuthorizationState",
})
fmt.Println(res)
fmt.Println(err)
result, err := client.SendAndCatchBytes(tdjson.Update{
"@type": "getChats",
"offset_order": 9223372036854775807,
"offset_chat_id": 0,
"limit": 200,
})
if err != nil {
panic("Fuck")
eventFilter := func(msg *tdlib.TdMessage) bool {
updateMsg := (*msg).(*tdlib.UpdateNewMessage)
if updateMsg.Message.SenderUserID == 41507975 {
return true
}
chatIDs := types.Chats{}
json.Unmarshal(result, &chatIDs)
var chats []types.Chat
chats = make([]types.Chat, 0, 1)
for _, chatID := range chatIDs.ChatIDs {
result, err = client.SendAndCatchBytes(tdjson.Update{
"@type": "getChat",
"chat_id": chatID,
})
var update tdjson.Update
json.Unmarshal(result, &update)
fmt.Println(update)
var chat types.Chat
json.Unmarshal(result, &chat)
chats = append(chats, chat)
}
result, err = client.SendAndCatchBytes(tdjson.Update{
"@type": "getChatMember",
"chat_id": -1001178287687,
"user_id": 41507975,
})
var update tdjson.Update
json.Unmarshal(result, &update)
fmt.Println(update)
time.Sleep(3 * time.Second)
return false
}
receiver := client.AddEventReceiver(&tdlib.UpdateNewMessage{}, eventFilter, 5)
for newMsg := range receiver.Chan {
fmt.Println(newMsg)
updateMsg := (newMsg).(*tdlib.UpdateNewMessage)
msgText := updateMsg.Message.Content.(*tdlib.MessageText)
fmt.Println("MsgText: ", msgText.Text)
fmt.Print("\n\n")
}
}()
// Main loop
for update := range client.Updates {
// Show all updates
fmt.Println(update)
fmt.Print("\n\n")
go func() {
for update := range client.RawUpdates {
// Show all updates
// fmt.Println(update.Data)
// fmt.Print("\n\n")
_ = update
}
}()
// see https://stackoverflow.com/questions/37782348/how-to-use-getchats-in-tdlib
chats, err := client.GetChats(math.MaxInt64, 0, 100)
allChats = make([]tdlib.Chat, 0, 1)
if err != nil {
fmt.Printf("Error getting chats, err: %v\n", err)
} else {
for _, chatID := range chats.ChatIDs {
chat, err := client.GetChat(chatID)
if err == nil {
fmt.Println("Got chat info: ", *chat)
allChats = append(allChats, *chat)
}
}
}
for {
time.Sleep(1 * time.Second)
}
}

6425
tdlib/methods.go Executable file

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
package tdjson
package tdlib
//#cgo linux CFLAGS: -I/usr/local/include
//#cgo windows CFLAGS: -IC:/src/td -IC:/src/td/build
@ -12,41 +12,43 @@ import "C"
import (
"encoding/json"
"errors"
"fmt"
"math/rand"
"sync"
"time"
"unsafe"
)
// Update is used to unmarshal recieved json strings into
type Update = map[string]interface{}
// UpdateData alias for use in UpdateMsg
type UpdateData map[string]interface{}
// AuthorizationState is used to indicate Authorization State
type AuthorizationState uint8
// UpdateMsg is used to unmarshal recieved json strings into
type UpdateMsg struct {
Data UpdateData
Raw []byte
}
// AuthorizationStates
const (
AuthorizationStateClosed = iota
AuthorizationStateClosing
AuthorizationStateLoggingOut
AuthorizationStateReady
AuthorizationStateWaitCode
AuthorizationStateWaitEncryptionKey
AuthorizationStateWaitPassword
AuthorizationStateWaitPhoneNumber
AuthorizationStateWaitTdlibParameters
)
// EventFilterFunc used to filter out unwanted messages in receiver channels
type EventFilterFunc func(msg *TdMessage) bool
// EventReceiver used to retreive updates from tdlib to user
type EventReceiver struct {
Instance TdMessage
Chan chan TdMessage
FilterFunc EventFilterFunc
}
// Client is the Telegram TdLib client
type Client struct {
Client unsafe.Pointer
Updates chan Update
waiters sync.Map
rawWaiters sync.Map
Client unsafe.Pointer
RawUpdates chan UpdateMsg
receivers []EventReceiver
waiters sync.Map
receiverLock *sync.Mutex
}
// TdlibConfig holds tdlibParameters
type TdlibConfig struct {
// Config holds tdlibParameters
type Config struct {
APIID string // Application identifier for Telegram API access, which can be obtained at https://my.telegram.org --- must be non-empty..
APIHash string // Application identifier hash for Telegram API access, which can be obtained at https://my.telegram.org --- must be non-empty..
SystemLanguageCode string // IETF language tag of the user's operating system language; must be non-empty.
@ -67,56 +69,69 @@ type TdlibConfig struct {
// NewClient Creates a new instance of TDLib.
// Has two public fields:
// Client itself and Updates channel
func NewClient(config TdlibConfig) *Client {
// Client itself and RawUpdates channel
func NewClient(config Config) *Client {
// Seed rand with time
rand.Seed(time.Now().UnixNano())
client := Client{Client: C.td_json_client_create()}
client.Updates = make(chan Update, 100)
client.RawUpdates = make(chan UpdateMsg, 100)
client.receivers = make([]EventReceiver, 0, 1)
client.receiverLock = &sync.Mutex{}
go func() {
for {
// get update
updateBytes := client.Receive(10)
var update Update
json.Unmarshal(updateBytes, &update)
var updateData UpdateData
json.Unmarshal(updateBytes, &updateData)
// does new update has @extra field?
if extra, hasExtra := update["@extra"].(string); hasExtra {
if extra, hasExtra := updateData["@extra"].(string); hasExtra {
// trying to load update with this salt
if waiter, found := client.waiters.Load(extra); found {
// found? send it to waiter channel
waiter.(chan Update) <- update
waiter.(chan UpdateMsg) <- UpdateMsg{Data: updateData, Raw: updateBytes}
// trying to prevent memory leak
close(waiter.(chan Update))
}
// trying to load update with this salt
if rawWaiter, found := client.rawWaiters.Load(extra); found {
// found? send it to rawWaiter channel
rawWaiter.(chan []byte) <- updateBytes
// trying to prevent memory leak
close(rawWaiter.(chan []byte))
close(waiter.(chan UpdateMsg))
}
} else {
// does new updates has @type field?
if _, hasType := update["@type"]; hasType {
if msgType, hasType := updateData["@type"]; hasType {
// if yes, send it in main channel
client.Updates <- update
client.RawUpdates <- UpdateMsg{Data: updateData, Raw: updateBytes}
client.receiverLock.Lock()
for _, receiver := range client.receivers {
if msgType == receiver.Instance.MessageType() {
err := json.Unmarshal(updateBytes, &receiver.Instance)
if err != nil {
fmt.Printf("Error unmarhaling to type %v", err)
}
if receiver.FilterFunc(&receiver.Instance) {
receiver.Chan <- receiver.Instance
}
}
}
client.receiverLock.Unlock()
}
}
}
}()
client.Send(Update{
client.Send(UpdateData{
"@type": "setTdlibParameters",
"parameters": Update{
"parameters": UpdateData{
"@type": "tdlibParameters",
"use_test_dc": config.UseTestDataCenter,
"database_directory": config.DatabaseDirectory,
"files_directory": config.FileDirectory,
"use_file_database": config.UseFileDatabase,
"use_chat_info_database": config.UseChatInfoDatabase,
"use_message_database": config.UseMessageDatabase,
"use_secret_chats": config.UseSecretChats,
"api_id": config.APIID,
"api_hash": config.APIHash,
"system_language_code": config.SystemLanguageCode,
@ -124,64 +139,79 @@ func NewClient(config TdlibConfig) *Client {
"system_version": config.SystemVersion,
"application_version": config.ApplicationVersion,
"enable_storage_optimizer": config.EnableStorageOptimizer,
"ignore_file_names": config.IgnoreFileNames,
},
})
return &client
}
// Destroy Destroys the TDLib client instance.
// AddEventReceiver adds a new receiver to be subscribed in receiver channels
func (client *Client) AddEventReceiver(msgInstance TdMessage, filterFunc EventFilterFunc, channelCapacity int) EventReceiver {
receiver := EventReceiver{
Instance: msgInstance,
Chan: make(chan TdMessage, channelCapacity),
FilterFunc: filterFunc,
}
client.receiverLock.Lock()
defer client.receiverLock.Unlock()
client.receivers = append(client.receivers, receiver)
return receiver
}
// DestroyInstance Destroys the TDLib client instance.
// After this is called the client instance shouldn't be used anymore.
func (c *Client) Destroy() {
C.td_json_client_destroy(c.Client)
func (client *Client) DestroyInstance() {
C.td_json_client_destroy(client.Client)
}
// Send Sends request to the TDLib client.
// You can provide string or Update.
func (c *Client) Send(jsonQuery interface{}) {
// You can provide string or UpdateData.
func (client *Client) Send(jsonQuery interface{}) {
var query *C.char
switch jsonQuery.(type) {
case string:
query = C.CString(jsonQuery.(string))
case Update:
jsonBytes, _ := json.Marshal(jsonQuery.(Update))
case UpdateData:
jsonBytes, _ := json.Marshal(jsonQuery.(UpdateData))
fmt.Println("Sending: ", string(jsonBytes))
query = C.CString(string(jsonBytes))
}
defer C.free(unsafe.Pointer(query))
C.td_json_client_send(c.Client, query)
C.td_json_client_send(client.Client, query)
}
// Receive Receives incoming updates and request responses from the TDLib client.
// You can provide string or Update.
func (c *Client) Receive(timeout float64) []byte {
result := C.td_json_client_receive(c.Client, C.double(timeout))
// You can provide string or UpdateData.
func (client *Client) Receive(timeout float64) []byte {
result := C.td_json_client_receive(client.Client, C.double(timeout))
// var update Update
// json.Unmarshal([]byte(C.GoString(result)), &update)
return []byte(C.GoString(result))
}
// Execute Synchronously executes TDLib request.
// Only a few requests can be executed synchronously.
func (c *Client) Execute(jsonQuery interface{}) Update {
func (client *Client) Execute(jsonQuery interface{}) UpdateMsg {
var query *C.char
switch jsonQuery.(type) {
case string:
query = C.CString(jsonQuery.(string))
case Update:
jsonBytes, _ := json.Marshal(jsonQuery.(Update))
case UpdateData:
jsonBytes, _ := json.Marshal(jsonQuery.(UpdateData))
query = C.CString(string(jsonBytes))
}
defer C.free(unsafe.Pointer(query))
result := C.td_json_client_execute(c.Client, query)
result := C.td_json_client_execute(client.Client, query)
var update Update
var update UpdateData
json.Unmarshal([]byte(C.GoString(result)), &update)
return update
return UpdateMsg{Data: update, Raw: []byte(C.GoString(result))}
}
// SetFilePath Sets the path to the file to where the internal TDLib log will be written.
@ -201,16 +231,16 @@ func SetLogVerbosityLevel(level int) {
}
// SendAndCatch Sends request to the TDLib client and catches the result in updates channel.
// You can provide string or Update.
func (c *Client) SendAndCatch(jsonQuery interface{}) (Update, error) {
var update Update
// You can provide string or UpdateData.
func (client *Client) SendAndCatch(jsonQuery interface{}) (UpdateMsg, error) {
var update UpdateData
switch jsonQuery.(type) {
case string:
// unmarshal JSON into map, we don't have @extra field, if user don't set it
json.Unmarshal([]byte(jsonQuery.(string)), &update)
case Update:
update = jsonQuery.(Update)
case UpdateData:
update = jsonQuery.(UpdateData)
}
// letters for generating random string
@ -227,11 +257,11 @@ func (c *Client) SendAndCatch(jsonQuery interface{}) (Update, error) {
update["@extra"] = randomString
// create waiter chan and save it in Waiters
waiter := make(chan Update, 1)
c.waiters.Store(randomString, waiter)
waiter := make(chan UpdateMsg, 1)
client.waiters.Store(randomString, waiter)
// send it through already implemented method
c.Send(update)
client.Send(update)
select {
// wait response from main loop in NewClient()
@ -239,138 +269,62 @@ func (c *Client) SendAndCatch(jsonQuery interface{}) (Update, error) {
return response, nil
// or timeout
case <-time.After(10 * time.Second):
c.waiters.Delete(randomString)
return Update{}, errors.New("timeout")
}
}
// SendAndCatchBytes Sends request to the TDLib client and catches the result (bytes) in updates channel.
// You can provide string or Update.
func (c *Client) SendAndCatchBytes(jsonQuery interface{}) ([]byte, error) {
var update Update
switch jsonQuery.(type) {
case string:
// unmarshal JSON into map, we don't have @extra field, if user don't set it
json.Unmarshal([]byte(jsonQuery.(string)), &update)
case Update:
update = jsonQuery.(Update)
}
// letters for generating random string
letterBytes := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
// generate random string for @extra field
b := make([]byte, 32)
for i := range b {
b[i] = letterBytes[rand.Intn(len(letterBytes))]
}
randomString := string(b)
// set @extra field
update["@extra"] = randomString
// create waiter chan and save it in Waiters
waiter := make(chan []byte, 1)
c.rawWaiters.Store(randomString, waiter)
// send it through already implemented method
c.Send(update)
select {
// wait response from main loop in NewClient()
case response := <-waiter:
return response, nil
// or timeout
case <-time.After(10 * time.Second):
c.rawWaiters.Delete(randomString)
return nil, errors.New("timeout")
}
}
// GetAuthorizationState returns authorization state
func (c *Client) GetAuthorizationState() (AuthorizationState, error) {
res, err := c.SendAndCatch(Update{
"@type": "getAuthorizationState",
})
switch res["@type"].(string) {
case "authorizationStateClosed":
return AuthorizationStateClosed, err
case "authorizationStateClosing":
return AuthorizationStateClosing, err
case "authorizationStateLoggingOut":
return AuthorizationStateLoggingOut, err
case "authorizationStateReady":
return AuthorizationStateReady, err
case "authorizationStateWaitCode":
return AuthorizationStateWaitCode, err
case "authorizationStateWaitEncryptionKey":
return AuthorizationStateWaitEncryptionKey, err
case "authorizationStateWaitPassword":
return AuthorizationStateWaitPassword, err
case "authorizationStateWaitPhoneNumber":
return AuthorizationStateWaitPhoneNumber, err
case "authorizationStateWaitTdlibParameters":
return AuthorizationStateWaitTdlibParameters, err
default:
return AuthorizationStateClosed, err
client.waiters.Delete(randomString)
return UpdateMsg{}, errors.New("timeout")
}
}
// Authorize is used to authorize the users
func (c *Client) Authorize() (AuthorizationState, error) {
if state, _ := c.GetAuthorizationState(); state == AuthorizationStateWaitEncryptionKey {
_, err := c.SendAndCatch(Update{
"@type": "checkDatabaseEncryptionKey",
})
func (client *Client) Authorize() (AuthorizationState, error) {
state, err := client.GetAuthorizationState()
if err != nil {
return nil, err
}
if err != nil {
return AuthorizationStateClosed, err
if state.GetAuthorizationStateEnum() == AuthorizationStateWaitEncryptionKeyType {
ok, err := client.CheckDatabaseEncryptionKey(nil)
if ok == nil || err != nil {
return nil, err
}
}
return c.GetAuthorizationState()
authState, err := client.GetAuthorizationState()
return authState, err
}
// SendPhoneNumber sends phone number to tdlib
func (c *Client) SendPhoneNumber(phoneNumber string) (AuthorizationState, error) {
_, err := c.SendAndCatch(Update{
"@type": "setAuthenticationPhoneNumber",
"phone_number": phoneNumber,
})
func (client *Client) SendPhoneNumber(phoneNumber string) (AuthorizationState, error) {
_, err := client.SetAuthenticationPhoneNumber(phoneNumber, false, false)
if err != nil {
return AuthorizationStateClosed, err
return nil, err
}
return c.GetAuthorizationState()
authState, err := client.GetAuthorizationState()
return authState, err
}
// SendAuthCode sends auth code to tdlib
func (c *Client) SendAuthCode(code string) (AuthorizationState, error) {
_, err := c.SendAndCatch(Update{
"@type": "checkAuthenticationCode",
"code": code,
})
func (client *Client) SendAuthCode(code string) (AuthorizationState, error) {
_, err := client.CheckAuthenticationCode(code, "", "")
if err != nil {
return AuthorizationStateClosed, err
return nil, err
}
return c.GetAuthorizationState()
authState, err := client.GetAuthorizationState()
return authState, err
}
// SendAuthPassword sends two-step verification password (user defined)to tdlib
func (c *Client) SendAuthPassword(password string) (AuthorizationState, error) {
_, err := c.SendAndCatch(Update{
"@type": "checkAuthenticationPassword",
"password": password,
})
func (client *Client) SendAuthPassword(password string) (AuthorizationState, error) {
_, err := client.CheckAuthenticationPassword(password)
if err != nil {
return AuthorizationStateClosed, err
return nil, err
}
return c.GetAuthorizationState()
authState, err := client.GetAuthorizationState()
return authState, err
}

14373
tdlib/types.go Executable file

File diff suppressed because it is too large Load Diff