Git Product home page Git Product logo

mtproto's Introduction

MTProto

Telegram MTProto and proxy (over gRPC) in Go (golang). Telegram API layer: 71

Quick start

# It is vendored in 'dep'. Refer to https://github.com/golang/dep for 'dep' installation.
dep ensure

# Run simple shell with your Telegram API id, hash, and, server address with your phone number.
# If you don't have Telegram API stuffs, get them from 'https://my.telegram.org/apps'.
go run examples/simpleshell/main.go <APIID> <APIHASH> <PHONE> <IP> <PORT>

# Then you can see 'Enter code:' message
# Telegram sends you an authentication code. Check it on your mobile or desktop app and put it.
Enter code: <YOUR_CODE>

# Now signed-in. Let's get your recent dialogs. 
# You can see them in JSON.
$ dialogs
....

# Quit the shell.
$ exit

# You can find 'credentials.json' file which keeps your MTProto secerets.
ls -al credentials.json

# You can check if the scerets correct by sign-in with it.
go run examples/simpleshell/main.go  credentials.json

Usage

You can find the real code at simpleshell.

Sign-in with key

// Mew MTProto manager
config, _ := mtproto.NewConfiguration(appVersion, deviceModel, systemVersion, language, 0, 0, "credentials.json")
manager, _ := mtproto.NewManager(config)

// Sign-in by key
mconn, _ := manager.LoadAuthentication()

Sign-in without key

// New MTProto manager
config, _ := mtproto.NewConfiguration(appVersion, deviceModel, systemVersion, language, 0, 0, "new-credentials.json")
manager, _ := mtproto.NewManager(config)

// Request to send an authentication code
// It needs your phone number and Telegram API stuffs you can check in https://my.telegram.org/apps 
mconn, sentCode, err := manager.NewAuthentication(phoneNumber, apiID, apiHash, ip, port)

// Get the code from user input
fmt.Scanf("%s", &code)

// Sign-in and generate the new key
_, err = mconn.SignIn(phoneNumber, code, sentCode.GetValue().PhoneCodeHash)

Telegram RPC in Protocol Buffer

cjongseok/mtproto implements TL-schema functions in Protocol Buffer. These are declared in types.tl.proto as RPCs, and implemented in Go at procs.tl.go. With the same interface, you can call functions not only in direct connection to the Telegram server, but also over a mtproto proxy.

Let's have two direct call examples, messages.getDialogs and messages.sendMessage.

Get dialogs

// New RPC caller with a connection to Telegram server. 
// By alternating mconn with a proxy connection, you can call same functions over proxy. It is covered later.
caller := mtproto.RPCaller{mconn}

// New input peer
// In Telegram DSL, Predicates inherit a Type.
// Here we create a Predicate, InputPeerEmpty whose parent is InputPeer.
// More details about these types are covered later.
emptyPeer := &mtproto.TypeInputPeer{&mtproto.TypeInputPeer_InputPeerEmpty{&mtproto.PredInputPeerEmpty{}}

// Query to Telegram
dialogs, _ := caller.MessagesGetDialogs(context.Background(), &mtproto.ReqMessagesGetDialogs{
    OffsetDate: 0,
    OffsetId: 	0,
    OffsetPeer: emptyPeer,
    Limit: 		1,
})

Send a message to a channel

// New RPC caller with a connection to Telegram server. 
caller := mtproto.RPCaller{mconn}

// New input peer
// Create a Predicate, InputPeerChannel, wraped by its parent Type, InputPeer.
channelPeer := &mtproto.TypeInputPeer{&mtproto.TypeInputPeer_InputPeerChannel{
    &mtproto.PredInputPeerChannel{
        yourChannelId, yourChannelHash,
    }}}

// Send a request to Telegram
caller.MessagesSendMessage(context.Background(), &mtproto.ReqMessagesSendMessage{
    Peer:      channelPeer,
    Message:   "Hello MTProto",
    RandomId:  rand.Int63(),
})

How mtproto is impelemented in Protocol Buffer

Types

Telegram's mtproto has three kinds of types, Type, Predicate, and Method. A Type is a kind of a data structure interface which has no fields, and a Predicate implements a Type. In the above case, mtproto.PredInputPeerChannel is a Predicate of a Type mtproto.TypeInputPeer. gRPC recommends to implement this kind of polymorphism with Oneof, so InputPeer is defined in Protocol Buffer as below:

// types.tl.proto:19
message TypeInputPeer {
	oneof Value {
		PredInputPeerEmpty InputPeerEmpty = 1;
		PredInputPeerSelf InputPeerSelf = 2;
		PredInputPeerChat InputPeerChat = 3;
		PredInputPeerUser InputPeerUser = 4;
		PredInputPeerChannel InputPeerChannel = 5;
    }
}

The use of gRPC Oneof in Go is complex, because Go does not allow hierarchical relations among types, e.g., inheritance. I believe, however, gRPC guys did their best and it would be the best implementation of such polymorphism in Go with RPC. For more details about the use of OneOf in Go, please refer to this document.

Methods

Mtproto methods have a namespace as you can see in TL-schema, e.g., auth, account, users, ... . Instead of managing these namespaces as separate Protocol Buffer services, these are integrated into one Protocol Buffer Service, Mtproto, and namesapces are remained as method name prefixes. In the above example, the original name of MessagesSendMessage is messages.sendMessage.

In the original schema, a method can have multiple parameters. These paremeters are declared into a new data structure in Protocol Buffer whose name starts with 'Req'. For example, messages.sendMessage requires many parameters, and these are transformed into ReqMessagesSendMessage in MessagesSendMessage.

Proxy

You can use the proxy in two purposes:

  • MTProto session sharing: Many proxy clients can use the same MTProto session on the proxy server.
  • MTProto in other languages: The proxy enables various languages on its client side, since it uses gRPC.

Server

As a stand-alone daemon

mtprotod is a stand-alone proxy daemon containing Telegram MTProto implementation in Go.

Quick Start

# start mtprotod at port 11011
docker run \
-p 11011: 11011 \
-v /your/mtproto/secrets/directory:/opt \
cjongseok/mtprotod start  \
--port 11011 \
--addr <Your_Telegram_server_address> \
--apiid <Your_Telegram_api_id> \
--apihash <Your_Telegram_api_hash> \
--phone <Your_Telegram_phone_number> \
--secrets /opt/<Your_MTProto_secrets_file_name>

# At mtproto/proxy, let's get dialogs through over the proxy
dep ensure
go test proxy/proxy_test.go --run TestDialogs

Build & Run

# In mtproto directory
dep ensure
go run mtprotod/main.go start \
--addr <Your_Telegram_server_address> \
--apiid <Your_Telegram_api_id> \
--apihash <Your_Telegram_api_hash> \
--phone <Your_Telegram_phone_number> \
--port <Proxy_port> \
--secrets /opt/<Your_MTProto_secrets_file_name>

As a part of Go application

Use mtproto/proxy package.

// New proxy server
config, _ := mtproto.NewConfiguration(apiId, apiHash, appVersion, deviceModel, systemVersion, language, 0, 0, key)
server = proxy.NewServer(port)

// Start the server
server.Start(config, phone)

Client in Go

// New proxy client
client, _ := proxy.NewClient(proxyAddr)

// Telegram RPC over proxy. It is same with the previous 'Get dialogs' but the RPC caller
emptyPeer := &mtproto.TypeInputPeer{&mtproto.TypeInputPeer_InputPeerEmpty{&mtproto.PredInputPeerEmpty{}}
dialogs, err := client.MessagesGetDialogs(context.Background(), &mtproto.ReqMessagesGetDialogs{
    OffsetDate: 0,
    OffsetId:   0,
    OffsetPeer: emptyPeer,
    Limit:      1,
})

Client in Python

See py.

Client in other languages

By compiling types.tl.proto and proxy/tl_update.proto, you can create clients in your preferred language.
For this, you need to install Protocol Buffer together with gRPC library of the target language. Then you can compile Protocol Buffer files with this kind of command lines:

You can find these command lines for other languages in gRPC tutorial.

Acknowledgement

License

Apache 2.0

mtproto's People

Contributors

amir3code avatar cjongseok avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mtproto's Issues

add auth via bot token

I want to use this via bot token and so need ability to auth not only by phone, but with bot token.

TL_messageFwdHeader update

Hi!
Thnx you for you work!

Can you update TL_messageFwdHeader to recive a filds "Saved_from_peer" and "Saved_from_msg_id" ?
Please.

Feature to load external session

Hi, is it possible to load a session from some external storage to your library?
We using https://github.com/LonamiWebs/Telethon and we have session store in redis with rate limiting and we can load session from there. Session is in format:
{\"phone\":******,\"api_id\":\"****\",\"api_hash\":\"****\",\"id\":\"****\",\"port\":***,\"salt\":\"***\",\"sequence\":****,\"time_offset\":***,\"server_address\":\"****\",\"auth_key_data\":\"***\"}

I looked one eye at the library and can help if necessary with programming. Or you do not interest it and it's easier for us to make a fork?

Handshaking Failure: TL_invokeWithLayer Timeout(10.000000 s)

2018/05/04 09:52:02 MAIN: load authentication
2018/05/04 09:52:02 [MM 1957114261] start
2018/05/04 09:52:02 [MM 1957114261] loadsession of  +86*********
2018/05/04 09:52:02 [0-4060730080273079382] dial TCP to 149.154.167.50:443
2018/05/04 09:52:02 [0-4060730080273079382] send: start
2018/05/04 09:52:02 [0-4060730080273079382] read: start
2018/05/04 09:52:02 [0-4060730080273079382] send *mtproto.ReqInvokeWithLayer: {"Layer":71,"Query":{"type_url":"type.googleapis.com/mtproto.ReqInitConnection","value":"***********************"}}
2018/05/04 09:52:02 [0-4060730080273079382] read: type: <nil>, data: <nil>, err: Server response error: -404
2018/05/04 09:52:02 [0-4060730080273079382] read: unknown error, Server response error: -404. reconnect to 149.154.167.50:443
2018/05/04 09:52:02 [0-4060730080273079382] notify Event, mtproto.refreshSession: {}, to [0xc4200a8120]
2018/05/04 09:52:02 [MM 1957114261] refreshSession  4060730080273079382
2018/05/04 09:52:03 [MM 1957114261] spinlocked. Session(4060730080273079382) is waiting for a response from either invokeWithLayer or updatesGetState.
2018/05/04 09:52:04 [MM 1957114261] spinlocked. Session(4060730080273079382) is waiting for a response from either invokeWithLayer or updatesGetState.
2018/05/04 09:52:05 [MM 1957114261] spinlocked. Session(4060730080273079382) is waiting for a response from either invokeWithLayer or updatesGetState.
2018/05/04 09:52:06 [MM 1957114261] spinlocked. Session(4060730080273079382) is waiting for a response from either invokeWithLayer or updatesGetState.
2018/05/04 09:52:07 [MM 1957114261] spinlocked. Session(4060730080273079382) is waiting for a response from either invokeWithLayer or updatesGetState.
2018/05/04 09:52:08 [MM 1957114261] spinlocked. Session(4060730080273079382) is waiting for a response from either invokeWithLayer or updatesGetState.
2018/05/04 09:52:09 [MM 1957114261] spinlocked. Session(4060730080273079382) is waiting for a response from either invokeWithLayer or updatesGetState.
2018/05/04 09:52:10 [MM 1957114261] spinlocked. Session(4060730080273079382) is waiting for a response from either invokeWithLayer or updatesGetState.
2018/05/04 09:52:11 [MM 1957114261] spinlocked. Session(4060730080273079382) is waiting for a response from either invokeWithLayer or updatesGetState.
2018/05/04 09:52:12 [MM 1957114261] connect failure: Handshaking Failure: TL_invokeWithLayer Timeout(10.000000 s)
2018/05/04 09:52:12 [0-4060730080273079382] send <nil>: null
2018/05/04 09:52:12 [0-4060730080273079382] send <nil>: null
2018/05/04 09:52:12 [0-4060730080273079382] send: stop
2018/05/04 09:52:12 [0-4060730080273079382] read: wait for inner routine ...
2018/05/04 09:52:12 [0-4060730080273079382] read: stop
2018/05/04 09:52:12 [0-4060730080273079382] notify Event, mtproto.SessionDiscarded: {}, to [0xc4200a8120]
2018/05/04 09:52:12 [MM 1957114261] session discarded  4060730080273079382

Can't get ReplyToMsgId to work

I am using your library and want to reply to message with some text. So I took your simpleshell example and slightly customised it.

Now in OnUpdate I have this code:

func (s *subscriber) OnUpdate(u mtproto.Update) {
	if _, ok := u.(*mtproto.PredUpdates); ok {
		predUpdates := u.(*mtproto.PredUpdates)
		updates := predUpdates.GetUpdates()
		for _, update := range updates {
			if _, ok := update.Value.(*mtproto.TypeUpdate_UpdateNewChannelMessage); ok {
				update := update.Value.(*mtproto.TypeUpdate_UpdateNewChannelMessage).UpdateNewChannelMessage
				message := update.Message.GetMessage()
				if message.GetToId().GetPeerChat() != nil {
					continue
				}
				if message.Message == "/help" {
					msgID := message.Id
					chanID := message.ToId.GetPeerChannel().ChannelId
					var chanHash int64
					chats := predUpdates.GetChats()
					for _, chat := range chats {
						if chat.GetChannel().Id == chanID {
							chanHash = chat.GetChannel().GetAccessHash()
							break
						}
					}
					peer := &mtproto.TypeInputPeer{Value: &mtproto.TypeInputPeer_InputPeerChannel{
						InputPeerChannel: &mtproto.PredInputPeerChannel{
							ChannelId: chanID, AccessHash: chanHash,
						}}}
					_, err := s.caller.MessagesSendMessage(context.Background(), &mtproto.ReqMessagesSendMessage{
						Peer:         peer,
						Message:      "Test of hndbot.",
						ReplyToMsgId: msgID,
						RandomId:     rand.Int63(),
					})
					handleError(err)
				}
			}
		}
	}
}

But message is sending without ReplyToMsgId (I also looked on MessagesSendMessage response and there isn't ReplyToMsgId too). Screenshot from Telegram Desktop:

Telegram Desktop screenshot

So how I can get replies to work? Do I need to use flags (as schema shows) or I did something wrong?

Program hangs when second session tries to start

I am trying to implement multi-account feature in my program. I define array of accounts and try to login:

// Account represents Telegram account.
type Account struct {
	Phone      string
	ConfigPath string
	// ...
}
accs := make(map[string]*Account)
accs[args[0]] = &Account{
	Phone:      args[0],
	ConfigPath: os.Args[1],
}
accs[args[0]].Login() // it works
accs[args[1]] = &Account{
	Phone:      args[1],
	ConfigPath: os.Args[1],
}
accs[args[1]].Login() // now it hangs

Logs:

... first account logs ...
... now second account tries to login
2019/01/27 23:42:54 [MM 290413704] start
2019/01/27 23:42:54 [MM 290413704] newsession to  149.154.167.50:443
here it hangs

Does your library support multiple sessions? I explored your code and I think those accounts should use different managers. If you need the Account.Login method's code, I can upload it as gist (this is the code from SimpleShell, with small changes). Thank you a lot for this beautiful library!

Disabling logging

Hi. I really like your lib, but is there is any way to configure logger which are you using inside your lib?

Panic on the session binding

2017/12/13 13:51:15 [MM 14433365] start
2017/12/13 13:51:15 [MM 14433365] newsession to  149.154.167.50:443
2017/12/13 13:51:15 [0-4072867300443788290] dial TCP to 149.154.167.50:443
2017/12/13 13:51:17 [0-4072867300443788290] read: start
2017/12/13 13:51:17 [0-4072867300443788290] send: start
2017/12/13 13:51:17 [0-4072867300443788290] send mtproto.TL_invokeWithLayer: {"Layer":71,"Query":{"Api_id":XXXXXX,"Device_model":"Unknown","System_version":"windows/amd64","App_version":"0.0.1","System_lang_code":"en","Lang_pack":"","Lang_code":"en","Query":{}}}
2017/12/13 13:51:17 [0-4072867300443788290] read: type: mtproto.TL_msg_container, data: {[{6499028881552709633 1 28 {6499028879457618992 6182303720115487009 [142 96 227 158 192 226 174 218]}} {6499028881552720897 2 20 {[6499028879457618992]}}]}, err: <nil>
2017/12/13 13:51:17 [0-4072867300443788290] send mtproto.TL_msgs_ack: {}
2017/12/13 13:51:17 [0-4072867300443788290] read: type: mtproto.TL_rpc_result, data: {6499028879457618992 {0 1513173077 1513176766 {} 2 [{0 1 149.154.175.50 443} {1 1 2001:0b28:f23d:f001:0000:0000:0000:000a 443} {0 2 149.154.167.51 443} {16 2 149.154.167.51 443} {1 2 2001:067c:04e8:f002:0000:0000:0000:000a 443} {0 3 149.154.175.100 443} {1 3 2001:0b28:f23d:f003:0000:0000:0000:000a 443} {0 4 149.154.167.91 443} {1 4 2001:067c:04e8:f004:0000:0000:0000:000a 443} {2 4 149.154.165.120 443} {0 5 91.108.56.165 443} {1 5 2001:0b28:f23f:f005:0000:0000:0000:000a 443}] 200 30000 100 120000 5000 30000 300000 30000 1500 10 60000 2 200 172800 2419200 30 5 0 5 20000 90000 30000 10000 https://t.me/  0 []}}, err: <nil>
2017/12/13 13:51:17 [0-4072867300443788290] process: unknown data type mtproto.TL_config {{"Flags":0,"Date":1513173077,"Expires":1513176766,"Test_mode":{},"This_dc":2,"Dc_options":[{"Flags":0,"Id":1,"Ip_address":"149.154.175.50","Port":443},{"Flags":1,"Id":1,"Ip_address":"2001:0b28:f23d:f001:0000:0000:0000:000a","Port":443},{"Flags":0,"Id":2,"Ip_address":"149.154.167.51","Port":443},{"Flags":16,"Id":2,"Ip_address":"149.154.167.51","Port":443},{"Flags":1,"Id":2,"Ip_address":"2001:067c:04e8:f002:0000:0000:0000:000a","Port":443},{"Flags":0,"Id":3,"Ip_address":"149.154.175.100","Port":443},{"Flags":1,"Id":3,"Ip_address":"2001:0b28:f23d:f003:0000:0000:0000:000a","Port":443},{"Flags":0,"Id":4,"Ip_address":"149.154.167.91","Port":443},{"Flags":1,"Id":4,"Ip_address":"2001:067c:04e8:f004:0000:0000:0000:000a","Port":443},{"Flags":2,"Id":4,"Ip_address":"149.154.165.120","Port":443},{"Flags":0,"Id":5,"Ip_address":"91.108.56.165","Port":443},{"Flags":1,"Id":5,"Ip_address":"2001:0b28:f23f:f005:0000:0000:0000:000a","Port":443}],"Chat_size_max":200,"Megagroup_size_max":30000,"Forwarded_count_max":100,"Online_update_period_ms":120000,"Offline_blur_timeout_ms":5000,"Offline_idle_timeout_ms":30000,"Online_cloud_timeout_ms":300000,"Notify_cloud_delay_ms":30000,"Notify_default_delay_ms":1500,"Chat_big_size":10,"Push_chat_period_ms":60000,"Push_chat_limit":2,"Saved_gifs_limit":200,"Edit_time_limit":172800,"Rating_e_decay":2419200,"Stickers_recent_limit":30,"Stickers_faved_limit":5,"Tmp_sessions":0,"Pinned_dialogs_count_max":5,"Call_receive_timeout_ms":20000,"Call_ring_timeout_ms":90000,"Call_connect_timeout_ms":30000,"Call_packet_timeout_ms":10000,"Me_url_prefix":"https://t.me/","Suggested_lang_code":"","Lang_pack_version":0,"Disabled_features":[]}}
2017/12/13 13:51:17 [0-4072867300443788290] send mtproto.TL_msgs_ack: {}
2017/12/13 13:51:17 [0-4072867300443788290] config: {"Flags":0,"Date":1513173077,"Expires":1513176766,"Test_mode":{},"This_dc":2,"Dc_options":[{"Flags":0,"Id":1,"Ip_address":"149.154.175.50","Port":443},{"Flags":1,"Id":1,"Ip_address":"2001:0b28:f23d:f001:0000:0000:0000:000a","Port":443},{"Flags":0,"Id":2,"Ip_address":"149.154.167.51","Port":443},{"Flags":16,"Id":2,"Ip_address":"149.154.167.51","Port":443},{"Flags":1,"Id":2,"Ip_address":"2001:067c:04e8:f002:0000:0000:0000:000a","Port":443},{"Flags":0,"Id":3,"Ip_address":"149.154.175.100","Port":443},{"Flags":1,"Id":3,"Ip_address":"2001:0b28:f23d:f003:0000:0000:0000:000a","Port":443},{"Flags":0,"Id":4,"Ip_address":"149.154.167.91","Port":443},{"Flags":1,"Id":4,"Ip_address":"2001:067c:04e8:f004:0000:0000:0000:000a","Port":443},{"Flags":2,"Id":4,"Ip_address":"149.154.165.120","Port":443},{"Flags":0,"Id":5,"Ip_address":"91.108.56.165","Port":443},{"Flags":1,"Id":5,"Ip_address":"2001:0b28:f23f:f005:0000:0000:0000:000a","Port":443}],"Chat_size_max":200,"Megagroup_size_max":30000,"Forwarded_count_max":100,"Online_update_period_ms":120000,"Offline_blur_timeout_ms":5000,"Offline_idle_timeout_ms":30000,"Online_cloud_timeout_ms":300000,"Notify_cloud_delay_ms":30000,"Notify_default_delay_ms":1500,"Chat_big_size":10,"Push_chat_period_ms":60000,"Push_chat_limit":2,"Saved_gifs_limit":200,"Edit_time_limit":172800,"Rating_e_decay":2419200,"Stickers_recent_limit":30,"Stickers_faved_limit":5,"Tmp_sessions":0,"Pinned_dialogs_count_max":5,"Call_receive_timeout_ms":20000,"Call_ring_timeout_ms":90000,"Call_connect_timeout_ms":30000,"Call_packet_timeout_ms":10000,"Me_url_prefix":"https://t.me/","Suggested_lang_code":"","Lang_pack_version":0,"Disabled_features":[]}
2017/12/13 13:51:17 [0-4072867300443788290] send mtproto.TL_updates_getState: {}
2017/12/13 13:51:17 [0-4072867300443788290] read: type: mtproto.TL_rpc_result, data: {6499028879522626992 {401 AUTH_KEY_UNREGISTERED}}, err: <nil>
2017/12/13 13:51:17 [0-4072867300443788290] process: unknown data type mtproto.TL_rpc_error {{}}
2017/12/13 13:51:17 [0-4072867300443788290] send mtproto.TL_msgs_ack: {}
2017/12/13 13:51:17 [MM 14433365] connectionOpened  1471635579
2017/12/13 13:51:17 [mconn 1471635579] start
2017/12/13 13:51:17 [mconn 1471635579] opened.
2017/12/13 13:51:17 [mconn 1471635579] wait for a session binding ...
2017/12/13 13:51:17 [mconn 1471635579] bind: mconn.discardedUpdatesState is nil
2017/12/13 13:51:17 [MM 14433365] sessionBound: session 4072867300443788290 is bound to mconn 1471635579
2017/12/13 13:51:17 [mconn 1471635579] bound to session 4072867300443788290
2017/12/13 13:51:17 [1471635579-4072867300443788290] send mtproto.TL_auth_sendCode: {"Flags":1,"Phone_number":"+44XXXXXXXXX","Current_number":{},"Api_id":XXXXXX,"Api_hash":"XXXXXXXXXXXXXXXXXXXXXXXXX"}
2017/12/13 13:51:17 [1471635579-4072867300443788290] read: type: mtproto.TL_rpc_result, data: {6499028879577136492 {303 PHONE_MIGRATE_4}}, err: <nil>
2017/12/13 13:51:17 [1471635579-4072867300443788290] process: unknown data type mtproto.TL_rpc_error {{}}
2017/12/13 13:51:17 [1471635579-4072867300443788290] send mtproto.TL_msgs_ack: {}
2017/12/13 13:51:17 [MM 14433365] renewSession to  149.154.165.120:443
2017/12/13 13:51:17 [mconn 1471635579] session will be discarded4072867300443788290
2017/12/13 13:51:17 [mconn 1471635579] unbound to session 4072867300443788290
2017/12/13 13:51:17 [MM 14433365] sessionUnbound: session 4072867300443788290 is unbound from mconn 1471635579
2017/12/13 13:51:17 [MM 14433365] discard session  4072867300443788290
2017/12/13 13:51:17 [1471635579-4072867300443788290] send: stop
2017/12/13 13:51:17 [1471635579-4072867300443788290] read: wait for inner routine ...
2017/12/13 13:51:17 [1471635579-4072867300443788290] read: type: <nil>, data: <nil>, err: read tcp 192.168.8.105:6114->149.154.167.50:443: use of closed network connection
2017/12/13 13:51:17 [1471635579-4072867300443788290] read: TCP connection closed (read tcp 192.168.8.105:6114->149.154.167.50:443: use of closed network connection)
2017/12/13 13:51:17 [1471635579-4072867300443788290] read: stop
2017/12/13 13:51:17 [MM 14433365] session discarded  4072867300443788290
2017/12/13 13:51:17 [MM 14433365] refreshSession  4072867300443788290
2017/12/13 13:51:17 [MM 14433365] session is discarded. keep its updates state, (json): {"Pts":0,"Qts":0,"Date":0,"Seq":0,"Unread_count":0}
2017/12/13 13:51:17 [MM 14433365] renewRoutine: req newsession
2017/12/13 13:51:17 [MM 14433365] newsession to  149.154.165.120:443
2017/12/13 13:51:17 [0-7482388398792317020] dial TCP to 149.154.165.120:443
2017/12/13 13:51:18 [MM 14433365] sessionBound: session 7482388398792317020 is bound to mconn 1471635579

after this i get this in the console output

[signal 0xc0000005 code=0x0 addr=0x0 pc=0x531ba0]

goroutine 61 [running]:
github.com/cjongseok/mtproto.(*MConn).bind(0xc0424ae000, 0xc0424e2000, 0xc057b7607b, 0xc0424ae098)
        github.com/cjongseok/mtproto/mconn.go:64 +0x110
github.com/cjongseok/mtproto.(*MManager).manageRoutine.func1(0xc042086210, 0x8775c0, 0xc04200a940)
        github.com/cjongseok/mtproto/mmanager.go:184 +0x54d
created by github.com/cjongseok/mtproto.(*MManager).manageRoutine
       github.com/cjongseok/mtproto/mmanager.go:188 +0x589
exit status 2

Reported by @nathan0

Error in handshake

Log from example application:

2018/01/31 11:16:38 MAIN: load authentication
2018/01/31 11:16:38 [MM 493794111] start
2018/01/31 11:16:38 [MM 493794111] loadsession of  +79689329901
2018/01/31 11:16:38 [0-5104173340106603236] dial TCP to 149.154.167.50:443
2018/01/31 11:16:38 [0-5104173340106603236] read: start
2018/01/31 11:16:38 [0-5104173340106603236] send: start
2018/01/31 11:16:38 [0-5104173340106603236] send mtproto.TL_invokeWithLayer: {"Layer":71,"Query":{"Api_id":35556,"Device_model":"Unknown","System_version":"linux/amd64","App_version":"0.0.1","System_lang_code":"en","Lang_pack":"","Lang_code":"en","Query":{}}}
2018/01/31 11:16:38 [0-5104173340106603236] read: type: mtproto.TL_crc_bad_msg_notification, data: {6517125814043208060 1 17}, err: <nil>
2018/01/31 11:16:38 [0-5104173340106603236] process: unknown data type mtproto.TL_crc_bad_msg_notification {{}}
2018/01/31 11:16:43 [MM 493794111] connect failure: Handshaking Failure: TL_invokeWithLayer Timeout(5.000000 s)
2018/01/31 11:16:43 [0-5104173340106603236] send: stop
2018/01/31 11:16:43 [0-5104173340106603236] read: wait for inner routine ...
2018/01/31 11:16:43 [0-5104173340106603236] read: type: <nil>, data: <nil>, err: read tcp 10.240.32.15:36862->149.154.167.50:443: use of closed network connection
2018/01/31 11:16:43 [0-5104173340106603236] read: TCP connection closed (read tcp 10.240.32.15:36862->149.154.167.50:443: use of closed network connection)
2018/01/31 11:16:43 [0-5104173340106603236] notify MEvent, mtproto.refreshSession: {}, to [0xc420022180]
2018/01/31 11:16:43 [0-5104173340106603236] read: stop
2018/01/31 11:16:43 [0-5104173340106603236] notify MEvent, mtproto.SessionDiscarded: {}, to [0xc420022180]
2018/01/31 11:16:43 [MM 493794111] session discarded  5104173340106603236
2018/01/31 11:16:43 [MM 493794111] refreshSession  5104173340106603236
2018/01/31 11:16:43 ERR: Handshaking Failure: TL_invokeWithLayer Timeout(5.000000 s)

$ go version
go version go1.9.2 linux/amd64

$ uname -a
Linux wks-mishkin 4.4.0-112-generic #135-Ubuntu SMP Fri Jan 19 11:48:36 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

How to send one message to many chanels

// New RPC caller with a connection to Telegram server. 
caller := mtproto.RPCaller{mconn}

// New input peer
// Create a Predicate, InputPeerChannel, wraped by its parent Type, InputPeer.
channelPeer := &mtproto.TypeInputPeer{&mtproto.TypeInputPeer_InputPeerChannel{
    &mtproto.PredInputPeerChannel{
        yourChannelId, yourChannelHash,
    }}}

// Send a request to Telegram
caller.MessagesSendMessage(context.Background(), &mtproto.ReqMessagesSendMessage{
    Peer:      channelPeer,
    Message:   "Hello MTProto",
    RandomId:  rand.Int63(),
})

You have put this code in the README.md file of the project.
But the problem is that I have to specify each channel on each request.
How can I supply a list of channels or peers to send message to all of them at once?
Is it even possible? (I have seen people do it in telegram but I didn't find how, at the same time I have checked schema.tl file but there is no method that can accept a list type)

Thanks in advance for the great work of the project.

A way to obtain file_id from media documents

Is there a way to recieve file_id from Media types (TypeMessageMedia) to send it through bot API without downloading? For example, in bot API for sharing existing photo required string file_id, but in core API only can be found (TypeFileLocation) fields, like VolumeId, Secret and so on.

Error Classification

Hi, Thanks for developing this mtproto library
Can you help about classifying errors & responses?
For example when using authSignIn how to determine the code was wrong or password was required?

connect failure: Handshaking Failure: missing port in address

Hi,

I am trying to start a mtproto proxy. I am using docker image and I am trying to launch it using the following command:

docker run -p 11011:11011 -v /root/mtproto/:/opt cjongseok/mtprotod start --port 11011 --addr 149.154.167.40:443 --apiid 20XXXX --apihash 95XXXXXXc1af049ad8cXXXXXX93eXXXX --phone +346XXXXXXXX --secrets /opt/cacert.pem

I have tried with "Test configuration" and "Production configuration" ips, with and without the port.

The complete trace is the following:

root@host:~/mtproto# docker run -p 11011:11011 -v /root/mtproto/:/opt cjongseok/mtprotod start --port 11011 --addr 149.154.167.XX:443  --apiid 20XXXX-apihash 95XXXXXXc1af049ad8cXXXXXX93eXXXX --phone +346XXXXXXXX --secrets /opt/cacert.pem
2018/06/19 15:00:17 [MM 669056947] start
2018/06/19 15:00:17 [MM 669056947] loadsession of  +346XXXXXXXX
2018/06/19 15:00:17 [MM 669056947] connect failure: Handshaking Failure: address aTTveB2GazTw
Efzk2DWgkBluml8OREmvfraX3bkHZJTKX4EQSjBbbdJ2ZXIsRrYOXfaA+xayEGB+
8hdlLmAj: missing port in address
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x97af92]

goroutine 6 [running]:
github.com/cjongseok/mtproto.(*Session).close(0xc42017e1e0)
        /Users/jongseok/gopath/src/github.com/cjongseok/mtproto/session.go:108 +0x72
github.com/cjongseok/mtproto.(*Manager).manageRoutine.func2(0xc420176240, 0xdaea40, 0xc4201c09c0)
        /Users/jongseok/gopath/src/github.com/cjongseok/mtproto/manager.go:300 +0x347
created by github.com/cjongseok/mtproto.(*Manager).manageRoutine
        /Users/jongseok/gopath/src/github.com/cjongseok/mtproto/manager.go:281 +0x231

which is the problem? how should I type the --addr ip?

PredUpdateShortChatMessage not working?

Stripped down code:

func newSubscriber(mconn *mtproto.Conn) *subscriber {
	s := new(subscriber)
	s.mconn = mconn
	return s
}

type subscriber struct {
	mconn *mtproto.Conn
}

func (s *subscriber) OnUpdate(u mtproto.Update) {
    switch u.(type) {
        case *mtproto.PredUpdateShortChatMessage:
            fmt.Println("PredUpdateShortChatMessage")
        case *mtproto.PredUpdateShortMessage:
            fmt.Println("PredUpdateShortMessage")
    }
}

func main() {
    mconn, _= manager.LoadAuthentication(phoneNumber)
    mconn.AddUpdateCallback(newSubscriber(mconn))
    for {
        time.Sleep(time.Second)
    }
}

PredUpdateShortMessage works fine, but PredUpdateShortChatMessage doesn't, it's called when there is a message to a group/channel, is there something i'm missing/doing wrong?

Output of u:

Updates:<
  Updates:<
    UpdateNewChannelMessage:<
      Message:<
        Message:<
          Flags:264
          Id:-
          FromId:-ToId:<
            PeerChannel:<
              ChannelId:-
            >
          >
          ReplyToMsgId:-
          Date:1527894767
          Message:"Some Message"
        >
      >
      Pts:41234
      PtsCount:1
    >
  >
  Users:<
    User:<
      Flags:107
      Id:-
      AccessHash:-
      FirstName:"Some"
      Username:"User"
      Photo:<
        UserProfilePhoto:<
          PhotoId:-
          PhotoSmall:<
            FileLocation:<
              DcId:1
              VolumeId:-
              LocalId:- Secret:-
            >
          >
          PhotoBig:<
            FileLocation:<
              DcId:1 VolumeId:-
              LocalId:-
              Secret:-
            >
          >
        >
      >
      Status:<
        UserStatusRecently:<>
      >
    >
  >
  Chats:<
    Channel:<
      Flags:24904
      Id:-
      AccessHash:-
      Title:"Group Name"
      Username:"groupusername"
      Photo:<
        ChatPhoto:<
          PhotoSmall:<
            FileLocation:<
              DcId:4
              VolumeId:-
              LocalId:-
              Secret:-
            >
          >
          PhotoBig:<
            FileLocation:<
              DcId:4
              VolumeId:-
              LocalId:-
              Secret:-
            >
          >
        >
      >
      Date:1506520301
      AdminRights:<
        Value:<
          Flags:121
        >
      >
    >
  >
  Date:1527894766
>

Changing DC?

In order to download something from telegram servers, I sometimes need to change datacenter (error "mtproto RPC error: 303 FILE_MIGRATE_2 " if you are interested why). How can I do it with your lib? As far as I understand I have no option to get "dcOptions" field from Session struct which contains all the information about available DCs, because it is a private field and apiDcOption(...) is private too.

Can you please provide any way either to get "dcOptions" or to reconnect to the specific DC? The second way is a little bit harder because it will require to first call AuthExportAuthorization, reconnect to new dc and then call AuthImportAuthorization.

P.S. Thanks for the project and really great support. I can do a merge request if you are busy

Sending Message to User

Hey! I like to get the full information about an user (from my contacts or not) if he writes me a message. So on PredUpdateShortMessage, i try to call the UsersGetUsers but i need an AccessHash i didnt have. how do i get it? Here is my code:
`

case *mtproto.PredUpdateShortMessage:

	{
		caller := mtproto.RPCaller{RPC: s.mconn}

		inputUser := &mtproto.TypeInputUser{
			Value: &mtproto.TypeInputUser_InputUser{
				InputUser: &mtproto.PredInputUser{
					UserId:	u.(*mtproto.PredUpdateShortMessage).Id,
					AccessHash: ???,
				},
			},
		}

		idArray := []*mtproto.TypeInputUser{
			inputUser,
		}

		_, err := caller.UsersGetUsers(context.Background(), &mtproto.ReqUsersGetUsers{
			Id: idArray,
		})

		fmt.Println(err.Error())
	}

panic: sync: negative WaitGroup counter

panic: sync: negative WaitGroup counter

goroutine 51 [running]:
sync.(*WaitGroup).Add(0xc0004640c0, 0xffffffffffffffff)
D:/Go/src/sync/waitgroup.go:74 +0x1eb
sync.(*WaitGroup).Done(0xc0004640c0)
D:/Go/src/sync/waitgroup.go:99 +0x3b
github.com/cjongseok/mtproto.(*Session).sendRoutine.func2(0xc0004b2000, 0xc0000c6460, 0xc0004640c0)
D:/MyGo/src/github.com/cjongseok/mtproto/session.go:643 +0x121
created by github.com/cjongseok/mtproto.(*Session).sendRoutine
D:/MyGo/src/github.com/cjongseok/mtproto/session.go:637 +0x1c6

mtproto.TL_crc_bad_msg_notification

I just tried to run the simpleshell.go example and got this output in ss.log, happens every time that i try it

2017/12/06 23:29:25 [MM 1123312869] start
2017/12/06 23:29:25 [MM 1123312869] newsession to  149.154.167.50:443
2017/12/06 23:29:25 [0-3809958685979515729] dial TCP to 149.154.167.50:443
2017/12/06 23:29:26 [0-3809958685979515729] read: start
2017/12/06 23:29:26 [0-3809958685979515729] send: start
2017/12/06 23:29:26 [0-3809958685979515729] send mtproto.TL_invokeWithLayer: {"Layer":71,"Query":{"Api_id":XXXXXX,"Device_model":"Unknown","System_version":"windows/amd64","App_version":"0.0.1","System_lang_code":"en","Lang_pack":"","Lang_code":"en","Query":{}}}
2017/12/06 23:29:26 [0-3809958685979515729] read: type: mtproto.TL_msg_container, data: {[{6496580273879479297 1 28 {6496580271469954036 -820804553205492118 [14 210 25 103 155 121 76 252]}} {6496580273879524353 2 20 {[6496580271469954036]}}]}, err: <nil>
2017/12/06 23:29:26 [0-3809958685979515729] send mtproto.TL_msgs_ack: {}
2017/12/06 23:29:26 [0-3809958685979515729] read: type: mtproto.TL_rpc_result, data: {6496580271469954036 {0 1512602966 1512606504 {} 2 [{0 1 149.154.175.50 443} {1 1 2001:0b28:f23d:f001:0000:0000:0000:000a 443} {0 2 149.154.167.51 443} {16 2 149.154.167.51 443} {1 2 2001:067c:04e8:f002:0000:0000:0000:000a 443} {0 3 149.154.175.100 443} {1 3 2001:0b28:f23d:f003:0000:0000:0000:000a 443} {0 4 149.154.167.91 443} {1 4 2001:067c:04e8:f004:0000:0000:0000:000a 443} {2 4 149.154.165.120 443} {0 5 91.108.56.165 443} {1 5 2001:0b28:f23f:f005:0000:0000:0000:000a 443}] 200 30000 100 120000 5000 30000 300000 30000 1500 10 60000 2 200 172800 2419200 30 5 0 5 20000 90000 30000 10000 https://t.me/  0 []}}, err: <nil>
2017/12/06 23:29:26 [0-3809958685979515729] process: unknown data type mtproto.TL_config {{"Flags":0,"Date":1512602966,"Expires":1512606504,"Test_mode":{},"This_dc":2,"Dc_options":[{"Flags":0,"Id":1,"Ip_address":"149.154.175.50","Port":443},{"Flags":1,"Id":1,"Ip_address":"2001:0b28:f23d:f001:0000:0000:0000:000a","Port":443},{"Flags":0,"Id":2,"Ip_address":"149.154.167.51","Port":443},{"Flags":16,"Id":2,"Ip_address":"149.154.167.51","Port":443},{"Flags":1,"Id":2,"Ip_address":"2001:067c:04e8:f002:0000:0000:0000:000a","Port":443},{"Flags":0,"Id":3,"Ip_address":"149.154.175.100","Port":443},{"Flags":1,"Id":3,"Ip_address":"2001:0b28:f23d:f003:0000:0000:0000:000a","Port":443},{"Flags":0,"Id":4,"Ip_address":"149.154.167.91","Port":443},{"Flags":1,"Id":4,"Ip_address":"2001:067c:04e8:f004:0000:0000:0000:000a","Port":443},{"Flags":2,"Id":4,"Ip_address":"149.154.165.120","Port":443},{"Flags":0,"Id":5,"Ip_address":"91.108.56.165","Port":443},{"Flags":1,"Id":5,"Ip_address":"2001:0b28:f23f:f005:0000:0000:0000:000a","Port":443}],"Chat_size_max":200,"Megagroup_size_max":30000,"Forwarded_count_max":100,"Online_update_period_ms":120000,"Offline_blur_timeout_ms":5000,"Offline_idle_timeout_ms":30000,"Online_cloud_timeout_ms":300000,"Notify_cloud_delay_ms":30000,"Notify_default_delay_ms":1500,"Chat_big_size":10,"Push_chat_period_ms":60000,"Push_chat_limit":2,"Saved_gifs_limit":200,"Edit_time_limit":172800,"Rating_e_decay":2419200,"Stickers_recent_limit":30,"Stickers_faved_limit":5,"Tmp_sessions":0,"Pinned_dialogs_count_max":5,"Call_receive_timeout_ms":20000,"Call_ring_timeout_ms":90000,"Call_connect_timeout_ms":30000,"Call_packet_timeout_ms":10000,"Me_url_prefix":"https://t.me/","Suggested_lang_code":"","Lang_pack_version":0,"Disabled_features":[]}}
2017/12/06 23:29:26 [0-3809958685979515729] send mtproto.TL_msgs_ack: {}
2017/12/06 23:29:26 [0-3809958685979515729] config: {"Flags":0,"Date":1512602966,"Expires":1512606504,"Test_mode":{},"This_dc":2,"Dc_options":[{"Flags":0,"Id":1,"Ip_address":"149.154.175.50","Port":443},{"Flags":1,"Id":1,"Ip_address":"2001:0b28:f23d:f001:0000:0000:0000:000a","Port":443},{"Flags":0,"Id":2,"Ip_address":"149.154.167.51","Port":443},{"Flags":16,"Id":2,"Ip_address":"149.154.167.51","Port":443},{"Flags":1,"Id":2,"Ip_address":"2001:067c:04e8:f002:0000:0000:0000:000a","Port":443},{"Flags":0,"Id":3,"Ip_address":"149.154.175.100","Port":443},{"Flags":1,"Id":3,"Ip_address":"2001:0b28:f23d:f003:0000:0000:0000:000a","Port":443},{"Flags":0,"Id":4,"Ip_address":"149.154.167.91","Port":443},{"Flags":1,"Id":4,"Ip_address":"2001:067c:04e8:f004:0000:0000:0000:000a","Port":443},{"Flags":2,"Id":4,"Ip_address":"149.154.165.120","Port":443},{"Flags":0,"Id":5,"Ip_address":"91.108.56.165","Port":443},{"Flags":1,"Id":5,"Ip_address":"2001:0b28:f23f:f005:0000:0000:0000:000a","Port":443}],"Chat_size_max":200,"Megagroup_size_max":30000,"Forwarded_count_max":100,"Online_update_period_ms":120000,"Offline_blur_timeout_ms":5000,"Offline_idle_timeout_ms":30000,"Online_cloud_timeout_ms":300000,"Notify_cloud_delay_ms":30000,"Notify_default_delay_ms":1500,"Chat_big_size":10,"Push_chat_period_ms":60000,"Push_chat_limit":2,"Saved_gifs_limit":200,"Edit_time_limit":172800,"Rating_e_decay":2419200,"Stickers_recent_limit":30,"Stickers_faved_limit":5,"Tmp_sessions":0,"Pinned_dialogs_count_max":5,"Call_receive_timeout_ms":20000,"Call_ring_timeout_ms":90000,"Call_connect_timeout_ms":30000,"Call_packet_timeout_ms":10000,"Me_url_prefix":"https://t.me/","Suggested_lang_code":"","Lang_pack_version":0,"Disabled_features":[]}
2017/12/06 23:29:26 [0-3809958685979515729] send mtproto.TL_updates_getState: {}
2017/12/06 23:29:26 [0-3809958685979515729] read: type: mtproto.TL_crc_bad_msg_notification, data: {6496580271534462136 7 33}, err: <nil>
2017/12/06 23:29:26 [0-3809958685979515729] process: unknown data type mtproto.TL_crc_bad_msg_notification {{}}```

An existing connection was forcibly closed by the remote host.

2018/02/22 13:55:00 MAIN: load authentication
2018/02/22 13:55:00 [MM 1855813799] start
2018/02/22 13:55:00 [MM 1855813799] loadsession of +86***
2018/02/22 13:55:00 [MM 1855813799] connect failure: Cannot Load Session info from neither session file nor env: open new session:%!(EXTRA *errors.errorString=New session)
2018/02/22 13:55:00 Cannot Load Session info from neither session file nor env: open new session:%!(EXTRA *errors.errorString=New session)
2018/02/22 13:55:08 MAIN: new authentication
2018/02/22 13:55:08 [MM 1161534771] start
2018/02/22 13:55:08 [MM 1161534771] newsession to 149.154.167.50:443
2018/02/22 13:55:08 [0-196229755453559639] dial TCP to 149.154.167.50:443
2018/02/22 13:55:09 [MM 1161534771] connect failure: write tcp 192.168.0.107:57004->149.154.167.50:443: wsasend: An existing connection was forcibly closed by the remote host.
2018/02/22 13:55:09 write tcp 192.168.0.107:57004->149.154.167.50:443: wsasend: An existing connection was forcibly closed by the remote host.

panic: runtime error: invalid memory address or nil pointer dereference

The code that I am writing is this:
What I am trying to do is to get a list of dialogs. But sometime panic error happens due to some network error.

package main

import (
	"github.com/cjongseok/mtproto"
	"context"
	"os"
	"fmt"
	"github.com/cjongseok/slog"
	"math/rand"
	"reflect"
)

func main() {
	// the acc we are using is: (telegram acc new three)
	caller := setUpLoggingNConnectNGetCaller()
	getDialogs(caller)                                                        // === line 16 ===
}

func getDialogs(caller *mtproto.RPCaller) *mtproto.PredMessagesDialogs {
	emptyPeer := &mtproto.TypeInputPeer{Value: &mtproto.TypeInputPeer_InputPeerEmpty{InputPeerEmpty: &mtproto.PredInputPeerEmpty{}}}
	var response *mtproto.TypeMessagesDialogs
	r, err := caller.MessagesGetDialogs(context.Background(), &mtproto.ReqMessagesGetDialogs{       //  === line 22 ===
		OffsetDate: 0, OffsetId: 0, OffsetPeer: emptyPeer,
	})
	if err != nil {
		fmt.Println("Can not get dialogs due to error:", err)
	}
	response = r

	dialogs := response.GetMessagesDialogs().GetDialogs()
	for _, item := range dialogs {
		fmt.Println(reflect.TypeOf(item.GetValue()))
		fmt.Println()
	}

	return response.GetMessagesDialogs()
}

func setUpLoggingNConnectNGetCaller() *mtproto.RPCaller {
	// set up logging
	logf, err := os.OpenFile("ss.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		fmt.Printf("error opening file: %v", err)
	}
	defer logf.Close()
	slog.SetLogOutput(logf)

	appVersion := "0.1"
	deviceModel := "SHIT"
	systemVersion := "0.2"
	language := "en"
	config, _ := mtproto.NewConfiguration(appVersion, deviceModel, systemVersion, language, 0, 0, "credentials.json")
	manager, _ := mtproto.NewManager(config)

	// Sign-in by key
	mconn, _ := manager.LoadAuthentication()
	caller := mtproto.RPCaller{RPC: mconn}
	return &caller
}

The error that happens is this:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x7a61be]

goroutine 1 [running]:
kasra/doingstuff_on_tg/vendor/github.com/cjongseok/mtproto.(*Conn).LogPrefix(0x0, 0xc49d80, 0x0)
        /home/kasra/go/src/kasra/doingstuff_on_tg/vendor/github.com/cjongseok/mtproto/conn.go:363 +0x2e
kasra/doingstuff_on_tg/vendor/github.com/cjongseok/slog.logprefix(0xc49d80, 0x0, 0x0, 0x12bc180)
        /home/kasra/go/src/kasra/doingstuff_on_tg/vendor/github.com/cjongseok/slog/slog.go:128 +0x29a
kasra/doingstuff_on_tg/vendor/github.com/cjongseok/slog.Logln(0xc49d80, 0x0, 0xc420093860, 0x2, 0x2)
        /home/kasra/go/src/kasra/doingstuff_on_tg/vendor/github.com/cjongseok/slog/slog.go:165 +0x6d
kasra/doingstuff_on_tg/vendor/github.com/cjongseok/mtproto.(*Conn).Session(0x0, 0x1)
        /home/kasra/go/src/kasra/doingstuff_on_tg/vendor/github.com/cjongseok/mtproto/conn.go:151 +0xdc
kasra/doingstuff_on_tg/vendor/github.com/cjongseok/mtproto.(*Conn).InvokeNonBlocked(0x0, 0xd09ac0, 0xc420250580, 0xc420093d70)
        /home/kasra/go/src/kasra/doingstuff_on_tg/vendor/github.com/cjongseok/mtproto/conn.go:130 +0x90
kasra/doingstuff_on_tg/vendor/github.com/cjongseok/mtproto.(*Conn).InvokeBlocked(0x0, 0xd09ac0, 0xc420250580, 0x7f1b32e68d90, 0x0, 0x2, 0xdf8475800)
        /home/kasra/go/src/kasra/doingstuff_on_tg/vendor/github.com/cjongseok/mtproto/conn.go:114 +0x5d
kasra/doingstuff_on_tg/vendor/github.com/cjongseok/mtproto.RPCaller.MessagesGetDialogs(0xd04060, 0x0, 0xd25760, 0xc4200d4050, 0xc420250580, 0xc88ace, 0x2, 0xdf8475800)
        /home/kasra/go/src/kasra/doingstuff_on_tg/vendor/github.com/cjongseok/mtproto/procs.tl.go:424 +0x57
main.getDialogs(0xc4202482f0, 0xc4200b8058)
        /home/kasra/go/src/kasra/doingstuff_on_tg/_accounts_/main.go:22 +0x127
main.main()
        /home/kasra/go/src/kasra/doingstuff_on_tg/_accounts_/main.go:16 +0x27
exit status 2

How can I handle this kind of error? (I have put comment after line 22 and 16 of my code to make it clear)
As you can see I have received the error in err variable and checked it but I still get this panic.
Not to mention that I dont ALWAYS get this panic, It just happens sometimes due to network errors, How can I handle this one?

endless spinlock

Hi,

i have a problem where from time to time the spinlock seems to be endless.
i managed to reproduce it when resetting the connection around the time where login happens using

iptables -A OUTPUT -o eth0 -d 149.154.167.50/32 -p tcp -j REJECT --reject-with tcp-reset

the log looks like this:

2020/04/16 19:10:58 [0-1691844592411390537] read: type: mtproto.TL_rpc_result, data: {6816358161102222444 Pts:1212 Date:1587057058 Seq:315 UnreadCount:1 }, err: <nil>
2020/04/16 19:10:58 [0-1691844592411390537] updatesState: {"Pts":1212,"Date":1587057058,"Seq":315,"UnreadCount":1}
2020/04/16 19:10:58 [0-1691844592411390537] read: type: <nil>, data: <nil>, err: read tcp 10.0.0.2:52164->149.154.167.50:443: read: connection reset by peer
2020/04/16 19:10:58 [0-1691844592411390537] read: lost connection (read tcp 10.0.0.2:52164->149.154.167.50:443: read: connection reset by peer). reconnect to 149.154.167.50:443
2020/04/16 19:10:58 [0-1691844592411390537] send mtproto.TL_msgs_ack: {}
2020/04/16 19:10:58 [0-1691844592411390537] notify Event, mtproto.SessionEstablished: {}, to [0xc0009baa80]
2020/04/16 19:10:58 [0-1691844592411390537] ping: start
2020/04/16 19:10:58 [mconn 1156161785] bind session 1691844592411390537
2020/04/16 19:10:58 [mconn 1156161785] start
2020/04/16 19:10:58 [0-1691844592411390537] notify Event, mtproto.refreshSession: {}, to [0xc0009baa80]
2020/04/16 19:10:58 [mconn 1156161785] session event mtproto.ConnectionOpened({0xc00000c1e0 0})
2020/04/16 19:10:58 [mconn 1156161785] pass the session to bindSession ch
2020/04/16 19:10:58 [mconn 1156161785] opened
2020/04/16 19:10:58 [mconn 1156161785] with session, 0
2020/04/16 19:10:58 [MM 1023332122] session established 1691844592411390537
2020/04/16 19:10:58 [MM 1023332122] connectionOpened  1156161785
2020/04/16 19:10:58 [MM 1023332122] refreshSession  1691844592411390537
2020/04/16 19:10:58 [mconn 1156161785] sesssin passed
2020/04/16 19:10:58 [mconn 1156161785] bind: mconn.discardedUpdatesState is nil
2020/04/16 19:10:58 [mconn 1156161785] session request 0xc0000a49c0
2020/04/16 19:10:58 [1156161785-1691844592411390537] notify Event, mtproto.discardSession: {}, to [0xc0009baa80 0xc0009bb6e0]
2020/04/16 19:10:58 [mconn 1156161785] session event mtproto.discardSession({1156161785 1691844592411390537 0xc0001a09c0})
2020/04/16 19:10:58 [mconn 1156161785] session(1691844592411390537) will be discarded
2020/04/16 19:10:58 [MM 1023332122] sessionBound: session 1691844592411390537 is bound to mconn 1156161785
2020/04/16 19:10:58 [mconn 1156161785] session event mtproto.sessionUnbound({0xc00000c1e0 1691844592411390537})
2020/04/16 19:10:58 [mconn 1156161785] unbound to session 1691844592411390537
2020/04/16 19:10:58 [mconn 1156161785] session event mtproto.sessionBound({0xc00000c1e0 1691844592411390537})
2020/04/16 19:10:58 [mconn 1156161785] bound to session 1691844592411390537
2020/04/16 19:10:58 [MM 1023332122] discard session  1691844592411390537
2020/04/16 19:10:58 [MM 1023332122] sessionUnbound: session 1691844592411390537 is unbound from mconn 1156161785
2020/04/16 19:10:58 [1156161785-1691844592411390537] send err: write tcp 10.0.0.2:52164->149.154.167.50:443: write: broken pipe
2020/04/16 19:10:58 [1156161785-1691844592411390537] send *mtproto.ReqUsersGetFullUser: {"Id":{"Value":{"InputUserSelf":{}}}}
2020/04/16 19:10:59 [1156161785-1691844592411390537] send err: write tcp 10.0.0.2:52164->149.154.167.50:443: write: broken pipe
2020/04/16 19:10:59 [1156161785-1691844592411390537] send: stop
2020/04/16 19:10:59 [1156161785-1691844592411390537] read: wait for inner routine ...
2020/04/16 19:10:59 [1156161785-1691844592411390537] read: stop
2020/04/16 19:10:59 [1156161785-1691844592411390537] notify Event, mtproto.SessionDiscarded: {}, to [0xc0009baa80 0xc0009bb6e0]
2020/04/16 19:10:59 [MM 1023332122] session is discarded. keep its updates state, (json): {"Pts":1212,"Date":1587057058,"Seq":315}
2020/04/16 19:10:59 [MM 1023332122] req loadsession
2020/04/16 19:10:59 [MM 1023332122] session discarded  1691844592411390537
2020/04/16 19:10:59 [MM 1023332122] loadsession of conn  1156161785
2020/04/16 19:10:59 [0-4373503034935838490] dial TCP to 149.154.167.50:443
2020/04/16 19:10:59 [mconn 1156161785] session event mtproto.SessionDiscarded({1156161785 1691844592411390537 0xc000c0f240})
2020/04/16 19:10:59 [MM 1023332122] connect failure: Handshaking Failure: dial tcp 0.0.0.0:0->149.154.167.50:443: connect: connection refused
2020/04/16 19:10:59 [0-4373503034935838490] notify Event, mtproto.SessionDiscarded: {}, to [0xc0009baa80]
2020/04/16 19:10:59 [MM 1023332122] session discarded  4373503034935838490
2020/04/16 19:10:59 [MM 1023332122] refreshSession failure; loadSession failure; Handshaking Failure: dial tcp 0.0.0.0:0->149.154.167.50:443: connect: connection refused; connID: 0, session: &{0 4373503034935838490 [] 0xc0004349d0 <nil> 0xc000450de0 <nil> <nil> <nil> <nil> false false false {{} [0 0 0]} {{} [0 0 0]} {{} [0 0 0]} 0xc000312630 <nil> 0 map[] map[] 0 0 {... ... ... ... 60000000000 500000000 {"phone":.....,"api_id":......,"api_hash":"........","ip":"149.154.167.50","port":443,"salt":"...........","auth_key":"..........."} 0xecb780} <nil> <nil> map[] 0.0.0.0}
2020/04/16 19:10:59 [MM 1023332122] retry refreshSession
2020/04/16 19:10:59 [MM 1023332122] refreshSession is done.
2020/04/16 19:10:59 [MM 1023332122] refreshSession  4373503034935838490

then the following never ends:

2020/04/16 19:11:00 [MM 1023332122] spinlocked. Session(4373503034935838490) is waiting for a response from either invokeWithLayer or updatesGetState.
2020/04/16 19:11:01 [MM 1023332122] spinlocked. Session(4373503034935838490) is waiting for a response from either invokeWithLayer or updatesGetState.
2020/04/16 19:11:02 [MM 1023332122] spinlocked. Session(4373503034935838490) is waiting for a response from either invokeWithLayer or updatesGetState.
2020/04/16 19:11:03 [MM 1023332122] spinlocked. Session(4373503034935838490) is waiting for a response from either invokeWithLayer or updatesGetState.
2020/04/16 19:11:04 [MM 1023332122] spinlocked. Session(4373503034935838490) is waiting for a response from either invokeWithLayer or updatesGetState.
2020/04/16 19:11:05 [MM 1023332122] spinlocked. Session(4373503034935838490) is waiting for a response from either invokeWithLayer or updatesGetState.
2020/04/16 19:11:06 [MM 1023332122] spinlocked. Session(4373503034935838490) is waiting for a response from either invokeWithLayer or updatesGetState.
2020/04/16 19:11:07 [MM 1023332122] spinlocked. Session(4373503034935838490) is waiting for a response from either invokeWithLayer or updatesGetState.
2020/04/16 19:11:08 [MM 1023332122] spinlocked. Session(4373503034935838490) is waiting for a response from either invokeWithLayer or updatesGetState.
2020/04/16 19:11:09 [MM 1023332122] spinlocked. Session(4373503034935838490) is waiting for a response from either invokeWithLayer or updatesGetState.
2020/04/16 19:11:10 [MM 1023332122] spinlocked. Session(4373503034935838490) is waiting for a response from either invokeWithLayer or updatesGetState.

i already increased any timeouts to 30s for testing, but that did not help.

any ideas?

thanks in advance.

update to the latest layer

when compiling layer 71 i get the following warnings

tl_update.proto:7:17: "mtproto.PredUpdatesState" is not defined.
tl_update.proto:8:17: "mtproto.PredUpdateShortMessage" is not defined.
tl_update.proto:9:17: "mtproto.PredUpdateShortChatMessage" is not defined.
tl_update.proto:10:17: "mtproto.PredUpdateShort" is not defined.
tl_update.proto:11:17: "mtproto.PredUpdates" is not defined.
tl_update.proto:12:17: "mtproto.PredUpdateShortSentMessage" is not defined.
tl_update.proto:13:17: "mtproto.PredUpdatesDifference" is not defined.
tl_update.proto:14:17: "mtproto.PredUpdatesDifferenceSlice" is not defined.
tl_update.proto:15:17: "mtproto.PredUpdateNewMessage" is not defined.
tl_update.proto:16:17: "mtproto.PredUpdateReadMessagesContents" is not defined.
tl_update.proto:17:17: "mtproto.PredUpdateDeleteMessages" is not defined.
tl_update.proto:18:17: "mtproto.PredUpdateNewEncryptedMessage" is not defined.
tl_update.proto:19:17: "mtproto.PredUpdateChannel" is not defined.
tl_update.proto:20:17: "mtproto.PredUpdateChannelMessageViews" is not defined.
tl_update.proto:21:17: "mtproto.PredUpdateChannelTooLong" is not defined.
tl_update.proto:22:17: "mtproto.PredUpdateReadChannelInbox" is not defined.
tl_update.proto:23:17: "mtproto.PredUpdateReadChannelOutbox" is not defined.
tl_update.proto:24:17: "mtproto.PredUpdateNewChannelMessage" is not defined.

but the application is compiling and working fine.

but when trying the latest layer 109 the above output is preceeded by:

types.tl.proto:1633:18: "TypemessagesSearchCounter" is not defined.
types.tl.proto:1882:18: "TypeBytes" is not defined.
types.tl.proto:3416:18: "TypeBytes" is not defined.
types.tl.proto:6231:18: "TypeBytes" is not defined.
types.tl.proto:6253:18: "TypeBytes" is not defined.
types.tl.proto:6842:18: "TypeBytes" is not defined.
types.tl.proto:6861:9: "TypeType" is not defined.
types.tl.proto:6867:9: "TypeType" is not defined.
types.tl.proto:6873:9: "TypeType" is not defined.
types.tl.proto:6888:9: "TypeType" is not defined.
types.tl.proto:6894:9: "TypeType" is not defined.
types.tl.proto:6899:9: "TypeType" is not defined.
types.tl.proto:6906:9: "TypeType" is not defined.
types.tl.proto:8206:18: "TypeBytes" is not defined.

when then trying to compile the application it errors out with the following:

convs.tl.go:3051:10: undefined: TypeRecentMeUrl
convs.tl.go:3066:10: undefined: TypeHelpRecentMeUrls
convs.tl.go:3069:10: undefined: TypeInputSingleMedia
convs.tl.go:3072:10: undefined: TypeWebAuthorization
convs.tl.go:3075:10: undefined: TypeAccountWebAuthorizations
convs.tl.go:3078:10: undefined: TypeInputMessage
convs.tl.go:3089:10: undefined: TypeInputDialogPeer
convs.tl.go:3098:10: undefined: TypeDialogPeer
convs.tl.go:3107:10: undefined: TypeMessagesFoundStickerSets
convs.tl.go:3116:10: undefined: TypeFileHash
convs.tl.go:3116:10: too many errors

any hints would be highly appreciated!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.