Awesome
td
Telegram MTProto API client in Go for users and bots.
- Examples
- Security policy
- User support and dev chat
- Roadmap
- Contributing
- Architecture
- Generated Go Documentation
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.
Higher level libraries
The gotd
itself is a pretty low-level library, and you may want to use higher level libraries instead:
- GoTGProto is a helper package for gotd library, It aims to make td's raw functions easy-to-use with the help of features like using session strings, custom helper functions, storing peers and extracting chat or user ids through it etc.
Usage
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.
Features
- Full MTProto 2.0 implementation in Golang, directly access any MTProto method with telegram.Client.API()
- Highly optimized, low memory (150kb per idle client) and CPU overhead, can handle thousands concurrent clients
- 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 pure 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
- Various helpers that lighten the complexity of the 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
- Connection pooling
- Automatic datacenter migration and redirects handling
- Graceful request cancellation via context
- WebSocket transport support (works in WASM)
Status
The 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).
Examples
See examples directory.
Also take a look at
- go-faster/bot as example of sophisticated telegram bot integration with GitHub
- gotd/cli, command line interface for subset of telegram methods.
Auth
User
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)
}
Bot
Use bot token from @BotFather.
if err := client.Auth().Bot(ctx, "token:12345"); err != nil {
panic(err)
}
Calling MTProto directly
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
})
Generated code
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
}
Contributions
Huge thanks to all contributors. Dealing with a project of this scale alone is impossible.
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
- shadowspore
- Background pings
- Links in generated documentation
- Message acknowledgements
- Retries
- RPC Engine
- Gap (Updates) 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)
Who is using gotd?
- The iyear/tdl, 📥 Telegram Downloader, but more than a downloader
Drop a comment here to add your project.
License
MIT License
Created by Aleksandr (ernado) Razumov
2020