| 503 | string, |
| 504 | (msg: Api.Message, trigger?: Api.Message) => Promise<void> |
| 505 | > = { |
| 506 | biko: async (msg: Api.Message) => { |
| 507 | const client = await getGlobalClient(); |
| 508 | if (!client) { |
| 509 | await msg.edit({ |
| 510 | text: "❌ Telegram 客户端未初始化", |
| 511 | parseMode: "html", |
| 512 | }); |
| 513 | return; |
| 514 | } |
| 515 | |
| 516 | const firstLine = String(msg.message || msg.text || "") |
| 517 | .split(/\r?\n/)[0] |
| 518 | ?.trim(); |
| 519 | const parts = firstLine.split(/\s+/).filter(Boolean); |
| 520 | const args = parts.slice(1); |
| 521 | |
| 522 | if (args[0] === "help" || args.length !== 4) { |
| 523 | await msg.edit({ |
| 524 | text: helpText, |
| 525 | parseMode: "html", |
| 526 | linkPreview: false, |
| 527 | }); |
| 528 | return; |
| 529 | } |
| 530 | |
| 531 | const [sourceChatRaw, sourceUserRaw, requestedCountRaw, targetChatRaw] = |
| 532 | args; |
| 533 | |
| 534 | try { |
| 535 | const requestedCount = parseRequestedCount(requestedCountRaw); |
| 536 | await msg.edit({ |
| 537 | text: "🔄 正在解析对话和用户...", |
| 538 | parseMode: "html", |
| 539 | }); |
| 540 | |
| 541 | const sourceChat = await resolveChatTarget( |
| 542 | client, |
| 543 | sourceChatRaw, |
| 544 | "来源对话", |
| 545 | ); |
| 546 | const targetChat = await resolveChatTarget( |
| 547 | client, |
| 548 | targetChatRaw, |
| 549 | "目标对话", |
| 550 | ); |
| 551 | const sourceUser = await resolveSourceUser(client, sourceUserRaw); |
| 552 | |
| 553 | const statusLines = [ |
| 554 | `🔄 正在整理消息...`, |
| 555 | `<b>来源对话:</b> ${htmlEscape(sourceChat.display)}`, |
| 556 | `<b>来源用户:</b> ${htmlEscape(sourceUser.display)}`, |
| 557 | `<b>目标对话:</b> ${htmlEscape(targetChat.display)}`, |
| 558 | `<b>消息数:</b> ${requestedCount}`, |
| 559 | ]; |
| 560 | |
| 561 | if (sourceUser.manualMode) { |
| 562 | statusLines.push("⚠️ 源用户实体解析失败,已切换为手动过滤模式"); |
nothing calls this directly
no test coverage detected