In reference to How to implement authorization using a Telegram API? This is the best telegram documentation I have yet to find! Thanks for that.
I am attempting to create a Python library to make calls to telegram.org. I can authenticate as described in the above link but ran into issues with method responses returning in a format found only in a previous layer. In other words, my client is calling a method from one layer of the api but the server is responding with a data format from an older api layer. I confirmed this by searching an older api layer file for the return id.
{
"id": "571849917",
"params": [
{
"name": "phone_registered",
"type": "Bool"
},
{
"name": "phone_code_hash",
"type": "string"
}
],
"predicate": "auth.sentCode",
"type": "auth.SentCode"
},
The format my client is expecting is this:
{
"id": "-269659687",
"params": [
{
"name": "phone_registered",
"type": "Bool"
},
{
"name": "phone_code_hash",
"type": "string"
},
{
"name": "send_call_timeout",
"type": "int"
},
{
"name": "is_password",
"type": "Bool"
}
],
"predicate": "auth.sentCode",
"type": "auth.SentCode"
},
So, I read in the telegram docs I need to call invokeWithLayer to make sure the client and server have their api layers in synch.
Several questions:
- Given a telegram api schema file, is there a way to determine from the schema which layer it is? Or do you just "simply have to know"?
- When calling invokeWithLayer how do you format the 'query' parameter? Do you have to serialize the query first?
Here is my initConnection code where I serialize each method before using it as a parameter. Unfortunately, the response is not favorable. The first response is:
('initConnection - msg: ', {u'messages': [{u'body': {u'first_msg_id': 6312441942040617984L, u'unique_id': 986871592203578887L, u'server_salt': 7658270006181864880L}, u'seqno': 1, u'msg_id': 6312441944354392065L, u'bytes': 28}, {u'body': {u'msg_ids': [6312441942040617984L]}, u'seqno': 2, u'msg_id': 6312441944354450433L, u'bytes': 20}]})
The second response is:
{u'req_msg_id': 6312441942040617984L, u'result': {u'error_message': 'INPUT_METHOD_INVALID', u'error_code': 400}})
...and the code:
def initConnection(self, config):
'''Set the API layer and initialize the connection'''
# get the required config data
api_layer = config.getint('App data', 'api_layer')
api_id = config.getint('App data', 'api_id')
version = config.get('App data', 'version')
print
print('----------------------------------------------')
print('initConnection - api_layer: ', api_layer)
print('initConnection - api_id: ', api_id)
print('initConnection - version: ', version)
# serialize a candidate method as a parameter. It doesn't
# matter what it is so we will use something simple like get_future_salts.
simpleQuery=TL.tl_serialize_method('get_future_salts', num=3)
# serialize the initConnection method
initConnectionQuery = TL.api_serialize_method('initConnection', api_id=api_id,
device_model='Unknown UserAgent',
system_version='Unknown Platform',
app_version=version,
lang_code='en-US',
query=simpleQuery)
# perform the initialization
msg = self.method_call('invokeWithLayer', layer=api_layer, query=initConnectionQuery)
print('initConnection - msg: ', msg)
Thanks!