Telegram.org API: 在 Python 中调用方法 invokeWithLayer
Telegram.org API: calling method invokeWithLayer in Python
参考 这是我迄今为止找到的最好的电报文档!谢谢。
我正在尝试创建一个 Python 库来调用 telegram.org。我可以按照上面 link 中的描述进行身份验证,但是 运行 遇到方法响应问题 returning 仅在前一层中找到的格式。换句话说,我的客户端正在从 api 的一层调用方法,但服务器正在使用来自较旧的 api 层的数据格式进行响应。我通过在较旧的 api 层文件中搜索 return id 来确认这一点。
{
"id": "571849917",
"params": [
{
"name": "phone_registered",
"type": "Bool"
},
{
"name": "phone_code_hash",
"type": "string"
}
],
"predicate": "auth.sentCode",
"type": "auth.SentCode"
},
我的客户期望的格式是这样的:
{
"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"
},
因此,我阅读了电报文档,我需要调用 invokeWithLayer 以确保客户端和服务器同步 api 层。
几个问题:
- 给定一个电报 api 架构文件,有没有办法从架构中确定它是哪一层?或者你只是 "simply have to know"?
- 调用invokeWithLayer时如何格式化'query'参数?必须先序列化查询吗?
这是我的 initConnection 代码,我在其中序列化每个方法,然后再将其用作参数。不幸的是,反应并不积极。第一反应是:
('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}]})
第二个回复是:
{u'req_msg_id': 6312441942040617984L, u'result': {u'error_message': 'INPUT_METHOD_INVALID', u'error_code': 400}})
...和代码:
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)
谢谢!
1) 我从这里得到最新的电报模式:
https://github.com/telegramdesktop/tdesktop/blob/master/Telegram/Resources/scheme.tl
您也可以构建自己的 TL 解析器库,以您想要的方式工作,并在版本更改时轻松将其更新到最新版本。
2) 要发送 X 查询参数,您只需序列化并附加到层查询调用的末尾。
示例:(来自我的 Telegram Elixir 库)
msg = TL.invokewithlayer(layer, TL.initconnection(app_id, device_model, system_version, app_version, lang_code, TL.help_getconfig))
可以看到相关Telegram schema的定义:
initConnection#69796de9 {X:Type} api_id:int device_model:string system_version:string app_version:string lang_code:string query:!X = X;
invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;
参考
我正在尝试创建一个 Python 库来调用 telegram.org。我可以按照上面 link 中的描述进行身份验证,但是 运行 遇到方法响应问题 returning 仅在前一层中找到的格式。换句话说,我的客户端正在从 api 的一层调用方法,但服务器正在使用来自较旧的 api 层的数据格式进行响应。我通过在较旧的 api 层文件中搜索 return id 来确认这一点。
{
"id": "571849917",
"params": [
{
"name": "phone_registered",
"type": "Bool"
},
{
"name": "phone_code_hash",
"type": "string"
}
],
"predicate": "auth.sentCode",
"type": "auth.SentCode"
},
我的客户期望的格式是这样的:
{
"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"
},
因此,我阅读了电报文档,我需要调用 invokeWithLayer 以确保客户端和服务器同步 api 层。
几个问题:
- 给定一个电报 api 架构文件,有没有办法从架构中确定它是哪一层?或者你只是 "simply have to know"?
- 调用invokeWithLayer时如何格式化'query'参数?必须先序列化查询吗?
这是我的 initConnection 代码,我在其中序列化每个方法,然后再将其用作参数。不幸的是,反应并不积极。第一反应是:
('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}]})
第二个回复是:
{u'req_msg_id': 6312441942040617984L, u'result': {u'error_message': 'INPUT_METHOD_INVALID', u'error_code': 400}})
...和代码:
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)
谢谢!
1) 我从这里得到最新的电报模式: https://github.com/telegramdesktop/tdesktop/blob/master/Telegram/Resources/scheme.tl
您也可以构建自己的 TL 解析器库,以您想要的方式工作,并在版本更改时轻松将其更新到最新版本。
2) 要发送 X 查询参数,您只需序列化并附加到层查询调用的末尾。
示例:(来自我的 Telegram Elixir 库)
msg = TL.invokewithlayer(layer, TL.initconnection(app_id, device_model, system_version, app_version, lang_code, TL.help_getconfig))
可以看到相关Telegram schema的定义:
initConnection#69796de9 {X:Type} api_id:int device_model:string system_version:string app_version:string lang_code:string query:!X = X;
invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;