xelaj/mtproto

repository·main·Indexed 23 days ago

https://github.com/xelaj/mtproto

A full-native implementation of the Telegram MTProto protocol written in pure Go. It provides a high-level API for interacting with Telegram servers, automatically handling encryption, session management, and TL schema serialization. The library supports two request patterns: a generic MakeRequest method and typed helper methods. It includes functionality for phone number authorization, server configuration via InvokeWithLayer, and a deeplinks package for resolving tg:// and t.me/ links.

Tokens
9K
Snippets
24
Records
53
Agent score
80%

What's inside mtproto

  1. Overview of Common MTProto objects

    main

    The mtproto/objects package provides default MTProto objects required for core protocol operations, such as key generation and session setup.

    These objects are derived from the official Telegram MTProto TL schema. While they are generated using the tlgen tool, they are manually reviewed and maintained as a 'gold standard' implementation of the schema, meaning they are not automatically regenerated from the schema files to ensure stability and correctness.

  2. Purpose of the deeplinks package

    main
    The deeplinks package is designed to handle Telegram's deep linking infrastructure (e.g., tg:// links). It provides tools for resolving, parsing, and working with links used for QR code logins, starting bots, retrieving post links, and joining hidden chats. This package is useful when you need to programmatically interact with Telegram's URI schemes, which are not officially documented in the standard Telegram API documentation.
  3. Choosing between tg:// and https:// schemes

    main

    When working with Telegram deep links, you should generally prefer the tg:// scheme over https:// for better compatibility across web browsers and mobile/desktop applications.

    When to use tg://:

    • For most use cases, as it is natively handled by Telegram clients on Android, iOS, Windows, macOS, and Linux.

    When to use https://:

    • When you need to support environments or editors that do not recognize the tg:// URI scheme.
    • Note that only a subset of deep links can be converted to https:// format.
  4. Optimize access_hash management with caching

    main

    Because retrieving access_hash values requires API calls, you should optimize your implementation by caching them in a database like Redis or Memcached.

    Critical Note: access_hash values are unique to the specific account performing the request. An access_hash obtained by Account A will not work for Account B.

    Best Practice: To minimize API overhead, retrieve public information using a few 'primary' accounts and store those specific access_hash values in your central storage.

  5. Perform phone number authorization

    main

    Phone authorization is a two-step process:

    1. Call AuthSendCode with the phone number, appID, and appHash to receive a PhoneCodeHash.
    2. Prompt the user for the code received via SMS/Telegram, then call AuthSignIn using the phone number and the PhoneCodeHash.
    func AuthByPhone() {
        resp, err := client.AuthSendCode(
            yourPhone,
            appID,
            appHash,
            &telegram.CodeSettings{},
        )
        if err != nil {
            panic(err)
        }
    
        // 获取验证码
        fmt.Print("Auth code:")
        code, _ := bufio.NewReader(os.Stdin).ReadString('\n')
        code = strings.Replace(code, "\n", "", -1)
    
        // 登录
        fmt.Println(client.AuthSignIn(yourPhone, resp.PhoneCodeHash, code))
    }
  6. How to obtain access_hash for InputUser and InputChannel

    main

    In Telegram's MTProto, certain requests requiring InputUser, InputChannel, or InputMedia require a specific access_hash parameter. Telegram does not publicly document the internal structure or the exact algorithm used to generate this hash. To use these objects in your API calls, you must first retrieve the hash from a successful response from Telegram.

    Methods for obtaining hashes

    Resolving a User by Username (InputUser)

    You can obtain a user's id and access_hash by resolving their username using the contacts.resolveUsername() method. The resulting Contacts.ResolvedPeer object contains a users slice; the User constructor within this slice holds both the id and the required access_hash.

    [Note: The provided source content ends before detailing the specific implementation for resolving channels via invite links.]

  7. Perform phone authorization

    main

    The authorization process involves two main steps: sending a code request and then signing in with the received code.

    1. Call AuthSendCode with the phone number, appID, and appHash.
    2. Capture the PhoneCodeHash from the response.
    3. Call AuthSignIn using the phone number, the PhoneCodeHash, and the verification code entered by the user.
    func AuthByPhone() {
        resp, err := client.AuthSendCode(
            yourPhone,
            appID,
            appHash,
            &telegram.CodeSettings{},
        )
        if err != nil {
            panic(err)
        }
    
        fmt.Print("Auth code:")
        code, _ := bufio.NewReader(os.Stdin).ReadString('\n')
        code = strings.Replace(code, "\n", "", -1)
    
        fmt.Println(client.AuthSignIn(yourPhone, resp.PhoneCodeHash, code))
    }
  8. Make requests to Telegram

    main

    You can interact with Telegram using two patterns:

    1. Generic MakeRequest: Pass a specific parameter struct (e.g., <MethodName>Params) to client.MakeRequest. You must then type-assert the result to the expected response object.
    2. Typed Helper Methods: Use direct method calls on the client (e.g., client.GetSomeInfo(args)) which are automatically typed according to the TL API specification.

    The library handles encryption, key exchange, and session management automatically.

    // Pattern 1: MakeRequest
    func main() {
        client := &Telegram.NewClient()
        result, err := client.MakeRequest(&telegram.GetSomeInfoParams{FromChatId: 12345})
        if err != nil {
            panic(err)
        }
    
        resp, ok := result.(*SomeResponseObject)
        if !ok {
            panic("Oh no! Wrong type!")
        }
    }
    
    // Pattern 2: Typed Helper Methods
    func main() {
        client := &Telegram.NewClient()
        resp, err := client.GetSomeInfo(12345)
        if err != nil {
            panic(err)
        }
    
        println(resp.InfoAboutSomething)
    }
  9. Authorize via phone number

    main

    The phone authorization process involves two main steps: sending the code request and then signing in with the received code. The library handles the asynchronous complexity of the process.

    1. Call AuthSendCode with the phone number, appID, and appHash.
    2. Capture the PhoneCodeHash from the response.
    3. Call AuthSignIn using the phone number, the hash, and the code provided by the user.
    func AuthByPhone() {
        resp, err := client.AuthSendCode(
            yourPhone,
            appID,
            appHash,
            &telegram.CodeSettings{},
        )
        if err != nil {
            panic(err)
        }
    
        fmt.Print("Auth code:")
        code, _ := bufio.NewReader(os.Stdin).ReadString('\n')
        code = strings.Replace(code, "\n", "", -1)
    
        // This completes the authorization process
        fmt.Println(client.AuthSignIn(yourPhone, resp.PhoneCodeHash, code))
    }
  10. Set up a Telegram bot using MTProto

    main

    To use the MTProto library for a Telegram bot (which provides access to the full Telegram API instead of the limited Bot API), follow these steps:

    1. Create a Bot: Use @BotFather on Telegram to create your bot and obtain a TgBotToken and TgBotUserName.
    2. Register an App: Visit my.telegram.org/apps to register your application and obtain an App api_id and App api_hash.
    3. Configure Credentials: Populate the required configuration constants in your Go code with your credentials and the appropriate server addresses.
    4. Run the Bot: Execute the application using go run main.go.
    const (
    	// from https://my.telegram.org/apps
    	TgAppID       = XXXXX                // integer value from "App api_id" field
    	TgAppHash     = "XXXXXXXXXXXX"       // string value from "App api_hash" field
    	TgTestServer  = "149.154.167.40:443" // string value from "Test configuration" field
    	TgProdServer  = "149.154.167.50:443" // string value from "Production configuration" field
    
    	// from https://t.me/BotFather
    	TgBotToken    = "XXXXX"  // bot token from BotFather
    	TgBotUserName = "YourBotUserName" // username of the bot
    )
  11. Ways to contribute without writing code

    main

    If you want to support the mtproto project but do not wish to write Go code, you can contribute through several non-coding activities:

    Spread Information

    • Write tutorials or reviews: Create cheatsheets, tutorials, or honest reviews on development forums and blogs such as golangbridge, Google Groups, Y Combinator, Habr, or Yandex Zen.
    • Social Media: Share the repository link on Twitter, Reddit, Facebook, or other social platforms.
    • Word of Mouth: Share the project with colleagues or friends, especially teams working with the Telegram API.

    Bug Reports and Questions

    • Report Bugs: If you find a bug, create an issue in the repository to help improve stability.
    • Ask Questions: Use the issue tracker to ask questions regarding the package's functionality.

    Documentation Improvements

    • Add missing info: If you discover a non-obvious way to use a feature, contribute that knowledge to the documentation.
    • Identify gaps: Inform the maintainers about specific topics not covered by the current docs.

    Improve TL Schema

    • Add documentation to TL schema: Since the native Telegram TL schema lacks documentation, you can contribute by copying and pasting relevant information from official Telegram documentation into the schema files.

    Propose New Ideas

    • If you have additional ideas for non-code contributions, submit them via a Pull Request (PR).
  12. How to use TL specs for API generation

    main
    The schemes/ directory contains the Type Language (TL) specifications for the Telegram API and MTProto protocol. The generator tool (cmd/generator) uses symlinks to determine which API version to process. By default, it uses api_latest.tl and e2e_latest.tl. To implement or generate code for older API versions, you must manually update these symlinks to point to the desired version's TL files.