mtproto

package module
v2.0.0-rc.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 13, 2024 License: MIT Imports: 18 Imported by: 0

README

MTProto 2.0


FINALLY! Full-native implementation of MTProto protocol on Golang!

english русский 简体中文

Features

Full native implementation

All code, from sending requests to encryption serialization is written on pure golang. You don't need to fetch any additional dependencies.




Latest API version (169+)

Lib is supports all the API and MTProto features, including video calls and post comments. You can create additional pull request to push api updates!






Reactive API updates (generated from TL schema)

All changes in TDLib and Android client are monitoring to get the latest features and changes in TL schemas. New methods are creates by adding new lines into TL schema and updating generated code!




Implements ONLY network tools

No more SQLite databases and caching unnecessary files, that you don't need. Also you can control how sessions are stored, auth process and literally everything that you want to!




Multiaccounting, Gateway mode

You can use more than 10 accounts at same time! xelaj/MTProto doesn't create huge overhead in memory or cpu consumption as TDLib. Thanks for that, you can create huge number of connection instances and don't worry about memory overload!




Getting started

[!CAUTION] Be sure that you are using github.com/xelaj/mtproto/v2 version: there are a lot of changes since first version, and first version is deprecated.

MTProto is really hard in implementation, but it's really easy to use. Basically, this lib sends serialized structures to Telegram servers (just like gRPC, but from Telegram LLC.). It looks like this:

func main() {
    client := telegram.NewClient()
    // for each method there is specific struct for serialization (<method_name>Params{})
    result, err := client.MakeRequest(&telegram.GetSomeInfoParams{FromChatId: 12345})
    if err != nil {
        panic(err)
    }

    resp, ok := result.(*SomeResponseObject)
    if !ok {
        panic("Oh no! Wrong type!")
    }
}

Not so hard, huh? But there is even easier way to send request, which is included in TL API specification:

func main() {
    client := telegram.NewClient()
    resp, err := client.GetSomeInfo(12345)
    if err != nil {
        panic(err)
    }

    // resp will be already asserted as described in TL specs of API
    // if _, ok := resp.(*SomeResponseObject); !ok {
    //     panic("No way, we found a bug! Create new issue!")
    // }

    println(resp.InfoAboutSomething)
}

You do not need to think about encryption, key exchange, saving and restoring session, and more routine things. It is already implemented just for you.

Code examples are here

Full docs are here

🏎️ Getting started

Simple How-To

Installation is simple. Just do go get:

go get github.com/xelaj/mtproto

After that you can generate source structures of methods and functions if you wish to. To do it, use go generate

go generate github.com/xelaj/mtproto

That's it! You don't need to do anything more!

What is InvokeWithLayer?

It's Telegram specific feature. If you want to create client instance and get information about the current server's configuration, you need to do something like this:

resp, err := client.InvokeWithLayer(apiVersion, &telegram.InitConnectionParams{
    ApiID:          124100,
    DeviceModel:    "Unknown",
    SystemVersion:  "linux/amd64",
    AppVersion:     "0.1.0",
    // just use "en", any other language codes will receive error. See telegram docs for more info.
    SystemLangCode: "en",
    LangCode:       "en",
    // HelpGetConfig() is ACTUAL request, but wrapped in InvokeWithLayer
    Query:          &telegram.HelpGetConfigParams{},
})

Why? We don't know! This method is described in Telegram API docs, any other starting requests will receive error.

How to use phone authorization?

Example here

func AuthByPhone() {
    resp, err := client.AuthSendCode(
        yourPhone,
        appID,
        appHash,
        &telegram.CodeSettings{},
    )
    if err != nil {
        panic(err)
    }

    // You can make any way to enter verification code, like in
    // http requests, or what you like. You just need to call two
    // requests, that's main method.
    fmt.Print("Auth code:")
    code, _ := bufio.NewReader(os.Stdin).ReadString('\n')
    code = strings.Replace(code, "\n", "", -1)

    // this is ALL process of authorization! :)
    fmt.Println(client.AuthSignIn(yourPhone, resp.PhoneCodeHash, code))
}

That's it! You don't need any cycles, code is ready-to-go for async execution. You just need to follow the official Telegram API documentation.

Want to deal those freaky tg:// links? See deeplinks package, here is the simplest how-to:

package main

import (
    "fmt"

    "github.com/xelaj/mtproto/telegram/deeplinks"
)

func main() {
    link, _ := deeplinks.Resolve("t.me/xelaj_developers")
    // btw, ResolveParameters is just struct for tg://resolve links, not all links are resolve
    resolve := link.(*deeplinks.ResolveParameters)
    fmt.Printf("Oh! Looks like @%v is the best developers channel in telegram!\n", resolve.Domain)
}
Docs are empty. Why?

There is a pretty huge chunk of documentation. We are ready to describe every method and object, but it requires a lot of work. Although all methods are already described here.

Does this project support Windows?

Technically — yes. In practice — components don't require specific architecture, but we didn't test it yet. If you have any problems running it, just create an issue, we will try to help.

Why Telegram API soooo unusable?

Well... Read this issue about TON source code. Use google translate, this issue will answer to all your questions.

🧶 Protocol implementation vs. Telegram client

[!IMPORTANT] TL;DR, what is mtproto library: It's just an implementation of MTProto protocol, encryption, handshake, rpc routing, etc. it doesn't rely on, but really good adapter for Telegram API. If you want to have great experience out-of-the-box, restogram is a great tool to do that.

Unlike TDLib, or gotd, mtproto package implements only one exact thing: mtproto protocol used by Telegram Messenger. That means, it doesn't contain Telegram business logic, like authorization, data caching, and much more things.

If you want real telegram client, but for scripting purposes, restogram is good enough solution for you: it's a Telegram API RESTful proxy, which works just like Bot API, but just for normal client, instead of bots.

Other good library for using telegram out-of box is gotd, which updates pretty frequently, and implements some business logic of Telegram.

🤔 Who use it

🤗 Contributing

Please read contributing guide if you want to help. And the help is very necessary!

Don't want code? Read this page! We love nocoders!

✅ TODO

  • Client MTProto implementation
  • Implement all Methods for latest layer
  • Make TL Encoder/Decoder
  • Get away from panics in parsing TL
  • Write MTProto RFC specification
  • Server MTProto implementation
  • Write amazing docs

Security bugs?

Please, don't create issue which describes security bug, this can be too offensive! Instead, please read this notification and follow that steps to notify us about problem.

Authors

License

This project is licensed under the MIT License - see the LICENSE file for details

One important thing

Even that maintainers of this project are generally from russia, we still stand up with Ukraine, and from beginning of war, decided to stop paying any taxes, or cooperate in any case with government, and companies, connected with government. This is absolutely nothing compared to how much pain putin brought to the fraternal country. And we are responsible for our inaction, and the only thing we can do is to take at least any actions that harm putin’s regime, and help the victims of regime using all resources available for us.


Created with love 💜 and magic 🦄
Xelaj Software, 2021-2024

Documentation

Overview

also why gocritic detects false positive, but if i write explanation, golangci-lint throws error that description expected as lintrer??? //TODO nolint: lll

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Dial

func Dial(host string) (mode.Mode, error)

func TryExpandError

func TryExpandError(errStr string) (nativeErrorName string, additionalData any)

Types

type BadMsgError

type BadMsgError struct {
	*objects.BadMsgNotification
	Description string
}

func BadMsgErrorFromNative

func BadMsgErrorFromNative(in *objects.BadMsgNotification) *BadMsgError

func (*BadMsgError) Error

func (e *BadMsgError) Error() string

type BadSystemMessageCode

type BadSystemMessageCode int32
const (
	ErrBadMsgUnknown             BadSystemMessageCode = 0
	ErrBadMsgIdTooLow            BadSystemMessageCode = 16
	ErrBadMsgIdTooHigh           BadSystemMessageCode = 17
	ErrBadMsgIncorrectMsgIdBits  BadSystemMessageCode = 18
	ErrBadMsgWrongContainerMsgId BadSystemMessageCode = 19 // this must never happen
	ErrBadMsgMessageTooOld       BadSystemMessageCode = 20
	ErrBadMsgSeqNoTooLow         BadSystemMessageCode = 32
	ErrBadMsgSeqNoTooHigh        BadSystemMessageCode = 33
	ErrBadMsgSeqNoExpectedEven   BadSystemMessageCode = 34
	ErrBadMsgSeqNoExpectedOdd    BadSystemMessageCode = 35
	ErrBadMsgServerSaltIncorrect BadSystemMessageCode = 48
	ErrBadMsgInvalidContainer    BadSystemMessageCode = 64
)

type ErrResponseCode

type ErrResponseCode struct {
	Code           int
	Message        string
	Description    string
	AdditionalInfo any // some errors has additional data like timeout seconds, dc id etc.
}

func (ErrResponseCode) Error

func (e ErrResponseCode) Error() string

type MTProto

type MTProto struct {
	// contains filtered or unexported fields
}

func New

func New(conn mode.Mode, key [256]byte, salt uint64) (m *MTProto, err error)

func NewAndRun

func NewAndRun(ctx context.Context, conn mode.Mode, key [256]byte, salt uint64, serverRequestHandler customHandlerFunc, finalize func(err error)) (m *MTProto, err error)

NewAndRun initiates and spawns goroutine that calls client.Run method.

IMPORTANT: This function is highly not recommended to use in real code, if you want to use it — probably there is something wrong with your architecture design. Think about this function like syntax sugar or context.TODO: it's worth it to manually call client.Run, cause you will have more control and code will look less implicit (obscurity was a giant problem of xelaj/mtproto 1.0, don't repeat our mistakes please 🙏)

func (*MTProto) MakeRequest

func (m *MTProto) MakeRequest(ctx context.Context, msg []byte) ([]byte, error)

func (*MTProto) Run

func (m *MTProto) Run(ctx context.Context, serverRequestHandler customHandlerFunc) error

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL