MCPcopy Create free account
hub / github.com/TeleBoxOrg/TeleBox_Plugins / cleanDeletedMember

Method cleanDeletedMember

clean/clean.ts:259–324  ·  view source on GitHub ↗
(client: any, msg: Api.Message, cleanMembers: boolean = false)

Source from the content-addressed store, hash-verified

257 }
258
259 // 群组已注销账号清理
260 // 根因修复:必须传完整 User(含 accessHash),不能只传裸 userId;
261 // banUser 失败返回 false 时不能算「已清理」。
262 private async cleanDeletedMember(client: any, msg: Api.Message, cleanMembers: boolean = false): Promise<void> {
263 const chat = await msg.getChat();
264 if (!chat || !(chat instanceof Api.Chat || chat instanceof Api.Channel)) {
265 await this.sendError(msg, "此命令仅在群组中可用");
266 return;
267 }
268
269 await this.editMessage(msg, cleanMembers
270 ? "🔍 正在扫描并清理群组已注销账号..."
271 : "🔍 正在扫描群组已注销账号...");
272
273 // 用完整 chat 实体,避免 EditBanned 拿不到 channel access_hash
274 const chatEntity = await client.getInputEntity(chat);
275 if (cleanMembers && !await this.checkBanPermission(client, chat)) {
276 await this.sendError(msg, "没有封禁用户权限,无法执行清理");
277 return;
278 }
279
280 let foundCount = 0;
281 let removedCount = 0;
282 let failedCount = 0;
283 const deletedUsers: Array<{id: string, username?: string, ok?: boolean, err?: string}> = [];
284
285 // 优先用完整 chat 实体迭代,保证 participant 上带 accessHash
286 const participants = client.iterParticipants(chat);
287 for await (const participant of participants) {
288 if (participant instanceof Api.User && participant.deleted) {
289 foundCount++;
290 const entry: {id: string, username?: string, ok?: boolean, err?: string} = {
291 id: participant.id.toString(),
292 username: participant.username || "已注销账号",
293 };
294
295 if (cleanMembers) {
296 try {
297 // 传完整 User,不要 participant.id(已注销账号 getInputEntity(id) 会失败)
298 const ok = await banUser(client, chatEntity, participant);
299 if (ok) {
300 removedCount++;
301 entry.ok = true;
302 // 踢出:封禁后再解封,避免永久 ban 列表堆积(与 kickUser 一致)
303 try {
304 await unbanUser(client, chatEntity, participant);
305 } catch {
306 /* 解封失败不影响已移出 */
307 }
308 } else {
309 failedCount++;
310 entry.ok = false;
311 entry.err = "封禁接口返回失败";
312 }
313 await sleep(150);
314 } catch (error: any) {
315 if (error.message?.includes("FLOOD_WAIT")) {
316 await this.handleFloodWait(msg, error);

Callers 1

handleDeletedCleanMethod · 0.95

Calls 5

sendErrorMethod · 0.95
editMessageMethod · 0.95
checkBanPermissionMethod · 0.95
handleFloodWaitMethod · 0.95
sleepFunction · 0.70

Tested by

no test coverage detected