(options: StreamProcessOptions)
| 304 | onlySearch: boolean; |
| 305 | maxRemove?: number; |
| 306 | statusCallback?: (message: string, forceUpdate?: boolean) => Promise<void>; |
| 307 | modeNames: { [key: string]: string }; |
| 308 | } |
| 309 | |
| 310 | interface StreamProcessResult { |
| 311 | totalScanned: number; |
| 312 | totalFound: number; |
| 313 | totalRemoved: number; |
| 314 | users: UserInfo[]; |
| 315 | failedUsers: FailedUserInfo[]; |
| 316 | } |
| 317 | |
| 318 | async function streamProcessMembers(options: StreamProcessOptions): Promise<StreamProcessResult> { |
| 319 | const { client, chatEntity, mode, day, adminIds, onlySearch, maxRemove, statusCallback, modeNames } = options; |
| 320 | const result: StreamProcessResult = { |
| 321 | totalScanned: 0, |
| 322 | totalFound: 0, |
| 323 | totalRemoved: 0, |
| 324 | users: [], |
| 325 | failedUsers: [] |
| 326 | }; |
| 327 | let offset = 0; |
| 328 | const limit = 200; |
| 329 | let hasMore = true; |
| 330 | let batchNumber = 0; |
| 331 | try { |
| 332 | while (hasMore) { |
| 333 | batchNumber++; |
| 334 | if (statusCallback) { |
| 335 | await statusCallback( |
| 336 | `🔍 扫描第 ${batchNumber} 批 (${modeNames[mode]}) | 已扫描: ${result.totalScanned} | 已找到: ${result.totalFound}${!onlySearch ? ` | 已移出: ${result.totalRemoved}` : ''}`, |
| 337 | true |
| 338 | ); |
| 339 | } |
| 340 | const participantsResult = await client.invoke(new Api.channels.GetParticipants({ |
| 341 | channel: chatEntity, |
| 342 | filter: new Api.ChannelParticipantsRecent(), |
| 343 | offset: offset, |
| 344 | limit: limit, |
| 345 | hash: 0 as any, |
| 346 | })); |
| 347 | if ("users" in participantsResult && participantsResult.users.length > 0) { |
| 348 | const users = participantsResult.users as Api.User[]; |
| 349 | result.totalScanned += users.length; |
| 350 | for (const user of users) { |
| 351 | const uid = Number(user.id); |
| 352 | if (adminIds.has(uid)) continue; |
| 353 | let shouldProcess = false; |
| 354 | if (mode === "1") { |
| 355 | const lastOnlineDays = getLastOnlineDays(user); |
| 356 | if (lastOnlineDays !== null && lastOnlineDays > day) { |
| 357 | shouldProcess = true; |
| 358 | } |
| 359 | } else if (mode === "2") { |
| 360 | try { |
| 361 | const userEntity = await client.getInputEntity(uid); |
| 362 | const minDate = Math.floor(Date.now() / 1000) - day * 24 * 60 * 60; |
| 363 | const res = await client.invoke(new Api.messages.Search({ |
no test coverage detected