go-tdlib
May 9, 2026 ยท View on GitHub
Go wrapper for TDLib (Telegram Database Library) with full support of the TDLib. Current supported version of TDLib corresponds to the commit hash 49b3bcb, updated on 2026-05-08
TDLib installation
Use TDLib build instructions with checkmarked Install built TDLib to /usr/local instead of placing the files to td/tdlib. Don't forget to checkout a supported commit (see above).
Custom TDLib Path
If you have TDLib installed in a custom location, use environment variables to specify the include and library paths:
CGO_CFLAGS=-I/path/to/tdlib/include \
CGO_LDFLAGS="-Wl,-rpath,/path/to/tdlib/lib -L/path/to/tdlib/lib -ltdjson" \
go build ...
Windows
Build with environment variables (use full paths):
CGO_ENABLED=1
CGO_CFLAGS=-IC:/path/to/tdlib/build/tdlib/include
CGO_LDFLAGS=-LC:/path/to/tdlib/build/tdlib/bin -ltdjson
Example for PowerShell:
$env:CGO_ENABLED=1; $env:CGO_CFLAGS="-IC:/td/tdlib/include"; $env:CGO_LDFLAGS="-LC:/td/tdlib/bin -ltdjson"; go build -trimpath -ldflags="-s -w" -o demo.exe .\cmd\demo.go
To run, put the .dll from C:/td/tdlib/bin to the directory with the compiled .exe.
Usage
Client
Register an application to obtain an api_id and api_hash
package main
import (
"context"
"github.com/zelenin/go-tdlib/client"
"log"
"os"
"os/signal"
"path/filepath"
"syscall"
)
const (
apiId = 00000
apiHash = "8pu9yg32qkuukj83ozaqo5zzjwhkxhnk"
)
func main() {
tdlibParameters := &client.SetTdlibParametersRequest{
UseTestDc: false,
DatabaseDirectory: filepath.Join(".tdlib", "database"),
FilesDirectory: filepath.Join(".tdlib", "files"),
UseFileDatabase: true,
UseChatInfoDatabase: true,
UseMessageDatabase: true,
UseSecretChats: false,
ApiId: apiId,
ApiHash: apiHash,
SystemLanguageCode: "en",
DeviceModel: "Server",
SystemVersion: "1.0.0",
ApplicationVersion: "1.0.0",
}
// client authorizer
authorizer := client.ClientAuthorizer(tdlibParameters)
go client.CliInteractor(authorizer)
// or bot authorizer
// botToken := "000000000:gsVCGG5YbikxYHC7bP5vRvmBqJ7Xz6vG6td"
// authorizer := client.BotAuthorizer(tdlibParameters, botToken)
_, err := client.SetLogVerbosityLevel(&client.SetLogVerbosityLevelRequest{
NewVerbosityLevel: 1,
})
if err != nil {
log.Fatalf("SetLogVerbosityLevel error: %s", err)
}
tdlibClient, err := client.NewClient(authorizer)
if err != nil {
log.Fatalf("NewClient error: %s", err)
}
versionOption, err := client.GetOption(&client.GetOptionRequest{
Name: "version",
})
if err != nil {
log.Fatalf("GetOption error: %s", err)
}
commitOption, err := client.GetOption(&client.GetOptionRequest{
Name: "commit_hash",
})
if err != nil {
log.Fatalf("GetOption error: %s", err)
}
log.Printf("TDLib version: %s (commit: %s)", versionOption.(*client.OptionValueString).Value, commitOption.(*client.OptionValueString).Value)
if commitOption.(*client.OptionValueString).Value != client.TDLIB_VERSION {
log.Printf("TDLib version supported by the library (%s) is not the same as TDLib version (%s)", client.TDLIB_VERSION, commitOption.(*client.OptionValueString).Value)
}
me, err := tdlibClient.GetMe(context.Background())
if err != nil {
log.Fatalf("GetMe error: %s", err)
}
log.Printf("Me: %s %s", me.FirstName, me.LastName)
ch := make(chan os.Signal, 2)
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
<-ch
tdlibClient.Close(context.Background())
os.Exit(1)
}
QR Code login
package main
import (
"github.com/skip2/go-qrcode"
"log"
"path/filepath"
"github.com/zelenin/go-tdlib/client"
)
const (
apiId = 00000
apiHash = "8pu9yg32qkuukj83ozaqo5zzjwhkxhnk"
)
func main() {
tdlibParameters := &client.SetTdlibParametersRequest{
UseTestDc: false,
DatabaseDirectory: filepath.Join(".tdlib", "database"),
FilesDirectory: filepath.Join(".tdlib", "files"),
UseFileDatabase: true,
UseChatInfoDatabase: true,
UseMessageDatabase: true,
UseSecretChats: false,
ApiId: apiId,
ApiHash: apiHash,
SystemLanguageCode: "en",
DeviceModel: "Server",
SystemVersion: "1.0.0",
ApplicationVersion: "1.0.0",
}
// client authorizer
authorizer := client.QrAuthorizer(tdlibParameters, func(link string) error {
return qrcode.WriteFile(link, qrcode.Medium, 256, "qr.png")
})
tdlibClient, err := client.NewClient(authorizer)
if err != nil {
log.Fatalf("NewClient error: %s", err)
}
}
Receive updates
resHandCallback := func(result client.Type) {
log.Printf("%#v", result.GetType())
}
tdlibClient, err := client.NewClient(authorizer, client.WithResultHandler(client.NewCallbackResultHandler(resHandCallback)))
if err != nil {
log.Fatalf("NewClient error: %s", err)
}
Proxy support
proxy := client.WithProxy(&client.AddProxyRequest{
Server: "1.1.1.1",
Port: 1080,
Enable: true,
Type: &client.ProxyTypeSocks5{
Username: "username",
Password: "password",
},
})
tdlibClient, err := client.NewClient(authorizer, proxy)
Example
cd example
docker build --network host --progress plain --tag tdlib-test .
docker run --rm -it -e "API_ID=00000" -e "API_HASH=abcdef0123456789" tdlib-test ash
./app
Notes
- WIP. Library API can be changed in the future
- The package includes a .tl-parser and generated json-schema for creating libraries in other languages
Author
Aleksandr Zelenin, e-mail: aleksandr@zelenin.me