mytglib 1.1.1 → 1.1.2

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 CHANGED
@@ -173,6 +173,102 @@ const jsonFilePath = await core.syncSessionJson();
173
173
 
174
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
175
 
176
+ ## 手机号状态检查
177
+
178
+ `checkPhoneStatus()` 是独立于注册流程的根导出方法。Telegram 没有为此提供纯查询接口;
179
+ 本方法使用一个已授权账号的 mtcute `.session` 文件和对应 JSON,根据
180
+ [`account.sendChangePhoneCode`](https://core.telegram.org/method/account.sendChangePhoneCode)
181
+ 的响应或 RPC 错误推断号码状态:
182
+
183
+ ```js
184
+ import { checkPhoneStatus } from "mytglib";
185
+
186
+ const result = await checkPhoneStatus({
187
+ phone: "+12025550123",
188
+ sessionFilePath: "/secure/account/account.session",
189
+ sessionJsonFilePath: "/secure/account/account.json",
190
+ proxy: "socks5://user:password@127.0.0.1:1080",
191
+ timeout_ms: 30_000,
192
+ abort_signal: new AbortController().signal,
193
+ });
194
+
195
+ console.log(result);
196
+ ```
197
+
198
+ JSON 必须包含 `syncSessionJson()` 生成的 `session_str`、`session_file`、`app_id`、`app_hash`
199
+ 和客户端配置;自定义 iOS 版本还会携带 `override_layer` 以便完整还原。
200
+ 方法会以只读方式打开 `.session`,校验其主 DC、IPv4、端口和 auth key 与 JSON 的规范
201
+ `session_str` 一致,再把必要连接状态复制到 `MemoryStorage`;不会迁移或修改原 SQLite 的表和主数据库
202
+ 内容。不过 SQLite 在 WAL 模式下即使只读打开也可能创建或更新 `-shm` 等 sidecar,因此这不等同于
203
+ “文件系统零写入”。用于请求的临时客户端不会注册 reCAPTCHA middleware,也不会求解或主动重放
204
+ challenge;正常主 DC 路径只调用一次 `client.call()`,不做应用层重试。mtcute 仍可能为 DC 迁移或
205
+ MTProto 连接恢复重发底层请求,这不是 `maxRetryCount` 控制的应用层重试。请求的
206
+ `settings` 固定为
207
+ `{ _: "codeSettings", allowFlashcall: true, allowFirebase: false, logoutTokens: [] }`。
208
+ `timeout_ms` 默认为 `30000`。会话导出、连接和目标 RPC 等受控异步阶段各自使用完整的
209
+ `timeout_ms` 上限,而不是共享整个方法的总 deadline;资源清理也使用独立的同值上限,并且不会因
210
+ 调用方取消而跳过。`abort_signal` 会取消清理前的受控异步阶段;请求重试次数和 flood 自动等待均固定
211
+ 为 `0`。客户端无论成功或失败都会在返回前尝试有界销毁。
212
+
213
+ Rust 对应入口是 `grammers_core` 根导出的 `check_phone_status()`。它读取项目生成的 `.grammers`
214
+ 会话和同目录 JSON,校验 JSON 中的 `session_str` 与只读会话的主 DC、地址和 auth key 一致,随后
215
+ 把授权 key 与连接配置复制到 `MemorySession`;原 `.grammers` 以只读方式
216
+ 打开,不会迁移或写回。输入字段使用 snake_case,结果序列化时使用与 npm 一致的 camelCase:
217
+
218
+ ```rust,no_run
219
+ use grammers_core::{AbortSignal, PhoneStatusCheckInput, Proxy, check_phone_status};
220
+
221
+ # async fn example() -> Result<(), Box<dyn std::error::Error>> {
222
+ let abort_signal = AbortSignal::new();
223
+ let mut input = PhoneStatusCheckInput::new(
224
+ "+12025550123",
225
+ "/secure/account/account.grammers",
226
+ "/secure/account/account.json",
227
+ );
228
+ input.proxy = Some(Proxy::from_url(
229
+ "socks5://user:password@127.0.0.1:1080",
230
+ ).expect("valid proxy URL"));
231
+ input.timeout_ms = 30_000;
232
+ input.abort_signal = Some(abort_signal);
233
+
234
+ let result = check_phone_status(input).await;
235
+ println!("{}", serde_json::to_string_pretty(&result)?);
236
+ # Ok(())
237
+ # }
238
+ ```
239
+
240
+ Rust 的 `timeout_ms` 覆盖文件读取、只读会话加载、连接及目标 RPC;每个阶段各自使用完整上限,而非
241
+ 共享整个方法的总 deadline。`abort_signal` 也覆盖清理前的这些异步阶段;sender cleanup 使用独立的
242
+ 同值上限且不会因调用方取消而跳过,因此超时或取消后仍会先尝试有界资源清理再返回。该方法使用
243
+ `NoRetries`,且不自动等待 `FLOOD_WAIT`。`abort_signal` 标记为 serde skip,若
244
+ 输入来自 JSON,必须在反序列化后由 Rust 代码赋值。`proxy` 可使用 `Proxy::from_url()`,也可直接
245
+ 构造 `Proxy`。
246
+
247
+ 这不是无副作用的号码查询:未注册号码可能因此真实收到验证码。调用方必须只在获授权的账号和号码
248
+ 范围内使用,并自行控制调用频率,避免触发发送滥用或 `FLOOD_WAIT`。
249
+
250
+ 返回对象固定包含 `waitTime`、原样传入的 `phone`、ISO 时间字符串 `startedAt`/`endedAt`、
251
+ `durationMs`、`status` 和 `error`。`status` 可能为 `PHONE_NUMBER_OCCUPIED`、
252
+ `PHONE_NUMBER_NO_OCCUPIED`、`PHONE_NUMBER_INVALID`、`PHONE_NUMBER_BANNED`、`FLOOD_WAIT`
253
+ 或 `OTHER_ERROR`。`RECAPTCHA_CHECK_signup` 不会触发求解或再次请求,也不用于推断号码状态,而是按
254
+ `OTHER_ERROR` 返回;`FLOOD_WAIT` 的秒数写入 `waitTime`;其他异常同样不会向外抛出,而是在 `error`
255
+ 中保留可用的 `message`、`name`、`code`、`text` 和 `seconds`。
256
+
257
+ 授权成功后可调用 Telegram 官方的 [`account.getAuthorizations`](https://core.telegram.org/method/account.getAuthorizations)
258
+ 获取当前账号的全部登录会话,并把响应保存到同目录的 `<session stem>.authorizations.json`:
259
+
260
+ ```js
261
+ const authorizationsJsonPath = await core.syncAuthorizationsJson();
262
+ ```
263
+
264
+ `syncAuthorizationsJson()` 无参数并返回 JSON 文件路径;Rust 对应入口为
265
+ `CoreClient::sync_authorizations_json()`。文件保留 mtcute 的 camelCase 响应结构(根节点为
266
+ `account.authorizations`),仅按官方 [`Authorization`](https://core.telegram.org/constructor/authorization)
267
+ 构造器的 `date_created`(会话创建时间)语义,把 `dateCreated` 的 Unix 秒时间戳按 UTC 转为补零的
268
+ `YYYY-MM` 字符串;为避免 JavaScript `Long` 的 JSON 对象结构和数字精度差异,`hash` 统一写为
269
+ 十进制字符串,其他授权字段保持原始响应值。该方法要求客户端已初始化并完成授权,应在
270
+ `destroy()` 前调用。
271
+
176
272
  `sendCode()`、`changePassword()`、`setNewPassword()`、`confirmPasswordEmail()`、`sendEmailCode()`、`verifyEmailCode()`、`verifyPhoneCode()`、`register()` 和 `submitCredentials()` 会直接向 `onLog` 发出 `started`、`completed` 或 `failed` 事件。日志不做脱敏,记录真实输入、响应和序列化后的错误;调用方需要自行控制日志文件的访问权限和生命周期。
177
273
 
178
274
  ## 两步验证密码