You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Arman Safikhani f37751283a
Merge pull request #100 from aluvare/master
11 months ago
examples Update sendText.go 2 years ago
.all-contributorsrc docs: update .all-contributorsrc [skip ci] 2 years ago
.gitignore Stable work, added some examples 5 years ago
LICENSE Initial commit 5 years ago Update 11 months ago
go.mod Add go modules, link against libc++ instead of stdc++ 2 years ago
methods.go Update to 1.7.1 2 years ago
tdlib.go fix typo 1 year ago
types.go fix MessageReplyInfo unmarshaller 2 years ago


All Contributors

Golang Telegram TdLib JSON bindings


Telegram Tdlib is a complete library for creating telegram clients, it also has a simple tdjson ready-to-use library to ease
the integration with different programming languages and platforms.

go-tdlib is a complete tdlib-tdjson binding package to help you create your own Telegram clients.

NOTE: basic tdjson-golang binding is inspired from this package: go-tdjson

All the classes and functions declared in Tdlib TypeLanguage schema
file have been exported using the autogenerate tool tl-parser.
So you can use every single type and method in Tdlib.

Key features:

  • Autogenerated golang structs and methods out of tdlib .tl schema
  • Custom event receivers defined by user (e.g. get only text messages from a specific user)
  • Supports all tdjson functions: Send(), Execute(), Receive(), Destroy(), SetFilePath(), SetLogVerbosityLevel()
  • Supports all tdlib functions and types


First of all you need to clone the Tdlib repo and build it:

git clone --depth 1
cd td
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build . -- -j5
make install

# -j5 refers to number of your cpu cores + 1 for multi-threaded build.

If hit any build errors, refer to Tdlib build instructions
I'm using static linking against tdlib so it won't require to build the whole tdlib source files.


You can use the prebuilt tdlib image and Go image of your liking:

FROM golang:1.15-alpine AS golang

COPY --from=wcsiu/tdlib:1.7-alpine /usr/local/include/td /usr/local/include/td
COPY --from=wcsiu/tdlib:1.7-alpine /usr/local/lib/libtd* /usr/local/lib/
COPY --from=wcsiu/tdlib:1.7-alpine /usr/lib/libssl.a /usr/local/lib/libssl.a
COPY --from=wcsiu/tdlib:1.7-alpine /usr/lib/libcrypto.a /usr/local/lib/libcrypto.a
COPY --from=wcsiu/tdlib:1.7-alpine /lib/libz.a /usr/local/lib/libz.a
RUN apk add build-base


COPY . .

RUN go build --ldflags "-extldflags '-static -L/usr/local/lib -ltdjson_static -ltdjson_private -ltdclient -ltdcore -ltdactor -ltddb -ltdsqlite -ltdnet -ltdutils -ldl -lm -lssl -lcrypto -lstdc++ -lz'" -o /tmp/getChats getChats.go

COPY --from=golang /tmp/getChats /getChats
ENTRYPOINT [ "/getChats" ]
$ docker build -fDockerfile -ttelegram-client .


Here is a simple example for authorization and fetching updates:

package main

import (


func main() {

	// 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
			_, 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
			_, 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
			_, 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")

	// Main loop
	rawUpdates := client.GetRawUpdatesChannel(100)
        for update := range rawUpdates {
		// Show all updates


More examples can be found on examples folder


Thanks goes to these wonderful people (emoji key):

Aleksandr Zelenin




Ahmadreza Zibaei




Ruben Vermeersch


Alexander Shelepenok

💻 🚧

Karim Nahas

💻 🚧 🐛

Wachiu Siu

💡 🐛 📖





This project follows the all-contributors specification. Contributions of any kind welcome!