(step, payload)
| 541 | } |
| 542 | |
| 543 | async function handlePollEmail(step, payload) { |
| 544 | const { |
| 545 | senderFilters = [], |
| 546 | subjectFilters = [], |
| 547 | maxAttempts = 5, |
| 548 | intervalMs = 3000, |
| 549 | filterAfterTimestamp = 0, |
| 550 | excludeCodes = [], |
| 551 | targetEmail = '', |
| 552 | } = payload || {}; |
| 553 | |
| 554 | const excludedCodeSet = new Set(excludeCodes.filter(Boolean)); |
| 555 | const filterAfterMinute = normalizeMinuteTimestamp(Number(filterAfterTimestamp) || 0); |
| 556 | |
| 557 | log(`步骤 ${step}:开始轮询 Gmail(最多 ${maxAttempts} 次)`); |
| 558 | if (filterAfterMinute) { |
| 559 | log(`步骤 ${step}:仅尝试 ${new Date(filterAfterMinute).toLocaleString('zh-CN', { hour12: false })} 及之后时间的邮件。`); |
| 560 | } |
| 561 | |
| 562 | let initialRows = await ensureInboxReady(step); |
| 563 | if (!initialRows.length) { |
| 564 | await refreshInbox(step); |
| 565 | initialRows = await ensureInboxReady(step); |
| 566 | } |
| 567 | |
| 568 | if (!initialRows.length) { |
| 569 | throw new Error('Gmail 收件箱列表未加载完成,请确认当前已打开 Gmail 收件箱。'); |
| 570 | } |
| 571 | |
| 572 | const categoryOrder = getCategoryScanOrder(); |
| 573 | const existingMailIdsByCategory = new Map(); |
| 574 | |
| 575 | for (const category of categoryOrder) { |
| 576 | const activeCategory = await activateCategoryTab(step, category.key); |
| 577 | const rows = collectThreadRows(); |
| 578 | existingMailIdsByCategory.set(activeCategory.key, getCurrentMailIds(rows)); |
| 579 | log(`步骤 ${step}:已记录 Gmail 分类 ${activeCategory.label} 的 ${rows.length} 封旧邮件快照`); |
| 580 | } |
| 581 | |
| 582 | for (let attempt = 1; attempt <= maxAttempts; attempt++) { |
| 583 | log(`步骤 ${step}:正在轮询 Gmail,第 ${attempt}/${maxAttempts} 次`); |
| 584 | |
| 585 | if (attempt > 1) { |
| 586 | await refreshInbox(step); |
| 587 | } |
| 588 | |
| 589 | const useFallback = attempt > GMAIL_FALLBACK_AFTER; |
| 590 | |
| 591 | for (const category of categoryOrder) { |
| 592 | const activeCategory = await activateCategoryTab(step, category.key); |
| 593 | const rows = collectThreadRows(); |
| 594 | const existingMailIds = existingMailIdsByCategory.get(activeCategory.key) || new Set(); |
| 595 | |
| 596 | for (let index = 0; index < rows.length; index++) { |
| 597 | const row = rows[index]; |
| 598 | const rowId = getRowFingerprint(row, index); |
| 599 | const rowTimestamp = getRowTimestamp(row); |
| 600 | const rowMinute = normalizeMinuteTimestamp(rowTimestamp || 0); |
no test coverage detected