General architecture and description of gotd.
Subprojects:
| Name | Description |
|---|---|
| getdoc | Documentation extraction (method descriptions, error messages, etc.) |
| tl | Schema parser and writer |
| ige | AES-IGE block cipher for crypto |
See the internal/gen package for code generation implementation.
We use text/template.
Generated packages:
| Name | Description |
|---|---|
tg |
The latest Telegram layer |
tg/e2e |
Secret chats schema |
internal/mt |
MTProto schema |
- Schema is parsed from
_schema/telegram.tl - Embedded docs are loaded from
getdocif available - Bindings (interim representation) are generated
- Type definitions are generated
- Templates are executed with (4) in context
- Source code is formatted and written to
tl_*_gen.gofiles.
High-level API with helpers, like downloader or uploader.
Ideally, every telegram functionality should have sugared helper
that is convenient to use.
Can handle reconnects, DC migration, connection pooling, session management.
It is also possible to call methods directly from tg.Client, because
telegram.Client implements the Invoker interface:
// Invoker can invoke raw MTProto RPC calls.
type Invoker interface {
Invoke(ctx context.Context, input bin.Encoder, output bin.Decoder) error
}Low-level API abstracts out a single MTProto connection and handles it for a life cycle. Implements background pings with keepalive.
Uses internal/mt (MTProto schema), internal/proto (MTProto-related implementation)
and internal/rpc (request-response handling, retries, acknowledgements) internally.
And it uses internal/exchange for the key exchange process and internal/crypto for encryption.
All cryptographical primitives that are used in key exchange or encryption are implemented in internal/crypto package.
Also, the internal/crypto/srp implements Secure Remote Password (2FA).
See bin package for implementation of MTProto basic types (de-)serialization.
We do a non-streaming approach, assuming that messages are fully available in memory,
so bin.Buffer is just a wrapper for byte slices that can read and write values.
We don't do a reflection-based approach, each serialization and deserialization is generated from the schema, and is constant.