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 层。

几个问题:

  1. 给定一个电报 api 架构文件,有没有办法从架构中确定它是哪一层?或者你只是 "simply have to know"?
  2. 调用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;