mytglib 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -4
- package/dist/index.js +1 -1
- package/package.json +1 -4
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ npm install
|
|
|
21
21
|
npm run build
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
构建结果位于 `dist/index.js`。Webpack 会打包本仓库源码,使用 Terser 压缩,并对标识符和字符串数组进行混淆;`@mtcute/node` 等运行时依赖保持为外部 ESM 依赖,不会重复打入产物。构建不生成 source map,发布包仅包含 `dist`、`README.md
|
|
24
|
+
构建结果位于 `dist/index.js`。Webpack 会打包本仓库源码,使用 Terser 压缩,并对标识符和字符串数组进行混淆;`@mtcute/node` 等运行时依赖保持为外部 ESM 依赖,不会重复打入产物。构建不生成 source map,发布包仅包含 `dist`、`README.md` 和 `package.json`。
|
|
25
25
|
|
|
26
26
|
## 离线示例
|
|
27
27
|
|
|
@@ -102,13 +102,112 @@ try {
|
|
|
102
102
|
}
|
|
103
103
|
```
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
iOS 默认使用 `ios.CURRENT_VERSION` 数组中的最新版本。需要覆盖时,必须同时传入
|
|
106
|
+
`appVersion` 与 `overrideLayer`,两者会作为同一版本配置应用:
|
|
106
107
|
|
|
107
|
-
|
|
108
|
+
```js
|
|
109
|
+
const iosCore = new CoreClient({
|
|
110
|
+
clientType: "ios",
|
|
111
|
+
phone: "+12025550123",
|
|
112
|
+
proxy: { type: "http", host: "127.0.0.1", port: 8080 },
|
|
113
|
+
sessionDirPath: resolve("telegram-sessions"),
|
|
114
|
+
langCode: "en",
|
|
115
|
+
appVersion: "13.0 (35000) ",
|
|
116
|
+
overrideLayer: 229,
|
|
117
|
+
deviceTokenResolver: async () => ({ token: "AQIDBA==" }),
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
覆盖值仅适用于 iOS;`appVersion` 必须是非空字符串,`overrideLayer` 必须是正数 int32。
|
|
122
|
+
如果传入的 `appVersion` 已存在于内置数组,其 layer 必须与数组中的官方配对一致。
|
|
123
|
+
`langCode` 同样只支持 iOS,并且必须来自公开的 `iosLangPackLanguages`;省略时继续根据
|
|
124
|
+
手机号自动选择。手工覆盖只改变 Telegram `langCode`,`systemLangCode` 仍按手机号地区推断。
|
|
125
|
+
|
|
126
|
+
`sendCode()` 可选接收 `codeSettings` 对象,用于覆盖本次 `auth.sendCode` 请求的五个布尔能力字段。Android 保持原有默认值:`allowFirebase`、`allowFlashcall`、`allowMissedCall` 为 `true`,`currentNumber`、`unknownNumber` 为 `false`。
|
|
127
|
+
|
|
128
|
+
iOS 默认显式传递 `allowFlashcall: true`、`allowFirebase: true` 和固定的 `logoutTokens: []`。调用方把 `allowFlashcall` 或 `allowFirebase` 设为 `false` 时仍会显式保留该值;`allowMissedCall`、`currentNumber`、`unknownNumber` 仅在设为 `true` 时传递,设为 `false` 或未提供时会从请求对象中省略。`logoutTokens` 不接受调用方覆盖,每次请求都会创建新的空数组。
|
|
129
|
+
|
|
130
|
+
```js
|
|
131
|
+
const response = await core.sendCode({
|
|
132
|
+
allowFirebase: false,
|
|
133
|
+
allowFlashcall: true,
|
|
134
|
+
allowMissedCall: false,
|
|
135
|
+
currentNumber: false,
|
|
136
|
+
unknownNumber: true,
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
传入的五个能力字段必须是 boolean;Android 的 `allowAppHash` 以及 iOS 的 APNs `token`、`appSandbox` 仍由平台配置自动生成,不属于可覆盖字段。根据 [mtcute 0.31.0 `sendCode` API](https://ref.mtcute.dev/funcs/_mtcute_core.highlevel_methods.sendCode.html),future auth tokens 的参数类型是 `Uint8Array[]`;本库直接构造 raw `codeSettings`,因此对应的 `logoutTokens` 使用原生 JavaScript 数组,并在请求对象中固定保留空数组 `[]`,而不是 TL JSON 包装对象或字符串数组。mtcute 0.31.0 只会序列化非空的 `logoutTokens`,因此空数组不会设置可选 TL vector flag。
|
|
141
|
+
|
|
142
|
+
`deviceTokenResolver` 和 `recaptchaMobileTokenResolver` 必须返回包含非空字符串 `token` 字段的对象,对象可保留求解服务返回的 `errorMessage`、`message` 等附加字段。无有效 token 时会抛出 `TypeError`,其 `cause` 是 resolver 返回的完整结果;reCAPTCHA token 最长为 16,384 个字符。
|
|
143
|
+
|
|
144
|
+
reCAPTCHA 由客户端的全局 network middleware 处理,不限于 `auth.sendCode`。任意尚未包装且允许重放的 RPC 返回格式严格匹配 `403 RECAPTCHA_CHECK_<action>__<siteKey>` 时,middleware 会调用 `recaptchaMobileTokenResolver`,使用 `invokeWithReCaptcha` 包装原请求,并通过后续的 `networkMiddlewares.basic()` 链重试一次。`account.updatePasswordSettings` 和 `payments.assignAppStoreTransaction` 不会被该 middleware 自动重放;已有 `invokeWithReCaptcha` 请求或包装请求再次失败时也不会重复求解、再次包装或形成无限重试。middleware 自动生成的 `invokeWithReCaptcha` 日志记录错误文本、完整原请求、真实响应和错误。
|
|
145
|
+
|
|
146
|
+
`auth.sentCodePaymentRequired` 不是 RPC 错误,而是 `auth.sendCode` 的合法返回。它表示由于所在国家或运营商的短信验证成本较高,官方客户端必须先完成 Telegram Premium 购买流程才能继续登录或注册。原始响应中的 `storeProduct`、`premiumDays`、`currency` 和 `amount` 描述商品与价格,`phoneCodeHash` 保留后续授权上下文,`supportEmailAddress` 和 `supportEmailSubject` 用于联系支持。
|
|
147
|
+
|
|
148
|
+
`sendCode()` 或 `verifyEmailCode()` 收到该响应时,会像保存 `phoneCodeHash` 一样把三个必需字段原子地挂载到 `core.inputStore`:`{ premiumDays, currency, amount }`。普通 `auth.sentCode`、`auth.sentCodeSuccess`、授权成功及成功销毁客户端时会清空该状态。
|
|
149
|
+
|
|
150
|
+
使用 iOS 客户端通过 StoreKit 完成购买并取得 App Store receipt 后,使用 `submitCredentials({ receipt })` 调用 `payments.assignAppStoreTransaction`。`receipt` 必须是 base64 字符串,方法会严格解码为 Telegram `bytes`;`inputStore` 自动读取 `core.inputStore`,`restore` 固定为 `false`,方法不会从调用参数读取这些字段。未先收到 `auth.sentCodePaymentRequired`,或缓存字段无效时,方法会在发送 RPC 前抛出 `TypeError`。方法返回原始 Telegram `Updates`,并从 `updateSentPhoneCode.sentCode` 同步 `phoneCodeHash` 和 `inputStore`;若返回 `auth.sentCodeSuccess`,也会沿用现有登录通知逻辑。
|
|
151
|
+
|
|
152
|
+
```js
|
|
153
|
+
const updates = await core.submitCredentials({
|
|
154
|
+
receipt: appStoreReceiptBase64,
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`payments.assignAppStoreTransaction` 及其购买流程仅供 Telegram 官方客户端使用。receipt 必须与 App Store 应用、商品和签名环境匹配;本库只封装 receipt 转换、TL 请求及返回状态处理,不负责发起 StoreKit 购买。
|
|
159
|
+
|
|
160
|
+
`auth.sentCodeTypeFirebaseSms` 表示短信尚未发送。调用方必须先完成 Firebase 设备验证,再通过 `core.client.call()` 调用 `auth.requestFirebaseSms` 请求短信验证码;本库当前不封装 SafetyNet、Google Play Integrity 或 iOS push secret 的获取流程。`examples/login.js` 遇到该响应时会明确停止,避免在验证码尚未发送时进入输入流程。
|
|
161
|
+
|
|
162
|
+
`timeout`、`maxRetryCount` 和 `abortSignal` 是所有 mytglib 登录 RPC 的统一调用参数。`timeout` 默认为 `30000`,必须是正安全整数毫秒;`maxRetryCount` 默认为 `0`,必须是非负安全整数;`abortSignal` 默认为 `undefined`,传入时必须是 `AbortSignal`。客户端创建后会通过原始 `TelegramClient.withParams()` 生成 `core.client`,登录流程和通过 `core.client.call()` 发出的请求都会使用这些参数。密码更新的最终 `account.updatePasswordSettings` 会把 `maxRetryCount` 强制为 `0`,避免 internal/flood retry middleware 重放;前置的只读 `account.getPassword` 仍使用客户端配置。它们只作用于 RPC,不处理 `connect()` 超时,也不会取消正在进行的 `connect()`。
|
|
108
163
|
|
|
109
164
|
`sessionDirPath` 是必传的会话主目录。路径已存在时必须是目录;路径不存在时会在初始化过程中递归创建。`init()` 会按照 `<主目录>/<+手机号>/<+手机号>.session` 创建 SQLite 会话文件,然后依次解析设备 token 并连接客户端。连接成功后可通过 `core.sessionFilePath` 直接取得当前客户端使用的 SQLite 文件路径;连接前该属性为 `null`。登录相关公共异步方法均返回原始 Telegram TL 响应。`core.rawClient` 保存原始 `TelegramClient`,只负责 `connect()`、`notifyLoggedIn()` 和 `destroy()`;`core.client` 保存 `withParams()` 返回的 RPC Proxy。`core.destroy()` 始终销毁 `rawClient`,不会在 `@mtcute/node` 0.31.0 的包装对象上调用 `destroy()`,从而避免私有字段错误。无论成功或失败,都应在 `finally` 中调用 `core.destroy()`,永久关闭连接、定时器和存储资源。销毁成功后两个客户端引用都会恢复为 `null`,SQLite 文件路径仍保留在 `core.sessionFilePath` 上。
|
|
110
165
|
|
|
111
|
-
`
|
|
166
|
+
初始化 `.session` 时,库会在同一个 SQLite 数据库内创建单行 `session_metadata` 表,并在授权成功后写入账号 Metadata;不会自动创建 JSON 文件或第二个数据库连接。每次初始化都会让 `session_file` 与当前会话路径一致;初始化配置与首次授权时间作为注册快照保留,`reg_time` 取最终产生授权的注册或登录方法入口调用时间。重新授权只刷新用户名、姓名、Premium 状态及非空运行态字段。`first_name` 和 `last_name` 在注册或登录授权成功后自动从 Telegram 用户信息同步,缺失时写入 `NULL`。`completion_type` 只有 `sign_up`(实际执行 `auth.signUp` 创建账号)和 `login`(已有账号完成授权)两种;缺失字段写入 `NULL`。最新 `phone_code_hash`、已验证登录邮箱、成功使用的 reCAPTCHA token 和两步验证密码会随运行生命周期同步更新。数据库写入失败时会按 `50ms`、`150ms`、`300ms` 额外重试三次;Telegram RPC 已成功但 Metadata 最终仍失败时,可调用 `await core.retrySaveSessionMetadata()` 重试当前全部待写操作。
|
|
167
|
+
|
|
168
|
+
授权成功后、调用 `destroy()` 之前,可主动将数据库内的 Metadata 同步为与 `.session` 同目录、同名主干的 JSON:
|
|
169
|
+
|
|
170
|
+
```js
|
|
171
|
+
const jsonFilePath = await core.syncSessionJson();
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
`syncSessionJson()` 无参数并返回 JSON 文件路径。JSON 中的 `session_str` 为可与 Telethon StringSession v1 兼容的字符串,`reg_time` 按中国标准时间转为 `YYYY-MM-DD`;当前转换仅支持项目使用的 IPv4 主 DC。底层 `.session` 仍是 mtcute SQLite,不会被转换成 Telethon SQLite。输出文件包含 auth key 和明文两步验证密码,会以 `0600` 权限原子替换,必须与 `.session` 一样按密码保护。
|
|
175
|
+
|
|
176
|
+
`sendCode()`、`changePassword()`、`setNewPassword()`、`confirmPasswordEmail()`、`sendEmailCode()`、`verifyEmailCode()`、`verifyPhoneCode()`、`register()` 和 `submitCredentials()` 会直接向 `onLog` 发出 `started`、`completed` 或 `failed` 事件。日志不做脱敏,记录真实输入、响应和序列化后的错误;调用方需要自行控制日志文件的访问权限和生命周期。
|
|
177
|
+
|
|
178
|
+
## 两步验证密码
|
|
179
|
+
|
|
180
|
+
Telegram 的两步验证密码流程先调用
|
|
181
|
+
[`account.getPassword`](https://core.telegram.org/method/account.getPassword)
|
|
182
|
+
取得 SRP 参数,再调用
|
|
183
|
+
[`account.updatePasswordSettings`](https://core.telegram.org/method/account.updatePasswordSettings)
|
|
184
|
+
更新密码。本库复用 `@mtcute/node` 的 SRP 与密码哈希实现,但会先按官方要求校验 2048-bit 安全素数、生成元和 `srp_B`,并把不足 256 字节的合法 `srp_B` 左侧补零后再计算 proof。
|
|
185
|
+
|
|
186
|
+
已有密码时使用 `changePassword()`:
|
|
187
|
+
|
|
188
|
+
```js
|
|
189
|
+
await core.changePassword({
|
|
190
|
+
currentPassword: "old password",
|
|
191
|
+
newPassword: "new password",
|
|
192
|
+
hint: "new hint",
|
|
193
|
+
});
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
尚未启用密码时改用 `setNewPassword()`:
|
|
197
|
+
|
|
198
|
+
```js
|
|
199
|
+
await core.setNewPassword({
|
|
200
|
+
newPassword: "first password",
|
|
201
|
+
});
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
两个方法都返回 `Promise<void>`,密码字符串不会被裁剪,且会随真实输入写入操作日志。`changePassword()` 省略 `hint` 时发送空字符串;`setNewPassword()` 省略 `hint` 时默认使用 `ATGHUB`,并且默认不设置恢复邮箱。需要恢复邮箱时显式传入 `email`;服务端返回 `EMAIL_UNCONFIRMED_%d` 后使用:
|
|
205
|
+
|
|
206
|
+
```js
|
|
207
|
+
await core.confirmPasswordEmail({ emailCode: "123456" });
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
确认成功后才会把密码写入 Metadata 的 `two_fa` 字段。该字段按需求保存明文密码,请妥善保护 `.session` 文件。最终密码更新不会进入 `maxRetryCount` 控制的 internal/flood 自动重试,也不会因 reCAPTCHA challenge 被 middleware 重放。若账户已有 Telegram Passport 数据,方法会在提交前拒绝改密,避免未重加密 Passport secret 导致数据失联。
|
|
112
211
|
|
|
113
212
|
## 代理检查
|
|
114
213
|
|
|
@@ -126,6 +225,13 @@ console.log(result);
|
|
|
126
225
|
|
|
127
226
|
`checkProxy` 会并行检查所选平台的全部五个 Telegram 主 DC,并关闭每个已建立的连接。
|
|
128
227
|
|
|
228
|
+
## Rust fork
|
|
229
|
+
|
|
230
|
+
`vendor/grammers` 是为后续 Tauri/Rust 桌面端准备的内置 fork,其中项目自有的
|
|
231
|
+
`grammers-core` 承载 `src` 对应的 Rust 实现。它目前尚未接入本 npm 包的 JavaScript 运行路径,
|
|
232
|
+
也不会进入 npm 发布包。上游基线、本地覆盖层、可重复的同步流程和验证范围见
|
|
233
|
+
[grammers fork 维护文档](docs/grammers-fork.md)。
|
|
234
|
+
|
|
129
235
|
## 测试
|
|
130
236
|
|
|
131
237
|
```bash
|