| 372 | Date.now() - lastProgressActivity >= RESULT_IDLE_MS * 3 && |
| 373 | Date.now() - lastFinalActivity >= RESULT_IDLE_MS |
| 374 | ) { |
| 375 | break; |
| 376 | } |
| 377 | } |
| 378 | |
| 379 | if (finalMessages.size === 0) { |
| 380 | return { lastId, forwarded: false, reason: "timeout" }; |
| 381 | } |
| 382 | |
| 383 | const sortedMessages = Array.from(finalMessages.values()).sort( |
| 384 | (a, b) => a.id - b.id, |
| 385 | ); |
| 386 | |
| 387 | let forwarded = false; |
| 388 | const fallbackTexts: string[] = []; |
| 389 | |
| 390 | for (let i = 0; i < sortedMessages.length; i += 100) { |
| 391 | const chunk = sortedMessages.slice(i, i + 100); |
| 392 | const ids = chunk.map((m) => m.id); |
| 393 | |
| 394 | try { |
| 395 | await forwardChunk(client, originMsg.peerId, ids); |
| 396 | forwarded = true; |
| 397 | } catch { |
| 398 | const snippet = chunk |
| 399 | .map((m) => m.message?.trim()) |
| 400 | .filter(Boolean) |
| 401 | .join("\n\n"); |
| 402 | fallbackTexts.push( |
| 403 | snippet.length |
| 404 | ? snippet |
| 405 | : `⚠️ 未能转发 @${BOT_USERNAME} 的多媒体结果,请前往私聊机器人查看。`, |
| 406 | ); |
| 407 | } |
| 408 | } |
| 409 | |
| 410 | if (!forwarded && fallbackTexts.length) { |
| 411 | try { |
| 412 | await client.sendMessage(originMsg.peerId, { |
| 413 | message: `📨 @${BOT_USERNAME} 返回内容:\n\n${fallbackTexts.join("\n\n")}`, |
| 414 | replyTo: originMsg.id, |
| 415 | }); |
| 416 | forwarded = true; |
| 417 | } catch {} |
| 418 | } |
| 419 | |
| 420 | return { |
| 421 | lastId, |
| 422 | forwarded, |
| 423 | reason: forwarded ? undefined : "timeout", |
| 424 | }; |
| 425 | } |
| 426 | |
| 427 | class ParseHubPlugin extends Plugin { |
| 428 | |
| 429 | description: string = `\n${pluginName}\n\n${helpText}`; |
| 430 | cmdHandlers: Record<string, (msg: Api.Message) => Promise<void>> = { |
| 431 | parsehub: async (msg: Api.Message) => { |
nothing calls this directly
no test coverage detected