Fast Telegram client fully in go.

td Go Reference codecov

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
  • 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:

Current implementation mostly conforms to security guidelines, but no formal security audit were performed.

Prior art

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 GitHub stars
GitHub watchers
Has 643 stars, which is much higher GitHub stars
GitHub watchers

License

MIT License

Created by Aleksandr (ernado) Razumov

2020

Owner
gotd
Go tools for Telegram
gotd
Comments
  • Download fails: Migrate error loop

    Download fails: Migrate error loop

    Hi, sorry if this is not a clearly defined issue. I'm getting a very high number of errors on file downloads using v0.27.0 but this happened with previous versions as well.

    Somewhere between 20-60% percent of file downloads fail (depending on time I try) which seems too high but it's notably not all of them, many succeeds as well and I can't differentiate between the ones who succeeds and fails. They usually fail with error: get file: get next chunk: rpcDoRequest: rpc error code 400: FILE_ID_INVALID which could be my fault but info logs looks strange. Once in a while they fail with get file: get next chunk: invoke pool: rpcDoRequest: rpc error code 401: AUTH_KEY_UNREGISTERED.

    Before the download errors with either of these messages the INFO log prints, the line below: Got migrate error: Creating sub-connection several hundred times before I usually get 400: FILE_ID_INVALID, occaccionally I get FILE_ID_INVALID right away. However, in some cases it also succeeds but the amount of migrate error seems strange?

    This is the line that gets printed hundreds of times, sometimes for up to to several minutes, before the download fails: INFO telegram/invoke_raw.go:23 Got migrate error: Creating sub-connection {"v": "v0.27.0", "error": "FILE_MIGRATE", "dc": 5} INFO telegram/invoke_raw.go:23 Got migrate error: Creating sub-connection {"v": "v0.27.0", "error": "FILE_MIGRATE", "dc": 5} INFO telegram/invoke_raw.go:23 Got migrate error: Creating sub-connection {"v": "v0.27.0", "error": "FILE_MIGRATE", "dc": 5}

    I'm calling both downloader.NewDownloader().DownloadDirect(c, loc).Stream(ctx, f) as well as downloader.NewDownloader().Download(c, loc).Stream(ctx, f) so there doesn't appear to be a difference when I use CDN.

    Happy to try to provide more info if you tell me what could be useful.

  • gen: reduce binary size

    gen: reduce binary size

    We have lots of mostly duplicating string literals that bloats binary size:

    return fmt.Errorf("unable to decode destroy_session#e7512126: field session_id: %w", err)
    

    This can be reduced, probably as following:

    type decodingErr {
       Type string
       TypeID int32
       // Field string?
    }
    
    $ go run github.com/jondot/goweight | head -n 10
       45 MB github.com/gotd/td/tg
      6.0 MB runtime
      5.3 MB net/http
      2.4 MB net
      2.4 MB crypto/tls
      2.0 MB reflect
      1.4 MB github.com/gotd/td/internal/mt
      1.3 MB math/big
      1.2 MB go.uber.org/zap/zapcore
      1.2 MB syscall
    
  • Testing package: Add a helper package to aid writing tests

    Testing package: Add a helper package to aid writing tests

    Description

    Currently, it's hard to write tests that use telegram.Client because there's no way to get access to an rpc mock (it's internal).

    I propose adding a new package, e.g. telegramtest. If mockClient were public, I believe it would be enough for me to start writing my own tests for my project.

    References

    Uber's zap has both a zap package and a zaptest one with helpers.

  • client: use WithContext pattern

    client: use WithContext pattern

    Currently using telegram.Client requires passing context.Context to almost all method invocations. However, in most cases we just use the context passed to Run “callback” function.

    We can make the use of context optional and default to background context using the WithContext pattern.

    Before

    err := client.Run(context.Background(), func(ctx context.Context) error {
    	if err := client.AuthIfNecessary(ctx, authFlow); err ≠ nil {
    		return err
    	}
    	self, err := client.Self(ctx)
    	if err ≠ nil {
    		return err
    	}
    	fmt.Println(self)
    	return nil
    })
    

    After (context-free)

    err := client.Run(func(client *telegram.Client) error {
    	if err := client.AuthIfNecessary(authFlow); err ≠ nil {
    		return err
    	}
    	self, err := client.Self()
    	if err ≠ nil {
    		return err
    	}
    	fmt.Println(self)
    	return nil
    })
    

    After (using context)

    ctx := req.Context()
    ctx, cancel := context.WithCancel(ctx)
    err := client.WithContext(ctx).Run(func(client *telegram.Client) error {
    	if err := client.AuthIfNecessary(authFlow); err ≠ nil {
    		return err
    	}
    	self, err := client.Self()
    	if err ≠ nil {
    		return err
    	}
    	return doSomething(client.Context(), self)
    })
    
  • client: PhoneCode missing in AuthSignUpRequest

    client: PhoneCode missing in AuthSignUpRequest

    AuthSignUpRequest is missing "PhoneCode", the official telegram docs are wrong on this as well:

    https://core.telegram.org/method/auth.signUp

    current struct:

    type AuthSignUpRequest struct {
    	// Phone number in the international format
    	PhoneNumber string
    	// SMS-message ID
    	PhoneCodeHash string
    	// New user first name
    	FirstName string
    	// New user last name
    	LastName string
    }
    

    should be:

    type AuthSignUpRequest struct {
    	// Phone number in the international format
    	PhoneNumber string
    	// SMS-message ID
    	PhoneCodeHash string
            ///Auth Code
    	PhoneCode string
    	// New user first name
    	FirstName string
    	// New user last name
    	LastName string
    }
    

    https://core.telegram.org/method/auth.signUp

    at the parameter list are 4 parameters, in the example 5.

  • Panic on download

    Panic on download

    Hi! There appears to be a regression in v0.26.1, I've started testing this library out on a project and been working fine but when I upgraded to latest version I get a panic when trying to download files. The panic doesnt happen in the download function itself but this is triggered when I begin a download, if I comment out my call to download, receiving messages etc. works just fine.

    panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x537f57a]
    
    goroutine 171 [running]:
    github.com/gotd/td/telegram/internal/manager.(*Conn).OnSession(0xc01c21e000, 0x44060bbdaafe45a9, 0xa01a6f8563c2504b, 0xadb5c849c8e82027, 0x9ba0c78becbf1b0b, 0x89fda9395701dbb0, 0x3bfa47bdf85e178e, 0x2863c1e9d6a35250, 0xe640e8c50c0152f6, 0x59bfee9847d544f9, ...)
            /Users/myusername/go/pkg/mod/github.com/gotd/[email protected]/telegram/internal/manager/conn.go:89 +0x17a
    github.com/gotd/td/mtproto.(*Conn).handleSessionCreated(0xc000358c80, 0xc00019e3a8, 0xe, 0x0)
            /Users/myusername/go/pkg/mod/github.com/gotd/[email protected]/mtproto/handle_session_created.go:20 +0x31a
    github.com/gotd/td/mtproto.(*Conn).handleMessage(0xc000358c80, 0xc00019e3a8, 0x14, 0x14)
            /Users/myusername/go/pkg/mod/github.com/gotd/[email protected]/mtproto/handle_message.go:21 +0x2ca
    github.com/gotd/td/mtproto.(*Conn).processContainerMessage(0xc000358c80, 0x6049c96fcdeb0801, 0x1, 0x1c, 0xc0002d2fc0, 0x1c, 0x1c, 0x59e2916, 0x9)
            /Users/myusername/go/pkg/mod/github.com/gotd/[email protected]/mtproto/handle_container.go:26 +0x68
    github.com/gotd/td/mtproto.(*Conn).handleContainer(0xc000358c80, 0xc00019e330, 0xe, 0x0)
            /Users/myusername/go/pkg/mod/github.com/gotd/[email protected]/mtproto/handle_container.go:17 +0x177
    github.com/gotd/td/mtproto.(*Conn).handleMessage(0xc000358c80, 0xc00019e330, 0x0, 0x0)
            /Users/myusername/go/pkg/mod/github.com/gotd/[email protected]/mtproto/handle_message.go:25 +0x20a
    github.com/gotd/td/mtproto.(*Conn).readEncryptedMessages(0xc000358c80, 0x5cbfe08, 0xc01bff1240, 0xc, 0x0)
            /Users/myusername/go/pkg/mod/github.com/gotd/[email protected]/mtproto/read.go:172 +0x157
    github.com/gotd/td/internal/tdsync.(*LogGroup).Go.func1(0x5cbfe08, 0xc01bff1240, 0x0, 0x0)
            /Users/myusername/go/pkg/mod/github.com/gotd/[email protected]/internal/tdsync/log_group.go:45 +0x270
    github.com/gotd/td/internal/tdsync.(*CancellableGroup).Go.func1(0x0, 0x0)
            /Users/myusername/go/pkg/mod/github.com/gotd/[email protected]/internal/tdsync/cancel_group.go:47 +0x3b
    golang.org/x/sync/errgroup.(*Group).Go.func1(0xc01c20d380, 0xc01bfaaa98)
            /Users/myusername/go/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:57 +0x59
    created by golang.org/x/sync/errgroup.(*Group).Go
            /Users/myusername/go/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:54 +0x66
    exit status 2
    make: *** [run] Error 1
    
  • downlaod photos alway fail: callback: get file: get next chunk: rpcDoRequest: rpc error code 400: FILE_REFERENCE_EXPIRED

    downlaod photos alway fail: callback: get file: get next chunk: rpcDoRequest: rpc error code 400: FILE_REFERENCE_EXPIRED

    What version of gotd are you using?

    $ go list -m github.com/gotd/td
    github.com/gotd/td v0.56.0
    
    

    Can this issue be reproduced with the latest version?

    I don't know

    What did you do?

    package main
    
    import (
    	"bufio"
    	"context"
    	"fmt"
    	"github.com/gotd/td/session"
    	"github.com/gotd/td/telegram/downloader"
    
    	"os"
    	"strings"
    
    	"github.com/gotd/td/telegram"
    	"github.com/gotd/td/telegram/auth"
    	"github.com/gotd/td/tg"
    )
    
    func main() {
    	client := telegram.NewClient(#####, "##################", telegram.Options{
    		SessionStorage: &session.FileStorage{
    			Path: "user.json",
    		},
    	})
    
    	err := client.Run(context.Background(), func(ctx context.Context) error {
    
    		codeFunc := auth.CodeAuthenticatorFunc(func(ctx context.Context, sentCode *tg.AuthSentCode) (string, error) {
    			fmt.Print("Enter code: ")
    			code, err := bufio.NewReader(os.Stdin).ReadString('\n')
    			if err != nil {
    				return "", err
    			}
    			return strings.TrimSpace(code), nil
    		})
    		authFlow := auth.NewFlow(auth.Constant("*******", "", codeFunc), auth.SendCodeOptions{})
    
    		err := client.Auth().IfNecessary(ctx, authFlow)
    		if err != nil {
    			return err
    		}
    		api := client.API()
    
    		request := &tg.ChannelsGetMessagesRequest{
    			Channel: &tg.InputChannel{
    				ChannelID:  1652331536,
    				AccessHash: 8880300310676456582,
    			},
    			ID: []tg.InputMessageClass{&tg.InputMessageID{ID: 2826}},
    		}
    		result, err := api.ChannelsGetMessages(ctx, request)
    		if err != nil {
    			fmt.Println(err.Error())
    			return err
    		}
    		channelMessages:=result.(*tg.MessagesChannelMessages)
    		messages := channelMessages.GetMessages()
    		downloaderInstance := downloader.NewDownloader()
    		for _, message := range messages {
    			if message.TypeID() == tg.MessageTypeID {
    				msg, ok := message.(*tg.Message)
    				if !ok {
    					continue
    				}
    			
    				if msg.Media != nil && msg.Media.TypeID() == tg.MessageMediaPhotoTypeID {
    					media := msg.Media.(*tg.MessageMediaPhoto)
    					photo, ok := media.GetPhoto()
    					if !ok {
    						continue
    					}
    					originPhoto := photo.(*tg.Photo)
    					_, err = downloaderInstance.Download(client.API(), &tg.InputPhotoFileLocation{
    						ID:            originPhoto.GetID(),
    						AccessHash:    originPhoto.GetAccessHash(),
    						FileReference: originPhoto.GetFileReference(),
    					}).ToPath(ctx, fmt.Sprintf("%d.png", originPhoto.GetID()))
    					if err!=nil {
    						return  err
    					}
    				}
    
    			}
    		}
    		return nil
    	})
    	if err != nil {
    		fmt.Println(err.Error())
    	}
    
    }
    
    

    What did you expect to see?

    I want to download files

    What did you see instead?

    callback: get file: get next chunk: rpcDoRequest: rpc error code 400: FILE_REFERENCE_EXPIRED

    What Go version and environment are you using?

    $ go version
    
    go env Output
    set GO111MODULE=on
    set GOARCH=amd64
    set GOBIN=
    set GOCACHE=C:\Users\Ms-User\AppData\Local\go-build
    set GOENV=C:\Users\Ms-User\AppData\Roaming\go\env
    set GOEXE=.exe
    set GOEXPERIMENT=
    set GOFLAGS=
    set GOHOSTARCH=amd64
    set GOHOSTOS=windows
    set GOINSECURE=
    set GOMODCACHE=C:\Users\Ms-User\go\pkg\mod
    set GONOPROXY=
    set GONOSUMDB=
    set GOOS=windows
    set GOPATH=D:\devTools\GOPATH;C:\Users\Ms-User\go
    set GOPRIVATE=
    set GOPROXY=https://proxy.golang.org,direct
    set GOROOT=D:\devTools\GO
    set GOSUMDB=sum.golang.org
    set GOTMPDIR=
    set GOTOOLDIR=D:\devTools\GO\pkg\tool\windows_amd64
    set GOVCS=
    set GOVERSION=go1.18
    set GCCGO=gccgo
    set GOAMD64=v1
    set AR=ar
    set CC=gcc
    set CXX=g++
    set CGO_ENABLED=1
    set GOMOD=D:\Code\GO\telegram_client\go.mod
    set GOWORK=
    set CGO_CFLAGS=-g -O2
    set CGO_CPPFLAGS=
    set CGO_CXXFLAGS=-g -O2
    set CGO_FFLAGS=-g -O2
    set CGO_LDFLAGS=-g -O2
    set PKG_CONFIG=pkg-config
    set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\Ms-User\AppData\Local\Temp\go-build4214324717=/tmp/go-build -gno-re
    cord-gcc-switches
    
  • chore(deps): bump github.com/go-faster/jx from 0.33.0 to 0.34.0

    chore(deps): bump github.com/go-faster/jx from 0.33.0 to 0.34.0

    Bumps github.com/go-faster/jx from 0.33.0 to 0.34.0.

    Release notes

    Sourced from github.com/go-faster/jx's releases.

    v0.34.0

    What's Changed

    Full Changelog: https://github.com/go-faster/jx/compare/v0.33.0...v0.34.0

    Commits
    • 0a79161 Merge pull request #43 from tdakkota/feat/add-bytestr-writer
    • 7018dd7 fix: cut tmp slice length in decodeRuneInByteseq
    • f880398 test: add benchmark for decodeRuneInByteseq
    • 5ed08bb test: add tests for ByteStr and ByteStrEscape, reduce tests duplication
    • 85e2464 feat: add byte slice as JSON string writer
    • 38ba9d2 chore: bump module requirement to Go 1.18
    • See full diff in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • Missing date in messages: Message struct Date field is zero in basic group chats but not in Channels or supergroups.

    Missing date in messages: Message struct Date field is zero in basic group chats but not in Channels or supergroups.

    What version of gotd are you using?

    $ go list -m github.com/gotd/td
    github.com/gotd/td v0.33.1
    

    Does this issue reproduce with the latest release?

    Yes

    What did you do?

    I receive messages thorough OnNewMessage but the .Date field is zero (not set)

    What did you expect to see?

    When I receive message in OnNewChannelMessage the .Date field is a unix time stamp. Expect it to be same for non-group chat messages.

    What did you see instead?

    .Date field is zero (not set)

    What Go version and environment are you using?

    $ go version
    go version go1.16 darwin/amd64
    
    go env Output
    $ go env
    GO111MODULE=""
    GOARCH="amd64"
    GOBIN=""
    GOCACHE="/Library/Caches/go-build"
    GOENV="/Library/Application Support/go/env"
    GOEXE=""
    GOFLAGS=""
    GOHOSTARCH="amd64"
    GOHOSTOS="darwin"
    GOINSECURE=""
    GOMODCACHE="/go/pkg/mod"
    GONOPROXY=""
    GONOSUMDB=""
    GOOS="darwin"
    GOPATH="/go"
    GOPRIVATE=""
    GOPROXY="https://proxy.golang.org,direct"
    GOROOT="/usr/local/go"
    GOSUMDB="sum.golang.org"
    GOTMPDIR=""
    GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
    GOVCS=""
    GOVERSION="go1.16"
    GCCGO="gccgo"
    AR="ar"
    CC="clang"
    CXX="clang++"
    CGO_ENABLED="1"
    GOMOD="go.mod"
    CGO_CFLAGS="-g -O2"
    CGO_CPPFLAGS=""
    CGO_CXXFLAGS="-g -O2"
    CGO_FFLAGS="-g -O2"
    CGO_LDFLAGS="-g -O2"
    PKG_CONFIG="pkg-config"
    GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/j1/hgqrbz2n1xsgz6_2c0slq9nh0000gn/T/go-build3091972184=/tmp/go-build -gno-record-gcc-switches -fno-common"
    
  • Clean up transport package

    Clean up transport package

    This PR cleans up naming after refactor in #213. The secondary MTProto transport protocol (e.g. intermediate, abridged) may be selected for different transports (e.g. TCP, WebSocket). Note that TCP-based transport currently corresponds to dcs.PlainResolver.

  • client: How send media

    client: How send media

    Hi, please share an example of how to send a media (picture) to a specific recipient? tg. Client has a method MessagesSendMedia, it is not clear how it works and whether it works at all (for example, MessagesSendMessage does not work)

  • chore(deps): bump golang.org/x/crypto from 0.4.0 to 0.5.0

    chore(deps): bump golang.org/x/crypto from 0.4.0 to 0.5.0

    Bumps golang.org/x/crypto from 0.4.0 to 0.5.0.

    Commits
    • 3d872d0 go.mod: update golang.org/x dependencies
    • bc7d1d1 bcrypt: reject passwords longer than 72 bytes
    • 7e3ac20 internal/wycheproof: also use Verify in TestECDSA
    • 23edec0 ssh: ensure that handshakeTransport goroutines have finished before Close ret...
    • f495dc3 acme: eliminate arbitrary timeouts in tests
    • See full diff in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • CHAT_ID_INVALID: When try to use MessagesAddChatUser

    CHAT_ID_INVALID: When try to use MessagesAddChatUser

    What version of gotd are you using?

     github.com/gotd/td v0.73.0
    

    Can this issue be reproduced with the latest version?

    Yes

    What did you do?

    When I'm trying to use

                                           update, err := api.MessagesAddChatUser(ctx, &tg.MessagesAddChatUserRequest{
    						ChatID: peer.ChannelID,
    						UserID: inputUser(user),
    					})
    					if err != nil {
    						return err
    					}
    
    

    Always I have some problem

    rpc error code 400: CHAT_ID_INVALID

    What did you expect to see?

    User added

    What did you see instead?

    What Go version and environment are you using?

    go1.18.1
    
    go env Output
    GO111MODULE=""
    GOARCH="amd64"
    GOBIN=""
    GOCACHE="/home/felipe/.cache/go-build"
    GOENV="/home/felipe/.config/go/env"
    GOEXE=""
    GOEXPERIMENT=""
    GOFLAGS=""
    GOHOSTARCH="amd64"
    GOHOSTOS="linux"
    GOINSECURE=""
    GOMODCACHE="/home/felipe/go/pkg/mod"
    GONOPROXY=""
    GONOSUMDB=""
    GOOS="linux"
    GOPATH="/home/felipe/go"
    GOPRIVATE=""
    GOPROXY="https://proxy.golang.org,direct"
    GOROOT="/usr/lib/go-1.18"
    GOSUMDB="sum.golang.org"
    GOTMPDIR=""
    GOTOOLDIR="/usr/lib/go-1.18/pkg/tool/linux_amd64"
    GOVCS=""
    GOVERSION="go1.18.1"
    GCCGO="gccgo"
    GOAMD64="v1"
    AR="ar"
    CC="gcc"
    CXX="g++"
    CGO_ENABLED="1"
    GOMOD="/home/felipe/Downloads/teste/go.mod"
    GOWORK=""
    CGO_CFLAGS="-g -O2"
    CGO_CPPFLAGS=""
    CGO_CXXFLAGS="-g -O2"
    CGO_FFLAGS="-g -O2"
    CGO_LDFLAGS="-g -O2"
    PKG_CONFIG="pkg-config"
    GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build3743326159=/tmp/go-build -gno-record-gcc-switches"
        
  • Cannot use peer retrieved from ContactsResolveUsername, as an argument to MessagesGetHistory

    Cannot use peer retrieved from ContactsResolveUsername, as an argument to MessagesGetHistory

    Though Go's linter didn't give me a hint that I was using mismatched type;

    What version of gotd are you using?

    0.71.0

    Can this issue be reproduced with the latest version?

    Yes

    What did you do?

    I tried to compile this code:

    api := self.client.API()
    	username := fmt.Sprintf("@%v", group)
    	peer, err := api.ContactsResolveUsername(
    		ctx,
    		username,
    	)
    	if err != nil {
    		return err
    	}
    
    	history, err := api.MessagesGetHistory(
    		ctx,
    		&tgappapiextra.MessagesGetHistoryRequest{
    			Peer:  peer,
    			Limit: 20,
    		},
    	)
    	if err != nil {
    		return err
    	}
    
    	messages := history.String()
    	fmt.Printf(
    		"retrieved msgs => %v\n",
    		messages,
    	)
    
    

    What did you expect to see?

    I expect successful compilation;

    What did you see instead?

    An error of type mismatch:

    services/my-secret-thing/index.go:60:11: cannot use peer (variable of type *tg.ContactsResolvedPeer) as type tg.InputPeerClass in struct literal:
            *tg.ContactsResolvedPeer does not implement tg.InputPeerClass (missing construct method)
    

    What Go version and environment are you using?

    Go version: go1.18.8 linux/amd64

  • helper: support messages/GetMediaGroup

    helper: support messages/GetMediaGroup

    Description

    When we call if grouped,ok := msg.GetGroupedID(); ok{}, it means a media/photo group.

    May be we need a helper func GetMediaGroup.

    References

    Like https://github.com/pyrogram/pyrogram/blob/master/pyrogram/methods/messages/get_media_group.py

  • clock: support network clock

    clock: support network clock

    Description

    I want to add a basic network clock implementation that uses ntp to calibrate the time and record the offset, the Ticker and Timer implementations are the same as clock.System.

    Note: will import new mod: https://github.com/beevik/ntp

    Add it in gotd/td or in gotd/contrib?

    References

    https://core.telegram.org/mtproto#time-synchronization

    Having received such a message or a container holding it, the client first performs a time synchronization (in effect, simply storing the difference between the server's time and its own to be able to compute the “correct” time in the future) and then verifies that the message identifiers for correctness.

gqlgenc is a fully featured go gql client, powered by codegen

gqlgenc Note: ⚠️ This is a WIP, backward-compatibility cannot be guaranteed yet, use at your own risk gqlgenc is a fully featured go gql client, power

Sep 17, 2022
GoSNMP is an SNMP client library fully written in Go

GoSNMP is an SNMP client library fully written in Go. It provides Get, GetNext, GetBulk, Walk, BulkWalk, Set and Traps. It supports IPv4 and IPv6, using SNMPv1, SNMPv2c or SNMPv3. Builds are tested against linux/amd64 and linux/386.

Jan 5, 2023
GoSNMP is an SNMP client library fully written in Go.

GoSNMP is an SNMP client library fully written in Go. It provides Get, GetNext, GetBulk, Walk, BulkWalk, Set and Traps. It supports IPv4 and IPv6, using SNMPv1, SNMPv2c or SNMPv3. Builds are tested against linux/amd64 and linux/386.

Oct 28, 2021
Gmqtt is a flexible, high-performance MQTT broker library that fully implements the MQTT protocol V3.1.1 and V5 in golang

中文文档 Gmqtt News: MQTT V5 is now supported. But due to those new features in v5, there area lots of breaking changes. If you have any migration problem

Jan 5, 2023
Automatically spawn a reverse shell fully interactive for Linux or Windows victim
Automatically spawn a reverse shell fully interactive for Linux or Windows victim

Girsh (Golang Interactive Reverse SHell) Who didn't get bored of manually typing the few lines to upgrade a reverse shell to a full interactive revers

Dec 14, 2022
纯Go编写的IM,完全自定义协议的高性能即时通讯服务(High-performance instant messaging service with fully customizable protocol)
纯Go编写的IM,完全自定义协议的高性能即时通讯服务(High-performance instant messaging service with fully customizable protocol)

LiMaoIM (Everything so easy) This project is a simple and easy to use, powerful performance, simple design concept instant messaging service, fully cu

Dec 5, 2022
DeSo is a blockchain built from the ground up to support a fully-featured social network

DeSo is a blockchain built from the ground up to support a fully-featured social network. Its architecture is similar to Bitcoin, only it supports complex social network data like profiles, posts, follows, creator coin transactions, and more.

Dec 22, 2022
Xray, Penetrates Everything. Also the best v2ray-core, with XTLS support. Fully compatible configuration.

Project X Project X originates from XTLS protocol, provides a set of network tools such as Xray-core and Xray-flutter. License Mozilla Public License

Jan 7, 2023
Laptop Booking Application in Golang and gRPC, load-balancing with NGINX, and fully compatible with HTTPS OpenAPI v3

Laptop Booking Application in Golang and gRPC Goals GitHub CI & Coverage Badge Serialize protobuf messages Create laptop unary gRPC Search laptop Serv

Jun 17, 2022
Episode VII: The DB Awakens (fully stablished JSON communication system)

APITrials0.7 Episode VII: The DB Awakens (fully stablished JSON communication system) Captain's log: Im too deep into the rabbit hole now. This seems

Jan 10, 2022
This project provides fully automated one-click experience to create Cloud and Kubernetes environment to run Data Analytics workload like Apache Spark.
This project provides fully automated one-click experience to create Cloud and Kubernetes environment to run Data Analytics workload like Apache Spark.

Introduction This project provides a fully automated one-click tool to create Data Analytics platform in Cloud and Kubernetes environment: Single scri

Nov 25, 2022
llb - It's a very simple but quick backend for proxy servers. Can be useful for fast redirection to predefined domain with zero memory allocation and fast response.

llb What the f--k it is? It's a very simple but quick backend for proxy servers. You can setup redirect to your main domain or just show HTTP/1.1 404

Sep 27, 2022
OWBot - Openwrt Telegram Bot
OWBot - Openwrt Telegram Bot

OWBot - Openwrt Telegram Bot

Dec 31, 2022
Highly-opionated MTPROTO proxy for Telegram.

Highly-opionated (ex-bullshit-free) MTPROTO proxy for Telegram.

Dec 30, 2022
Watch for interesting patterns in Caddy logs and send a Telegram notification.

Watch for interesting patterns in Caddy logs and send a Telegram notification.

Jul 21, 2022
Bridge between mattermost, IRC, gitter, xmpp, slack, discord, telegram, rocketchat, twitch, ssh-chat, zulip, whatsapp, keybase, matrix, microsoft teams, nextcloud, mumble, vk and more with REST API
Bridge between mattermost, IRC, gitter, xmpp, slack, discord, telegram, rocketchat, twitch, ssh-chat, zulip, whatsapp, keybase, matrix, microsoft teams, nextcloud, mumble, vk and more with REST API

bridge between mattermost, IRC, gitter, xmpp, slack, discord, telegram, rocketchat, twitch, ssh-chat, zulip, whatsapp, keybase, matrix, microsoft teams, nextcloud, mumble, vk and more with REST API (mattermost not required!)

Jan 4, 2023
Powered by Matterbridge, MatterAMXX is a plugin for AMXX that allows simple bridging between your game servers, Mattermost, IRC, XMPP, Gitter, Slack, Discord, Telegram, and more.
Powered by Matterbridge, MatterAMXX is a plugin for AMXX that allows simple bridging between your game servers, Mattermost, IRC, XMPP, Gitter, Slack, Discord, Telegram, and more.

Powered by Matterbridge, MatterAMXX is a plugin for AMXX that allows simple bridging between your game servers, Mattermost, IRC, XMPP, Gitter, Slack, Discord, Telegram, and more.

Dec 27, 2022
A service notification for Telegram that accepts icinga vars as arguments

A service notification for Telegram that accepts icinga vars as arguments. This is mainly to workaround a limitation in Icinga Director which is unabl

Dec 19, 2021
This small Docker project is the easiest way to send notifications directly via .txt files to services like: Gotify, Telegram, SMTP (Email) or Webhook.
This small Docker project is the easiest way to send notifications directly via .txt files to services like: Gotify, Telegram, SMTP (Email) or Webhook.

This small Docker project is the easiest way to send notifications directly via .txt files to services like: Gotify, Telegram, SMTP (Email) or Webhook.

Oct 5, 2022