MCPcopy Index your code
hub / github.com/QLHazyCoder/FlowPilot / handlePollEmail

Function handlePollEmail

content/qq-mail.js:57–132  ·  view source on GitHub ↗
(step, payload)

Source from the content-addressed store, hash-verified

55// ============================================================
56
57async function handlePollEmail(step, payload) {
58 const { senderFilters, subjectFilters, maxAttempts, intervalMs, excludeCodes = [] } = payload;
59 const excludedCodeSet = new Set(excludeCodes.filter(Boolean));
60
61 log(`步骤 ${step}:开始轮询邮箱(最多 ${maxAttempts} 次,每 ${intervalMs / 1000} 秒一次)`);
62
63 // Wait for mail list to load
64 try {
65 await waitForElement('.mail-list-page-item', 10000);
66 log(`步骤 ${step}:邮件列表已加载`);
67 } catch {
68 throw new Error('邮件列表未加载完成,请确认 QQ 邮箱已打开收件箱。');
69 }
70
71 // Step 1: Snapshot existing mail IDs BEFORE we start waiting for new email
72 const existingMailIds = getCurrentMailIds();
73 log(`步骤 ${step}:已将当前 ${existingMailIds.size} 封邮件标记为旧邮件快照`);
74
75 // Fallback after just 3 attempts (~10s). In practice, the email is usually
76 // already in the list but has the same mailid (page was already open).
77 const FALLBACK_AFTER = 3;
78
79 for (let attempt = 1; attempt <= maxAttempts; attempt++) {
80 log(`步骤 ${step}:正在轮询 QQ 邮箱,第 ${attempt}/${maxAttempts} 次`);
81
82 // Refresh inbox (skip on first attempt, list is fresh)
83 if (attempt > 1) {
84 await refreshInbox();
85 await sleep(800);
86 }
87
88 const allItems = document.querySelectorAll('.mail-list-page-item[data-mailid]');
89 const useFallback = attempt > FALLBACK_AFTER;
90
91 // Phase 1 (attempt 1~3): only look at NEW emails (not in snapshot)
92 // Phase 2 (attempt 4+): fallback to first matching email in list
93 for (const item of allItems) {
94 const mailId = item.getAttribute('data-mailid');
95
96 if (!useFallback && existingMailIds.has(mailId)) continue;
97
98 const sender = (item.querySelector('.cmp-account-nick')?.textContent || '').toLowerCase();
99 const subject = (item.querySelector('.mail-subject')?.textContent || '').toLowerCase();
100 const digest = item.querySelector('.mail-digest')?.textContent || '';
101
102 const senderMatch = senderFilters.some(f => sender.includes(f.toLowerCase()));
103 const subjectMatch = subjectFilters.some(f => subject.includes(f.toLowerCase()));
104
105 if (senderMatch || subjectMatch) {
106 const code = extractVerificationCode(subject + ' ' + digest);
107 if (code) {
108 if (excludedCodeSet.has(code)) {
109 log(`步骤 ${step}:跳过排除的验证码:${code}`, 'info');
110 continue;
111 }
112 const source = useFallback && existingMailIds.has(mailId) ? '回退首封匹配邮件' : '新邮件';
113 log(`步骤 ${step}:已找到验证码:${code}(来源:${source},主题:${subject.slice(0, 40)})`, 'ok');
114 return { ok: true, code, emailTimestamp: Date.now(), mailId };

Callers 1

qq-mail.jsFile · 0.70

Calls 6

logFunction · 0.85
waitForElementFunction · 0.85
sleepFunction · 0.85
getCurrentMailIdsFunction · 0.70
refreshInboxFunction · 0.70
extractVerificationCodeFunction · 0.70

Tested by

no test coverage detected