Telegram client, in Go. (MTProto API)
See the codeTelegram MTProto API client in Go for users and bots.
Before using this library, read How To Not Get Banned guide.
Due to limitations of pkg.go.dev, documentation for tg package is not shown, but there is hosted version.
The gotd itself is a pretty low-level library, and you may want to use higher level libraries instead:
go get github.com/gotd/td
package main
import (
"context"
"github.com/gotd/td/telegram"
)
func main() {
// https://core.telegram.org/api/obtaining_api_id
client := telegram.NewClient(appID, appHash, telegram.Options{})
if err := client.Run(context.Background(), func(ctx context.Context) error {
// It is only valid to use client while this function is not returned
// and ctx is not cancelled.
api := client.API()
// Now you can invoke MTProto RPC requests by calling the API.
// ...
// Return to close client connection and free up resources.
return nil
}); err != nil {
panic(err)
}
// Client is closed.
}
See examples for more info.
./cmd/gotdgen (based on gotd/tl parser) with embedded official documentationThe goal of this project is to implement a stable, performant and safe client for Telegram in pure Go while having a simple and convenient API and a feature parity with TDLib.
This project is fully non-commercial and not affiliated with any commercial organization (including Telegram LLC).
See examples directory.
Also take a look at
You can use td/telegram/auth.Flow to simplify user authentications.
codePrompt := func(ctx context.Context, sentCode *tg.AuthSentCode) (string, error) {
// NB: Use "golang.org/x/crypto/ssh/terminal" to prompt password.
fmt.Print("Enter code: ")
code, err := bufio.NewReader(os.Stdin).ReadString('\n')
if err != nil {
return "", err
}
return strings.TrimSpace(code), nil
}
// This will setup and perform authentication flow.
// If account does not require 2FA password, use telegram.CodeOnlyAuth
// instead of telegram.ConstantAuth.
if err := auth.NewFlow(
auth.Constant(phone, password, auth.CodeAuthenticatorFunc(codePrompt)),
auth.SendCodeOptions{},
).Run(ctx, client.Auth()); err != nil {
panic(err)
}
Use bot token from @BotFather.
if err := client.Auth().Bot(ctx, "token:12345"); err != nil {
panic(err)
}
You can use the generated tg.Client that allows calling any MTProto method
directly.
// Grab these from https://my.telegram.org/apps.
// Never share it or hardcode!
client := telegram.NewClient(appID, appHash, telegram.Options{})
client.Run(ctx, func(ctx context.Context) error {
// Grab token from @BotFather.
if _, err := client.Auth().Bot(ctx, "token:12345"); err != nil {
return err
}
state, err := client.API().UpdatesGetState(ctx)
if err != nil {
return err
}
// Got state: &{Pts:197 Qts:0 Date:1606855030 Seq:1 UnreadCount:106}
// This will close client and cleanup resources.
return nil
})
You can invoke methods using MTProto JSON format with InvokeJSON.
This accepts JSON with @type field in MTProto format (e.g., "messages.sendMessage")
and returns JSON response in MTProto format.
client := telegram.NewClient(appID, appHash, telegram.Options{})
client.Run(ctx, func(ctx context.Context) error {
if _, err := client.Auth().Bot(ctx, "token:12345"); err != nil {
return err
}
// Send message using MTProto JSON format
jsonReq := `{
"@type": "messages.sendMessage",
"peer": {"@type": "inputPeerUser", "user_id": 123456789, "access_hash": 0},
"message": "Hello from MTProto JSON!",
"random_id": 0
}`
jsonResp, err := client.API().InvokeJSON(ctx, jsonReq, true)
if err != nil {
return err
}
// jsonResp contains MTProto JSON response with snake_case field names
// {"@type":"messages.sentMessage",...} or error response
return nil
})
The code output of gotdgen contains references to TL types, examples, URL to
official documentation and extracted comments from it.
For example, the auth.Authorization type in tg/tl_auth_authorization_gen.go:
// AuthAuthorizationClass represents auth.Authorization generic type.
//
// See https://core.telegram.org/type/auth.Authorization for reference.
//
// Example:
// g, err := DecodeAuthAuthorization(buf)
// if err != nil {
// panic(err)
// }
// switch v := g.(type) {
// case *AuthAuthorization: // auth.authorization#cd050916
// case *AuthAuthorizationSignUpRequired: // auth.authorizationSignUpRequired#44747e9a
// default: panic(v)
// }
type AuthAuthorizationClass interface {
bin.Encoder
bin.Decoder
construct() AuthAuthorizationClass
}
Also, the corresponding auth.signIn method:
// AuthSignIn invokes method auth.signIn#bcd51581 returning error if any.
// Signs in a user with a validated phone number.
//
// See https://core.telegram.org/method/auth.signIn for reference.
func (c *Client) AuthSignIn(ctx context.Context, request *AuthSignInRequest) (AuthAuthorizationClass, error) {}
The generated constructors contain detailed official documentation, including links:
// FoldersDeleteFolderRequest represents TL type `folders.deleteFolder#1c295881`.
// Delete a peer folder¹
//
// Links:
// 1) https://core.telegram.org/api/folders#peer-folders
//
// See https://core.telegram.org/method/folders.deleteFolder for reference.
type FoldersDeleteFolderRequest struct {
// Peer folder ID, for more info click here¹
//
// Links:
// 1) https://core.telegram.org/api/folders#peer-folders
FolderID int
}
Huge thanks to all contributors. Dealing with a project of this scale alone is impossible.
Special thanks:
The MTProto protocol description is hosted by Telegram.
Most important parts for client implementations:
Current implementation mostly conforms to security guidelines, but no formal security audit were performed.
Drop a comment here to add your project.
MIT License
Created by Aleksandr (ernado) Razumov
2020
Overall
Maintained
Code review
Go module
Latest release
Releases this year
679 followers · starred Feb 2026
849 followers · starred Feb 2021
108 followers · starred Feb 2022
264 followers · starred Apr 2024
Telegram client, in Go. (MTProto API)
See the codeTelegram MTProto API client in Go for users and bots.
Before using this library, read How To Not Get Banned guide.
Due to limitations of pkg.go.dev, documentation for tg package is not shown, but there is hosted version.
The gotd itself is a pretty low-level library, and you may want to use higher level libraries instead:
go get github.com/gotd/td
package main
import (
"context"
"github.com/gotd/td/telegram"
)
func main() {
// https://core.telegram.org/api/obtaining_api_id
client := telegram.NewClient(appID, appHash, telegram.Options{})
if err := client.Run(context.Background(), func(ctx context.Context) error {
// It is only valid to use client while this function is not returned
// and ctx is not cancelled.
api := client.API()
// Now you can invoke MTProto RPC requests by calling the API.
// ...
// Return to close client connection and free up resources.
return nil
}); err != nil {
panic(err)
}
// Client is closed.
}
See examples for more info.
./cmd/gotdgen (based on gotd/tl parser) with embedded official documentationThe goal of this project is to implement a stable, performant and safe client for Telegram in pure Go while having a simple and convenient API and a feature parity with TDLib.
This project is fully non-commercial and not affiliated with any commercial organization (including Telegram LLC).
See examples directory.
Also take a look at
You can use td/telegram/auth.Flow to simplify user authentications.
codePrompt := func(ctx context.Context, sentCode *tg.AuthSentCode) (string, error) {
// NB: Use "golang.org/x/crypto/ssh/terminal" to prompt password.
fmt.Print("Enter code: ")
code, err := bufio.NewReader(os.Stdin).ReadString('\n')
if err != nil {
return "", err
}
return strings.TrimSpace(code), nil
}
// This will setup and perform authentication flow.
// If account does not require 2FA password, use telegram.CodeOnlyAuth
// instead of telegram.ConstantAuth.
if err := auth.NewFlow(
auth.Constant(phone, password, auth.CodeAuthenticatorFunc(codePrompt)),
auth.SendCodeOptions{},
).Run(ctx, client.Auth()); err != nil {
panic(err)
}
Use bot token from @BotFather.
if err := client.Auth().Bot(ctx, "token:12345"); err != nil {
panic(err)
}
You can use the generated tg.Client that allows calling any MTProto method
directly.
// Grab these from https://my.telegram.org/apps.
// Never share it or hardcode!
client := telegram.NewClient(appID, appHash, telegram.Options{})
client.Run(ctx, func(ctx context.Context) error {
// Grab token from @BotFather.
if _, err := client.Auth().Bot(ctx, "token:12345"); err != nil {
return err
}
state, err := client.API().UpdatesGetState(ctx)
if err != nil {
return err
}
// Got state: &{Pts:197 Qts:0 Date:1606855030 Seq:1 UnreadCount:106}
// This will close client and cleanup resources.
return nil
})
You can invoke methods using MTProto JSON format with InvokeJSON.
This accepts JSON with @type field in MTProto format (e.g., "messages.sendMessage")
and returns JSON response in MTProto format.
client := telegram.NewClient(appID, appHash, telegram.Options{})
client.Run(ctx, func(ctx context.Context) error {
if _, err := client.Auth().Bot(ctx, "token:12345"); err != nil {
return err
}
// Send message using MTProto JSON format
jsonReq := `{
"@type": "messages.sendMessage",
"peer": {"@type": "inputPeerUser", "user_id": 123456789, "access_hash": 0},
"message": "Hello from MTProto JSON!",
"random_id": 0
}`
jsonResp, err := client.API().InvokeJSON(ctx, jsonReq, true)
if err != nil {
return err
}
// jsonResp contains MTProto JSON response with snake_case field names
// {"@type":"messages.sentMessage",...} or error response
return nil
})
The code output of gotdgen contains references to TL types, examples, URL to
official documentation and extracted comments from it.
For example, the auth.Authorization type in tg/tl_auth_authorization_gen.go:
// AuthAuthorizationClass represents auth.Authorization generic type.
//
// See https://core.telegram.org/type/auth.Authorization for reference.
//
// Example:
// g, err := DecodeAuthAuthorization(buf)
// if err != nil {
// panic(err)
// }
// switch v := g.(type) {
// case *AuthAuthorization: // auth.authorization#cd050916
// case *AuthAuthorizationSignUpRequired: // auth.authorizationSignUpRequired#44747e9a
// default: panic(v)
// }
type AuthAuthorizationClass interface {
bin.Encoder
bin.Decoder
construct() AuthAuthorizationClass
}
Also, the corresponding auth.signIn method:
// AuthSignIn invokes method auth.signIn#bcd51581 returning error if any.
// Signs in a user with a validated phone number.
//
// See https://core.telegram.org/method/auth.signIn for reference.
func (c *Client) AuthSignIn(ctx context.Context, request *AuthSignInRequest) (AuthAuthorizationClass, error) {}
The generated constructors contain detailed official documentation, including links:
// FoldersDeleteFolderRequest represents TL type `folders.deleteFolder#1c295881`.
// Delete a peer folder¹
//
// Links:
// 1) https://core.telegram.org/api/folders#peer-folders
//
// See https://core.telegram.org/method/folders.deleteFolder for reference.
type FoldersDeleteFolderRequest struct {
// Peer folder ID, for more info click here¹
//
// Links:
// 1) https://core.telegram.org/api/folders#peer-folders
FolderID int
}
Huge thanks to all contributors. Dealing with a project of this scale alone is impossible.
Special thanks:
The MTProto protocol description is hosted by Telegram.
Most important parts for client implementations:
Current implementation mostly conforms to security guidelines, but no formal security audit were performed.
Drop a comment here to add your project.
MIT License
Created by Aleksandr (ernado) Razumov
2020
Overall
Maintained
Code review
Go module
Latest release
Releases this year
679 followers · starred Feb 2026
849 followers · starred Feb 2021
108 followers · starred Feb 2022
264 followers · starred Apr 2024