Fast Telegram client fully in go.
Before using this library, read How Not To Get Banned guide.
Usage
go get github.com/gotd/td
package main
import (
"context"
"github.com/gotd/td/telegram"
"github.com/gotd/td/tg"
)
func main() {
client := telegram.NewClient(appID, appHash, telegram.Options{})
err := client.Run(context.Background(), func(ctx context.Context) error {
api := tg.NewClient(client)
// Now you can invoke MTProto RPC requests by calling api.
// ...
// Return to close client connection and free up resources.
return nil
})
if err != nil {
panic(err)
}
}
See examples for more info.
Status
Work is still in progress (mostly helpers and convenience wrappers), but basic functionality were tested in production and works fine. Only go1.16 is supported and no backward compatibility is provided for now.
Goal of this project is to implement stable, performant and safe client for Telegram in go while providing simple and convenient API, including feature parity with TDLib.
This project is fully non-commercial and not affiliated with any commercial organization (including Telegram LLC).
Also see comparison with other Go Telegram clients.
Features
- Full MTProto 2.0 implementation in Golang
- Code for Telegram types generated by
./cmd/gotdgen
(based on gotd/tl parser) with embedded official documentation - Pluggable session storage
- Automatic re-connects with keepalive
- Vendored Telegram public keys that are kept up-to-date
- Rigorously tested
- End-to-end with real Telegram server in CI
- End-to-end with gotd Telegram server (in go)
- Lots of unit testing
- Fuzzing
- 24/7 canary bot in production that tests reconnects, update handling, memory leaks and performance
- No runtime reflection overhead
- Conforms to Security guidelines for Telegram client software developers
- Secure PRNG used for crypto
- Replay attack protection
- 2FA support
- MTProxy support
- Multiple helpers that hide complexity of raw Telegram API
- uploads for big and small files with multiple streams for single file and progress reporting
- downloads with CDN support, also multiple streams
- messages with various convenience builders and text styling support
- query with pagination helpers
- middleware for rate limiting and FLOOD_WAIT handling
- CDN support with connection pooling
- Automatic datacenter migration and redirects handling
- Graceful request cancellation via context
- WebSocket transport support (works in WASM)
Examples
See examples directory.
Also take a look at
- gotd/bot with updates recovery enabled, used as canary for stability testing
- gotd/cli, command line interface for subset of telegram methods.
Auth
User
You can use td/telegram/auth.Flow
to simplify user authentication flow.
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)
}
Bot
Use bot token from @BotFather.
if err := client.Auth().Bot(ctx, "token:12345"); err != nil {
panic(err)
}
Calling MTProto directly
You can use generated tg.Client
that allows calling any MTProto methods 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 := tg.NewClient(client).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
}
Generated code
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
}
Contributions
Huge thanks to every contributor, dealing with a project of such scale is impossible alone.
Special thanks:
- tdakkota
- Two-factor authentication (SRP)
- Proxy support
- Update dispatcher
- Complete transport support (abridged, padded intermediate and full)
- Telegram server for end-to-end testing
- Multiple major refactorings, including critical cryptographical scope reduction
- Code generation improvements (vector support, multiple modes for pretty-print)
- And many other cool things and performance improvements
- zweihander
- Background pings
- Links in generated documentation
- Message acknowledgements
- Retries
- RPC Engine
Reference
The MTProto protocol description is hosted by Telegram.
Most important parts for client implementations:
- Security guidelines for client software developers
Current implementation mostly conforms to security guidelines, but no formal security audit were performed.
Prior art
- Lonami/grammers (Great Telegram client in Rust, many test vectors were used as reference)
- sdidyk/mtproto, cjongseok/mtproto, xelaj/mtproto (MTProto 1.0 in go)
Difference to other projects
Status by 11.07.2021
Topic | gotd | xelaj/mtproto | ||
---|---|---|---|---|
Maintainers |
At least 3 core contributors, 1.7K commits, actively maintained, automatically updated to latest layer | Single core contributor, 150 commits, effectively not maintaned from March 2021, failed to update to 129 layer | ||
Security |
MTProto v2, conforms to security guidelines | MTProto v1 that is insecure and deprecated since 2017 (SHA-1 is used instead of SHA-256), code was probably copied from sdidyk/mtproto or cjongseok/mtproto with little understanding | ||
Features |
MTProxy support, WebSocket transport, helpers for uploads, downloads, messages, text styling, datacenter redirects handling and more, but you can still use the raw API | Raw MTProto API | ||
Platforms |
All platforms including WASM and special stability features for Windows that considers clock resolution | Limited support for Windows | ||
Performance |
Multiple optimizations for zero allocations | Uses reflection in runtime | ||
Stability |
Lots of unit tests (237 tests, 943 including subtests), end-to-end tests with self-made Telegram server in Go, end-to-end tests with real staging server, fuzzing | 12 unit tests, 41 including sub-tests | ||
GitHub Stargazers |
Has only 192 stars | |
Has 643 stars, which is much higher | |
License
MIT License
Created by Aleksandr (ernado) Razumov
2020