在创建 Auth_key 之后,我发现在继续之前确保我连接到最近的数据中心是最简单的方法。此外,您应该发送一个 InitConnection 命令以及您的代码将使用的当前层(API 版本)。
这是我发送的示例:
msg = TL.invokewithlayer(@layer, TL.initconnection(@app_id, @device_model, @system_version, @app_version, @lang_code, TL.help_getnearestdc))
现在,在您发送此之前,这里有一些背景:
1) Telegram 服务器在 TL 中通信,它基本上是一种自定义开发的编码方案,Telegram 用它来表达一切:从命令到所有类型。您需要自己构建一个解码器和编码器,用于将原始字节转换为 TL,反之亦然。
2) Telegram 不时更新他们的 API 版本,但他们网站上的版本已经过时了。您可以轻松获得其官方开源项目的最新 API 规范。特别是来自 Webogram 的 this 和 this 对于生成您自己的 TL 解析器非常有用。当前层版本为45
3) 因此,当您发送 init + nearestDc 请求时,这很可能是您的第一个 MTproto 加密消息,因此您需要创建一个新的随机 64 位数字作为会话密钥,但您还需要一个有效的 server_salt ...
4) 您可能在创建 Auth_Key 时跳过了此步骤,但您可以从中创建一个有效的初始 server_salt:
server_salt = substr(new_nonce, 0, 8) XOR substr(server_nonce, 0, 8)
you can look that up here: STEP 9) DH key exchange complete
5) 你现在有了 server_salt,一个新的随机 64 位 session_id,你想发送以下内容:
msg = TL.invokewithlayer(@layer, TL.initconnection(@app_id, @device_model, @system_version, @app_version, @lang_code, TL.help_getnearestdc))
MTProto 格式为:auth_id + msg_key + enc_payload
enc_payload = AES_IGE_enc(payload)
payload = salt + session_id + msg_id + seq_no + len(msg) + msg + padding
以上内容可以从here获取
6) 现在您希望得到一个告诉您最近的 dc_id 的结果,如果这与 dc_id = 2 不同(通常 dc_id = 2 是您开始时的默认值),那么您需要断开连接并启动一个新的连接到您的新 dc_id 并重新生成连接到此新 dc 的 auth_key。您的 dc_ids 指向 Telegram 数据中心 IP 地址列表['149.154.175.50', '149.154.167.51', '149.154.175.100', '149.154.167.91', '149.154.171.5']
7) 连接到正确的“最近的 dc”后,您现在可以执行 User Authorization,以授权(您的)手机号码使用您的新 Telegram 客户端访问 Telegram
8) 您发送到 Telegram 的所有后续消息都将使用相同的 session_id 和 salt 发送,并像之前一样遵循 MTProto 加密步骤
9) 请注意,盐通常只能保存 24 小时。服务器将向您发送一个新的盐,您可以用它来替换过期的盐。 session_id 通常是长期存在的。
10) 一旦掌握了这几个步骤,您就可以尝试发送消息或获取联系人列表和消息历史记录
干杯。