修复 LuckMail 验证码轮询与重试逻辑
This commit is contained in:
+78
-9
@@ -3509,21 +3509,16 @@ async function resolveLuckmailVerificationMail(client, token, filters = {}, toke
|
||||
return match || null;
|
||||
}
|
||||
|
||||
async function pollLuckmailVerificationCode(step, state, pollPayload = {}) {
|
||||
async function legacyPollLuckmailVerificationCode(step, state, pollPayload = {}) {
|
||||
const purchase = getCurrentLuckmailPurchase(state);
|
||||
if (!purchase?.token) {
|
||||
throw new Error('LuckMail 当前没有可用 token,请先执行步骤 3 购买邮箱。');
|
||||
}
|
||||
|
||||
const client = createLuckmailClient(state);
|
||||
const maxAttempts = Math.max(1, Number(pollPayload.maxAttempts) || 5);
|
||||
const intervalMs = Math.max(1000, Number(pollPayload.intervalMs) || 3000);
|
||||
const filters = {
|
||||
afterTimestamp: pollPayload.filterAfterTimestamp || 0,
|
||||
senderFilters: pollPayload.senderFilters || [],
|
||||
subjectFilters: pollPayload.subjectFilters || [],
|
||||
excludeCodes: pollPayload.excludeCodes || [],
|
||||
};
|
||||
const maxAttempts = Math.max(1, Number(pollPayload.maxAttempts) || 3);
|
||||
const intervalMs = Math.max(15000, Number(pollPayload.intervalMs) || 15000);
|
||||
const excludedCodes = new Set((pollPayload.excludeCodes || []).filter(Boolean));
|
||||
|
||||
const initialCursor = normalizeLuckmailMailCursor((await getState()).currentLuckmailMailCursor);
|
||||
if (!initialCursor.messageId && !initialCursor.receivedAt) {
|
||||
@@ -3587,6 +3582,80 @@ async function pollLuckmailVerificationCode(step, state, pollPayload = {}) {
|
||||
throw lastError || new Error(`步骤 ${step}:未在 LuckMail 邮箱中找到新的匹配验证码。`);
|
||||
}
|
||||
|
||||
async function pollLuckmailVerificationCode(step, state, pollPayload = {}) {
|
||||
const purchase = getCurrentLuckmailPurchase(state);
|
||||
if (!purchase?.token) {
|
||||
throw new Error('LuckMail 当前没有可用 token,请先执行步骤 3 购买邮箱。');
|
||||
}
|
||||
|
||||
const client = createLuckmailClient(state);
|
||||
const maxAttempts = Math.max(1, Number(pollPayload.maxAttempts) || 3);
|
||||
const intervalMs = Math.max(15000, Number(pollPayload.intervalMs) || 15000);
|
||||
const excludedCodes = new Set((pollPayload.excludeCodes || []).filter(Boolean));
|
||||
|
||||
const initialCursor = normalizeLuckmailMailCursor((await getState()).currentLuckmailMailCursor);
|
||||
if (!initialCursor.messageId && !initialCursor.receivedAt) {
|
||||
const mailList = await client.user.getTokenMails(purchase.token);
|
||||
const baselineCursor = buildLuckmailBaselineCursor(mailList?.mails || []);
|
||||
await setLuckmailMailCursorState(baselineCursor);
|
||||
if (baselineCursor?.messageId || baselineCursor?.receivedAt) {
|
||||
await addLog(`步骤 ${step}:LuckMail 已保存当前邮箱旧邮件快照,后续仅使用新收到的验证码。`, 'info');
|
||||
}
|
||||
}
|
||||
|
||||
let lastError = null;
|
||||
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
||||
throwIfStopped();
|
||||
await addLog(`步骤 ${step}:正在通过 LuckMail /code 接口轮询验证码(${attempt}/${maxAttempts})...`, 'info');
|
||||
|
||||
try {
|
||||
const tokenCode = await client.user.getTokenCode(purchase.token);
|
||||
const remoteEmail = String(tokenCode?.email_address || '').trim().toLowerCase();
|
||||
const expectedEmail = String(purchase.email_address || state?.email || '').trim().toLowerCase();
|
||||
if (remoteEmail && expectedEmail && remoteEmail !== expectedEmail) {
|
||||
throw new Error(`步骤 ${step}:LuckMail token 对应邮箱与当前邮箱不一致。当前邮箱:${expectedEmail};token 邮箱:${remoteEmail}`);
|
||||
}
|
||||
|
||||
const tokenMail = tokenCode.verification_code && tokenCode.mail && !tokenCode.mail.verification_code
|
||||
? {
|
||||
...tokenCode.mail,
|
||||
verification_code: tokenCode.verification_code,
|
||||
}
|
||||
: tokenCode.mail;
|
||||
const code = String(tokenCode?.verification_code || tokenMail?.verification_code || '').trim();
|
||||
const cursor = normalizeLuckmailMailCursor((await getState()).currentLuckmailMailCursor);
|
||||
|
||||
if (!code || !tokenMail) {
|
||||
lastError = new Error(`步骤 ${step}:LuckMail /code 接口暂未返回新的验证码。`);
|
||||
} else if (excludedCodes.has(code)) {
|
||||
lastError = new Error(`步骤 ${step}:LuckMail 返回的验证码 ${code} 已试过,等待 15 秒后再次轮询。`);
|
||||
} else if (!isLuckmailMailNewerThanCursor(tokenMail, cursor)) {
|
||||
lastError = new Error(`步骤 ${step}:LuckMail /code 返回的最新邮件仍是旧验证码。`);
|
||||
} else {
|
||||
await setLuckmailMailCursorState(buildLuckmailMailCursor(tokenMail));
|
||||
return {
|
||||
ok: true,
|
||||
code,
|
||||
emailTimestamp: normalizeLuckmailTimestamp(tokenMail.received_at) || Date.now(),
|
||||
mailId: tokenMail.message_id,
|
||||
};
|
||||
}
|
||||
} catch (err) {
|
||||
if (isStopError(err)) {
|
||||
throw err;
|
||||
}
|
||||
lastError = err;
|
||||
await addLog(`步骤 ${step}:LuckMail /code 轮询失败:${err.message}`, 'warn');
|
||||
}
|
||||
|
||||
if (attempt < maxAttempts) {
|
||||
await sleepWithStop(intervalMs);
|
||||
}
|
||||
}
|
||||
|
||||
throw lastError || new Error(`步骤 ${step}:未在 LuckMail /code 接口中获取到新的验证码。`);
|
||||
}
|
||||
|
||||
function summarizeCloudflareTempEmailMessagesForLog(messages) {
|
||||
return (messages || [])
|
||||
.slice()
|
||||
|
||||
@@ -268,9 +268,11 @@
|
||||
getRemainingTimeMs: getStep8RemainingTimeResolver(state?.oauthUrl || '', visibleStep),
|
||||
requestFreshCodeFirst: false,
|
||||
targetEmail: fixedTargetEmail,
|
||||
resendIntervalMs: (mail.provider === HOTMAIL_PROVIDER || mail.provider === '2925')
|
||||
? 0
|
||||
: STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS,
|
||||
resendIntervalMs: mail.provider === LUCKMAIL_PROVIDER
|
||||
? 15000
|
||||
: ((mail.provider === HOTMAIL_PROVIDER || mail.provider === '2925')
|
||||
? 0
|
||||
: STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -149,6 +149,7 @@
|
||||
|
||||
const shouldRequestFreshCodeFirst = ![
|
||||
HOTMAIL_PROVIDER,
|
||||
LUCKMAIL_PROVIDER,
|
||||
CLOUDFLARE_TEMP_EMAIL_PROVIDER,
|
||||
].includes(mail.provider);
|
||||
|
||||
@@ -157,9 +158,11 @@
|
||||
sessionKey: verificationSessionKey,
|
||||
disableTimeBudgetCap: mail.provider === '2925',
|
||||
requestFreshCodeFirst: shouldRequestFreshCodeFirst,
|
||||
resendIntervalMs: (mail.provider === HOTMAIL_PROVIDER || mail.provider === '2925')
|
||||
? 0
|
||||
: STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS,
|
||||
resendIntervalMs: mail.provider === LUCKMAIL_PROVIDER
|
||||
? 15000
|
||||
: ((mail.provider === HOTMAIL_PROVIDER || mail.provider === '2925')
|
||||
? 0
|
||||
: STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -917,7 +917,7 @@
|
||||
getLegacyVerificationResendCountDefault(step, { requestFreshCodeFirst })
|
||||
)
|
||||
: getConfiguredVerificationResendCount(step, state, { requestFreshCodeFirst });
|
||||
const maxSubmitAttempts = 15;
|
||||
const maxSubmitAttempts = mail.provider === LUCKMAIL_PROVIDER ? 3 : 15;
|
||||
const resendIntervalMs = Math.max(0, Number(options.resendIntervalMs) || 0);
|
||||
let lastResendAt = Number(options.lastResendAt) || 0;
|
||||
|
||||
@@ -1002,6 +1002,12 @@
|
||||
throw new Error(`步骤 ${step}:验证码连续失败,已达到 ${maxSubmitAttempts} 次重试上限。`);
|
||||
}
|
||||
|
||||
if (mail.provider === LUCKMAIL_PROVIDER) {
|
||||
await addLog(`步骤 ${step}:LuckMail 验证码提交失败,等待 15 秒后重新轮询 /code 接口(${attempt + 1}/${maxSubmitAttempts})...`, 'warn');
|
||||
await sleepWithStop(15000);
|
||||
continue;
|
||||
}
|
||||
|
||||
const remainingBeforeResendMs = resendIntervalMs > 0 && lastResendAt > 0
|
||||
? Math.max(0, resendIntervalMs - (Date.now() - lastResendAt))
|
||||
: 0;
|
||||
|
||||
Reference in New Issue
Block a user