import { aiPlatformCatalog } from '@geo/shared-types' import { probeAIAccountSession, probePublishAccountSession, silentRefreshAIAccountSession, 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 code = typeof input.error?.code === 'string' ? input.error.code : '' if (code === 'doubao_challenge_required') { return 'challenge' } 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') { return 'auth_failure' } if (code === 'wangyihao_token_missing') { return 'ok' } 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 aiAdapter: PlatformAdapter = { async probe(account, partition) { return await probeAIAccountSession(account, partition) }, async silentRefresh(account, partition) { return await silentRefreshAIAccountSession(account, partition) }, classifyFailure, } 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 probeAIAccountSession(account, partition) }, async silentRefresh(account, partition) { return await silentRefreshAIAccountSession(account, partition) }, classifyFailure: classifyDoubaoFailure, } const wenxinAdapter: PlatformAdapter = { async probe(account, partition) { return await probeAIAccountSession(account, partition) }, async silentRefresh(account, partition) { return await silentRefreshAIAccountSession(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 : aiPlatformCatalog.some((item) => item.id === platform) ? aiAdapter : genericAdapter, ]), ) export function getPlatformAdapter(platformId: string): PlatformAdapter { return adapterRegistry.get(platformId) ?? genericAdapter }