拆分腾讯会话 Cookie 与复核截图辅助逻辑

This commit is contained in:
yml
2026-05-04 14:15:13 +08:00
parent ab33272cac
commit 37299a2797
5 changed files with 176 additions and 69 deletions
+8 -69
View File
@@ -19,6 +19,9 @@ import {
isRetryableQrCaptureError,
logBrowserSessionDebug,
} from './session-login-shared.js'
import {
loadCookieMapFromContext,
} from './session-cookie-map.js'
import {
buildSessionPayload as buildSessionPayloadBase,
} from './session-payload.js'
@@ -30,6 +33,9 @@ import {
import {
saveRedeemArtifacts,
} from './session-proof.js'
import {
ensureReviewScreenshot,
} from './session-review.js'
import {
capturePageCaptchaForOcr,
isCaptchaRejectedResult,
@@ -46,6 +52,7 @@ import {
import { recognizeTencentCaptcha } from './ocr.js'
import {
hasRedeemCredential,
resolveInitialQrSessionState,
resolveSessionNotice,
resolveSessionStatus,
resolveTencentSessionExpiresAt,
@@ -560,10 +567,7 @@ async function ensureLoginTab(page, loginType) {
function applyInitialQrSessionState(session) {
resetTencentSessionAutoClose(session)
session.status = 'waiting_scan'
session.notice = `请使用${getLoginTypeLabel(session.loginType)}扫码登录`
session.updatedAt = new Date().toISOString()
session.expiresAt = Date.now() + SESSION_TTL_MS
Object.assign(session, resolveInitialQrSessionState(session.loginType))
}
function armRedeemedSessionAutoClose(session) {
@@ -884,71 +888,6 @@ function buildSessionPayload(session, { includeQrImage = true } = {}) {
})
}
async function ensureReviewScreenshot(session, activityInfo) {
const roleId = String(activityInfo?.role?.roleId || '').trim()
const roleName = String(activityInfo?.role?.roleName || '').trim()
const signature = `${session.loginType}|${roleId}|${roleName}`
if (session.lastReview?.screenshotPath && session.lastReview?.signature === signature) {
return
}
const screenshotPath = path.join(session.sessionDir, 'role-review.png')
try {
await session.page.screenshot({
path: screenshotPath,
fullPage: true,
})
session.lastReview = {
screenshotPath,
capturedAt: new Date().toISOString(),
roleId,
roleName,
signature,
}
} catch (error) {
logBrowserSessionDebug('reviewScreenshot.capture.error', {
sessionId: session.sessionId,
message: error instanceof Error ? error.message : String(error),
})
}
}
async function loadCookieMapFromContext(browserContext) {
const cookies = await browserContext.cookies([
'https://df.qq.com',
'https://ssl.captcha.qq.com',
'https://graph.qq.com',
'https://milo.qq.com',
])
const cookieMap = {}
for (const cookie of cookies) {
if (!cookie?.name) {
continue
}
cookieMap[String(cookie.name)] = String(cookie.value || '')
}
if (!cookieMap.acctype) {
cookieMap.acctype = 'qc'
}
if (!cookieMap.appid) {
cookieMap.appid = '101491592'
}
if (cookieMap.openid && cookieMap.access_token && !cookieMap.iegams_milo_proxylogin_qc) {
cookieMap.iegams_milo_proxylogin_qc =
`${cookieMap.appid}_$$_${cookieMap.openid}_$$_${cookieMap.access_token}`
}
return cookieMap
}
async function fillRedeemCodeInBrowser(page, code) {
await prepareRedeemCodeFill(page, code, { ensureActivityInfoReady })
}