import { aiPlatformCatalog } from "@geo/shared-types"; import { probePublishAccountSession, silentRefreshPublishAccountSession, type PublishAccountIdentity, } from "./account-binder"; import type { AuthProbeResult, PlatformFailureClassification, } from "./auth-types"; export interface PlatformFailureInput { summary?: string | null; error?: Record | null; message?: string | null; } export interface PlatformAdapter { probe(account: PublishAccountIdentity, partition: string): Promise; silentRefresh(account: PublishAccountIdentity, partition: string): Promise; classifyFailure(input: PlatformFailureInput): PlatformFailureClassification; } function normalizeFailureText(input: PlatformFailureInput): string { const values = [ input.summary, input.message, typeof input.error?.code === "string" ? input.error.code : null, typeof input.error?.reason_code === "string" ? input.error.reason_code : null, typeof input.error?.message === "string" ? input.error.message : null, typeof input.error?.detail === "string" ? input.error.detail : null, typeof input.error?.page_error === "string" ? input.error.page_error : null, typeof input.error?.verify_scene === "string" ? input.error.verify_scene : null, ]; return values .filter((value): value is string => typeof value === "string" && Boolean(value.trim())) .join(" | ") .toLowerCase(); } function classifyFailure(input: PlatformFailureInput): PlatformFailureClassification { const text = normalizeFailureText(input); if (!text) { return "ok"; } if ( /(verify_scene|verification required|captcha|challenge|验证码|滑块|人机验证|安全验证|请完成验证|短信验证|扫码验证)/i.test(text) ) { return "challenge"; } if ( /(not_logged_in|unauthorized|unauthenticated|login redirect|login required|signin|sign in|expired|401|登录态失效|登录超时|请重新登录|请先登录|未登录)/i .test(text) ) { return "auth_failure"; } if ( /(network|timeout|timed out|failed to fetch|econnreset|econnrefused|enotfound|dns|socket hang up|502|503|504)/i .test(text) ) { return "network"; } return "ok"; } function classifyDoubaoFailure(input: PlatformFailureInput): PlatformFailureClassification { const text = normalizeFailureText(input); if (!text) { return "ok"; } if ( /(rate limited|rate limit|too many requests|request limit|frequency limit|请求过于频繁|频率过快|访问过于频繁|限流|风控|服务繁忙|请稍后|稍后再试)/i .test(text) ) { return "risk_control"; } return classifyFailure(input); } function classifyWenxinFailure(input: PlatformFailureInput): PlatformFailureClassification { const text = normalizeFailureText(input); if (!text) { return "ok"; } if ( /(当前访问环境存在异常|访问环境存在异常|环境存在异常|更换浏览器再尝试提问|当前环境异常|访问受限|环境异常)/i .test(text) ) { return "risk_control"; } return classifyFailure(input); } function classifyBaijiahaoFailure(input: PlatformFailureInput): PlatformFailureClassification { const code = typeof input.error?.code === "string" ? input.error.code : ""; if (code === "baijiahao_challenge_required") { return "challenge"; } if (code === "baijiahao_not_logged_in" || code === "baijiahao_token_missing") { return "auth_failure"; } if (code.startsWith("baijiahao_")) { return "ok"; } return classifyFailure(input); } function classifySohuhaoFailure(input: PlatformFailureInput): PlatformFailureClassification { const code = typeof input.error?.code === "string" ? input.error.code : ""; if (code === "sohuhao_not_logged_in") { return "auth_failure"; } if (code === "sohuhao_challenge_required") { return "challenge"; } if (code.startsWith("sohuhao_")) { return "ok"; } return classifyFailure(input); } function classifyQiehaoFailure(input: PlatformFailureInput): PlatformFailureClassification { const code = typeof input.error?.code === "string" ? input.error.code : ""; if (code === "qiehao_challenge_required") { return "challenge"; } if (code === "qiehao_not_logged_in" || code === "qiehao_cookie_missing") { return "auth_failure"; } if (code.startsWith("qiehao_")) { return "ok"; } return classifyFailure(input); } function classifyBilibiliFailure(input: PlatformFailureInput): PlatformFailureClassification { const code = typeof input.error?.code === "string" ? input.error.code : ""; if (code === "bilibili_not_logged_in" || code === "bilibili_csrf_missing") { return "auth_failure"; } if (code.startsWith("bilibili_")) { return "ok"; } return classifyFailure(input); } function classifyJuejinFailure(input: PlatformFailureInput): PlatformFailureClassification { const code = typeof input.error?.code === "string" ? input.error.code : ""; if (code === "juejin_not_logged_in") { return "auth_failure"; } if (code.startsWith("juejin_")) { return "ok"; } return classifyFailure(input); } function classifyWangyihaoFailure(input: PlatformFailureInput): PlatformFailureClassification { const code = typeof input.error?.code === "string" ? input.error.code : ""; if (code === "wangyihao_not_logged_in" || code === "wangyihao_token_missing") { return "auth_failure"; } if (code === "wangyihao_challenge_required") { return "challenge"; } if (code.startsWith("wangyihao_")) { return "ok"; } return classifyFailure(input); } function classifyWeixinGzhFailure(input: PlatformFailureInput): PlatformFailureClassification { const code = typeof input.error?.code === "string" ? input.error.code : ""; if (code === "weixin_gzh_not_logged_in") { return "auth_failure"; } if (code === "weixin_gzh_challenge_required") { return "challenge"; } if (code.startsWith("weixin_gzh_")) { return "ok"; } return classifyFailure(input); } function classifyZolFailure(input: PlatformFailureInput): PlatformFailureClassification { const code = typeof input.error?.code === "string" ? input.error.code : ""; if (code === "zol_not_logged_in") { return "auth_failure"; } if (code === "zol_challenge_required") { return "challenge"; } if (code.startsWith("zol_")) { return "ok"; } return classifyFailure(input); } function classifyDongchediFailure(input: PlatformFailureInput): PlatformFailureClassification { const code = typeof input.error?.code === "string" ? input.error.code : ""; if (code === "dongchedi_not_logged_in") { return "auth_failure"; } if (code === "dongchedi_challenge_required") { return "challenge"; } if (code.startsWith("dongchedi_")) { return "ok"; } return classifyFailure(input); } const genericAdapter: PlatformAdapter = { async probe(account, partition) { return await probePublishAccountSession(account, partition); }, async silentRefresh(account, partition) { return await silentRefreshPublishAccountSession(account, partition); }, classifyFailure, }; const doubaoAdapter: PlatformAdapter = { async probe(account, partition) { return await probePublishAccountSession(account, partition); }, async silentRefresh(account, partition) { return await silentRefreshPublishAccountSession(account, partition); }, classifyFailure: classifyDoubaoFailure, }; const wenxinAdapter: PlatformAdapter = { async probe(account, partition) { return await probePublishAccountSession(account, partition); }, async silentRefresh(account, partition) { return await silentRefreshPublishAccountSession(account, partition); }, classifyFailure: classifyWenxinFailure, }; const baijiahaoAdapter: PlatformAdapter = { async probe(account, partition) { return await probePublishAccountSession(account, partition); }, async silentRefresh(account, partition) { return await silentRefreshPublishAccountSession(account, partition); }, classifyFailure: classifyBaijiahaoFailure, }; const sohuhaoAdapter: PlatformAdapter = { async probe(account, partition) { return await probePublishAccountSession(account, partition); }, async silentRefresh(account, partition) { return await silentRefreshPublishAccountSession(account, partition); }, classifyFailure: classifySohuhaoFailure, }; const qiehaoAdapter: PlatformAdapter = { async probe(account, partition) { return await probePublishAccountSession(account, partition); }, async silentRefresh(account, partition) { return await silentRefreshPublishAccountSession(account, partition); }, classifyFailure: classifyQiehaoFailure, }; const bilibiliAdapter: PlatformAdapter = { async probe(account, partition) { return await probePublishAccountSession(account, partition); }, async silentRefresh(account, partition) { return await silentRefreshPublishAccountSession(account, partition); }, classifyFailure: classifyBilibiliFailure, }; const wangyihaoAdapter: PlatformAdapter = { async probe(account, partition) { return await probePublishAccountSession(account, partition); }, async silentRefresh(account, partition) { return await silentRefreshPublishAccountSession(account, partition); }, classifyFailure: classifyWangyihaoFailure, }; const juejinAdapter: PlatformAdapter = { async probe(account, partition) { return await probePublishAccountSession(account, partition); }, async silentRefresh(account, partition) { return await silentRefreshPublishAccountSession(account, partition); }, classifyFailure: classifyJuejinFailure, }; const weixinGzhAdapter: PlatformAdapter = { async probe(account, partition) { return await probePublishAccountSession(account, partition); }, async silentRefresh(account, partition) { return await silentRefreshPublishAccountSession(account, partition); }, classifyFailure: classifyWeixinGzhFailure, }; const zolAdapter: PlatformAdapter = { async probe(account, partition) { return await probePublishAccountSession(account, partition); }, async silentRefresh(account, partition) { return await silentRefreshPublishAccountSession(account, partition); }, classifyFailure: classifyZolFailure, }; const dongchediAdapter: PlatformAdapter = { async probe(account, partition) { return await probePublishAccountSession(account, partition); }, async silentRefresh(account, partition) { return await silentRefreshPublishAccountSession(account, partition); }, classifyFailure: classifyDongchediFailure, }; const adapterRegistry = new Map( [ ...aiPlatformCatalog.map((platform) => platform.id), "toutiaohao", "baijiahao", "sohuhao", "qiehao", "zhihu", "wangyihao", "jianshu", "bilibili", "juejin", "smzdm", "weixin_gzh", "zol", "dongchedi", ].map((platform) => [ platform, platform === "doubao" ? doubaoAdapter : platform === "wenxin" ? wenxinAdapter : platform === "baijiahao" ? baijiahaoAdapter : platform === "sohuhao" ? sohuhaoAdapter : platform === "qiehao" ? qiehaoAdapter : platform === "wangyihao" ? wangyihaoAdapter : platform === "bilibili" ? bilibiliAdapter : platform === "juejin" ? juejinAdapter : platform === "weixin_gzh" ? weixinGzhAdapter : platform === "zol" ? zolAdapter : platform === "dongchedi" ? dongchediAdapter : genericAdapter, ]), ); export function getPlatformAdapter(platformId: string): PlatformAdapter { return adapterRegistry.get(platformId) ?? genericAdapter; }