@skrillex1224/chrome-article-publish-extension 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +226 -0
- package/dist/adapters/index.d.ts +1125 -0
- package/dist/adapters/index.js +1900 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/chunk-7Q3KKWUB.js +602 -0
- package/dist/chunk-7Q3KKWUB.js.map +1 -0
- package/dist/chunk-IUAZAMKF.js +123 -0
- package/dist/chunk-IUAZAMKF.js.map +1 -0
- package/dist/chunk-QM2T4VGM.js +6688 -0
- package/dist/chunk-QM2T4VGM.js.map +1 -0
- package/dist/chunk-UO6CDRC5.js +322 -0
- package/dist/chunk-UO6CDRC5.js.map +1 -0
- package/dist/converter/index.d.ts +2 -0
- package/dist/converter/index.html +10 -0
- package/dist/converter/index.js +432 -0
- package/dist/converter/index.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +192 -0
- package/dist/index.js.map +1 -0
- package/dist/interface-BlLeWXzS.d.ts +265 -0
- package/dist/preprocessor/index.html +10 -0
- package/dist/runtime/index.d.ts +90 -0
- package/dist/runtime/index.js +9 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/types-BAnNlLpy.d.ts +140 -0
- package/package.json +54 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapters/code-adapter.ts","../src/adapters/platforms/baijiahao.ts","../src/adapters/platforms/bilibili.ts","../src/adapters/platforms/cnblogs.ts","../src/adapters/platforms/csdn.ts","../src/adapters/platforms/cto51.ts","../src/adapters/platforms/douyin.ts","../src/adapters/platforms/juejin.ts","../src/adapters/platforms/netease.ts","../src/adapters/platforms/sohu.ts","../src/adapters/platforms/tencent.ts","../src/adapters/platforms/toutiao.ts","../src/adapters/platforms/weixin.ts"],"sourcesContent":["/**\n * 代码适配器基类\n *\n * 架构说明:\n * - Content Script (有 DOM): 负责所有 HTML/DOM 处理\n * - 代码块处理 (使用 innerText)\n * - 懒加载图片处理\n * - HTML 转 Markdown\n * - Service Worker (无 DOM): 只负责 API 调用\n * - 接收已处理好的 html 和 markdown\n * - 图片上传 (URL 替换,不需要 DOM)\n * - 调用平台 API\n *\n * 适配器接收的 Article 对象:\n * - article.html: 已预处理的 HTML (代码块已简化,图片已处理)\n * - article.markdown: 已转换的 Markdown\n *\n * 适配器只需:\n * 1. 选择使用 html 还是 markdown\n * 2. 处理图片上传 (如果平台需要)\n * 3. 调用平台 API\n */\nimport type {\n Article,\n AuthResult,\n HeaderRule,\n PlatformMeta,\n PublishStatusRef,\n PublishStatusResult,\n SyncResult,\n} from '../types'\nimport type { RuntimeInterface } from '../runtime/interface'\nimport type { PlatformAdapter, PublishOptions } from './types'\nimport { createLogger } from '../lib/logger'\nimport { parseMarkdownImages } from '../lib/markdown-images'\n\nconst logger = createLogger('CodeAdapter')\n\n/**\n * 图片上传结果\n */\nexport interface ImageUploadResult {\n /** 新的图片 URL */\n url: string\n /** 额外的 img 属性 */\n attrs?: Record<string, string | number>\n}\n\n/**\n * 图片处理选项\n */\nexport interface ImageProcessOptions {\n /** 跳过匹配这些模式的图片 */\n skipPatterns?: string[]\n /** 进度回调 */\n onProgress?: (current: number, total: number) => void\n}\n\n/**\n * 代码适配器基类\n */\nexport abstract class CodeAdapter implements PlatformAdapter {\n abstract readonly meta: PlatformMeta\n protected runtime!: RuntimeInterface\n\n /** Header 规则 ID 列表(用于请求拦截) */\n protected headerRuleIds: string[] = []\n\n async init(runtime: RuntimeInterface): Promise<void> {\n this.runtime = runtime\n }\n\n // ============ 抽象方法,子类必须实现 ============\n\n abstract checkAuth(): Promise<AuthResult>\n abstract publish(article: Article, options?: PublishOptions): Promise<SyncResult>\n\n protected async getStatusFromUrl(statusRef: PublishStatusRef): Promise<PublishStatusResult> {\n if (!statusRef.url) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: 'statusRef does not include a URL',\n checkedAt: Date.now(),\n }\n }\n\n const response = await this.runtime.fetch(statusRef.url, { credentials: 'include' })\n if (response.status === 404) {\n return {\n platform: this.meta.id,\n state: 'not_found',\n message: 'Article URL returned 404',\n checkedAt: Date.now(),\n }\n }\n\n if (response.ok) {\n return {\n platform: this.meta.id,\n state: 'published',\n postUrl: statusRef.url,\n checkedAt: Date.now(),\n }\n }\n\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: `Article URL returned HTTP ${response.status}`,\n checkedAt: Date.now(),\n }\n }\n\n // ============ Header 规则管理 ============\n\n /**\n * 添加 Header 规则\n * @param rule 规则配置\n * @returns 规则 ID\n */\n protected async addHeaderRule(rule: Omit<HeaderRule, 'id'>): Promise<string | null> {\n if (!this.runtime.headerRules) return null\n\n try {\n const ruleId = await this.runtime.headerRules.add(rule)\n this.headerRuleIds.push(ruleId)\n return ruleId\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n throw new Error(`[${this.meta.id}] 请求头规则添加失败: ${message || '未知错误'}`)\n }\n }\n\n /**\n * 批量添加 Header 规则\n * @param rules 规则配置列表\n */\n protected async addHeaderRules(rules: Array<Omit<HeaderRule, 'id'>>): Promise<void> {\n for (const rule of rules) {\n await this.addHeaderRule(rule)\n }\n if (this.headerRuleIds.length > 0) {\n logger.debug(`[${this.meta.id}] Header rules added:`, this.headerRuleIds)\n }\n }\n\n /**\n * 清除所有已添加的 Header 规则\n */\n protected async clearHeaderRules(): Promise<void> {\n if (!this.runtime.headerRules || this.headerRuleIds.length === 0) return\n\n const ruleIds = [...this.headerRuleIds]\n this.headerRuleIds = []\n\n for (const ruleId of ruleIds) {\n try {\n await this.runtime.headerRules.remove(ruleId)\n } catch (error) {\n logger.warn(`[${this.meta.id}] Failed to clear header rule ${ruleId}:`, error)\n }\n }\n logger.debug(`[${this.meta.id}] Header rules cleared:`, ruleIds)\n }\n\n /**\n * 在 Header 规则保护下执行操作\n * 自动设置规则,执行完成后自动清除\n * @param rules 规则配置列表\n * @param fn 要执行的操作\n */\n protected async withHeaderRules<T>(\n rules: Array<Omit<HeaderRule, 'id'>>,\n fn: () => Promise<T>\n ): Promise<T> {\n try {\n await this.addHeaderRules(rules)\n } catch (error) {\n await this.clearHeaderRules()\n throw error\n }\n try {\n return await fn()\n } finally {\n await this.clearHeaderRules()\n }\n }\n\n // ============ HTTP 请求能力 ============\n\n /**\n * GET 请求\n */\n protected async get<T = unknown>(url: string, headers?: Record<string, string>): Promise<T> {\n const response = await this.runtime.fetch(url, {\n method: 'GET',\n credentials: 'include',\n headers,\n })\n return this.parseResponse<T>(response)\n }\n\n /**\n * POST 请求 (JSON)\n */\n protected async postJson<T = unknown>(\n url: string,\n data: Record<string, unknown>,\n headers?: Record<string, string>\n ): Promise<T> {\n const response = await this.runtime.fetch(url, {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify(data),\n })\n return this.parseResponse<T>(response)\n }\n\n /**\n * POST 请求 (Form)\n */\n protected async postForm<T = unknown>(\n url: string,\n data: Record<string, string>,\n headers?: Record<string, string>\n ): Promise<T> {\n const response = await this.runtime.fetch(url, {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n ...headers,\n },\n body: new URLSearchParams(data),\n })\n return this.parseResponse<T>(response)\n }\n\n /**\n * POST 请求 (Multipart)\n */\n protected async postMultipart<T = unknown>(\n url: string,\n formData: FormData,\n headers?: Record<string, string>\n ): Promise<T> {\n const response = await this.runtime.fetch(url, {\n method: 'POST',\n credentials: 'include',\n headers,\n body: formData,\n })\n return this.parseResponse<T>(response)\n }\n\n /**\n * 解析响应\n */\n private async parseResponse<T>(response: Response): Promise<T> {\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n const text = await response.text()\n\n // 尝试解析 JSON\n try {\n return JSON.parse(text) as T\n } catch {\n return text as T\n }\n }\n\n // ============ 图片处理能力 ============\n\n /**\n * 处理文章图片 (使用正则提取 URL,兼容 Service Worker)\n * 同时支持 HTML 和 Markdown 格式\n * - HTML: <img src=\"url\" alt=\"text\">\n * - Markdown: \n *\n * 注意: 这个方法只做 URL 提取和替换,不涉及 DOM 解析\n */\n protected async processImages(\n content: string,\n uploadFn: (src: string) => Promise<ImageUploadResult>,\n options?: ImageProcessOptions\n ): Promise<string> {\n const { skipPatterns = [], onProgress } = options || {}\n\n // 提取所有图片(HTML + Markdown)\n const matches: { full: string; src: string; alt?: string; type: 'html' | 'markdown' }[] = []\n\n // 1. HTML 格式: <img ... src=\"url\" ...>\n const htmlImgRegex = /<img[^>]+src=\"([^\"]+)\"[^>]*>/gi\n let match\n while ((match = htmlImgRegex.exec(content)) !== null) {\n matches.push({ full: match[0], src: match[1], type: 'html' })\n }\n\n // 2. Markdown 格式: \n for (const mdMatch of parseMarkdownImages(content)) {\n matches.push({ full: mdMatch.full, src: mdMatch.src, alt: mdMatch.alt, type: 'markdown' })\n }\n\n if (matches.length === 0) {\n return content\n }\n\n logger.debug(`Found ${matches.length} images to process (HTML + Markdown)`)\n\n let result = content\n const uploadedMap = new Map<string, ImageUploadResult>()\n let processed = 0\n\n for (const { full, src, alt, type } of matches) {\n // 跳过空 src\n if (!src) continue\n\n // 跳过匹配的模式(但不跳过 data URI)\n if (!src.startsWith('data:')) {\n const shouldSkip = skipPatterns.some(pattern => src.includes(pattern))\n if (shouldSkip) {\n logger.debug(`Skipping matched pattern: ${src}`)\n continue\n }\n }\n\n processed++\n onProgress?.(processed, matches.length)\n\n try {\n // 检查是否已上传过\n let uploadResult = uploadedMap.get(src)\n\n if (!uploadResult) {\n logger.debug(`Uploading image ${processed}/${matches.length}: ${src.startsWith('data:') ? 'data URI' : src}`)\n // uploadFn 应该能处理 URL 和 data URI(通过 fetch)\n uploadResult = await uploadFn(src)\n uploadedMap.set(src, uploadResult)\n }\n\n // 根据格式构建替换内容\n let replacement: string\n if (type === 'html') {\n // HTML 格式\n replacement = `<img src=\"${uploadResult.url}\"`\n if (uploadResult.attrs) {\n for (const [key, value] of Object.entries(uploadResult.attrs)) {\n replacement += ` ${key}=\"${value}\"`\n }\n }\n replacement += ' />'\n } else {\n // Markdown 格式\n replacement = ``\n }\n\n // 替换原内容\n result = result.replace(full, replacement)\n\n logger.debug(`Image uploaded: ${uploadResult.url}`)\n } catch (error) {\n logger.error(`Failed to upload image: ${src}`, error)\n // 继续处理其他图片\n }\n\n // 避免请求过快\n await this.delay(300)\n }\n\n return result\n }\n\n /**\n * 上传图片(子类实现)\n * 默认实现抛出错误\n */\n protected async uploadImageByUrl(_src: string): Promise<ImageUploadResult> {\n throw new Error('uploadImageByUrl not implemented')\n }\n\n /**\n * 通过 Blob 上传图片(公开方法,实现 PlatformAdapter 接口)\n * 默认实现:转为 data URI,调用 uploadImageByUrl\n * 子类可以覆盖以提供更优的实现\n */\n async uploadImage(file: Blob, _filename?: string): Promise<string> {\n const dataUri = await this.blobToDataUri(file)\n const result = await this.uploadImageByUrl(dataUri)\n return result.url\n }\n\n /**\n * Blob 转 data URI\n */\n protected async blobToDataUri(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => {\n const result = reader.result\n if (typeof result === 'string') {\n resolve(result)\n } else {\n reject(new Error('Failed to read blob as data URI'))\n }\n }\n reader.onerror = () => reject(new Error('FileReader error'))\n reader.readAsDataURL(blob)\n })\n }\n\n /**\n * data URI 转 Blob\n */\n protected async dataUriToBlob(dataUri: string): Promise<Blob> {\n const response = await fetch(dataUri)\n return response.blob()\n }\n\n // ============ 工具方法 ============\n\n /**\n * 延迟\n */\n protected delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n }\n\n /**\n * 创建同步结果\n */\n protected createResult(success: boolean, data?: Partial<SyncResult>): SyncResult {\n return {\n platform: this.meta.id,\n success,\n timestamp: Date.now(),\n ...data,\n }\n }\n}\n","/**\n * 百家号适配器\n */\nimport { CodeAdapter, type ImageUploadResult } from '../code-adapter'\nimport type { Article, AuthResult, PublishStatusRef, PublishStatusResult, SyncResult, PlatformMeta } from '../../types'\nimport type { PublishOptions } from '../types'\nimport { markdownToHtml } from '../../lib/turndown'\nimport { createLogger } from '../../lib/logger'\n\nconst logger = createLogger('Baijiahao')\n\ninterface BaijiahaoUserInfo {\n userid: string\n name: string\n avatar: string\n}\n\ninterface BaijiahaoArticleResponse {\n errno: number\n errmsg: string\n ret?: {\n article_id?: string\n nid?: string\n url?: string\n article_url?: string\n }\n data?: {\n article_id?: string\n nid?: string\n url?: string\n article_url?: string\n }\n}\n\ninterface BaijiahaoListItem {\n article_id?: string\n id?: string\n nid?: string\n title?: string\n status?: string\n is_published?: string | number\n dxxFinalAuditResult?: string\n secure_status?: string\n quality_status?: string\n url?: string\n share_url?: string\n audit_msg?: string\n secure_not_pass_reason?: string\n quality_not_pass_reason?: string\n}\n\ninterface BaijiahaoListResponse {\n errno: number\n errmsg: string\n data?: {\n list?: BaijiahaoListItem[]\n }\n}\n\ninterface BaijiahaoPublicPageSnapshot {\n href?: string\n title?: string\n readsrcLink?: string\n nid?: string\n hasJsonData?: boolean\n matchesArticle?: boolean\n}\n\nexport class BaijiahaoAdapter extends CodeAdapter {\n readonly meta: PlatformMeta = {\n id: 'baijiahao',\n name: '百家号',\n icon: 'https://www.baidu.com/favicon.ico',\n homepage: 'https://baijiahao.baidu.com/',\n capabilities: ['article', 'image_upload', 'cover'],\n }\n\n /** 预处理配置: 百家号使用 HTML 格式 */\n readonly preprocessConfig = {\n outputFormat: 'html' as const,\n }\n\n private userInfo: BaijiahaoUserInfo | null = null\n private authToken: string = ''\n\n /** 百家号 API 需要的 Header 规则 */\n private readonly HEADER_RULES = [\n {\n urlFilter: '*://baijiahao.baidu.com/*',\n headers: {\n 'Origin': 'https://baijiahao.baidu.com',\n 'Referer': 'https://baijiahao.baidu.com/',\n },\n resourceTypes: ['xmlhttprequest'],\n },\n ]\n\n async checkAuth(): Promise<AuthResult> {\n try {\n const res = await this.get<{\n errno: number\n errmsg: string\n data?: { user: BaijiahaoUserInfo }\n }>(`https://baijiahao.baidu.com/builder/app/appinfo?_=${Date.now()}`)\n\n logger.debug('checkAuth response:', res)\n\n if (res.errmsg === 'success' && res.data?.user) {\n this.userInfo = res.data.user\n return {\n isAuthenticated: true,\n userId: res.data.user.userid,\n username: res.data.user.name,\n avatar: res.data.user.avatar,\n }\n }\n\n return { isAuthenticated: false }\n } catch (error) {\n logger.debug('checkAuth: not logged in -', error)\n return { isAuthenticated: false, error: (error as Error).message }\n }\n }\n\n private async fetchAuthToken(): Promise<string> {\n const response = await this.runtime.fetch('https://baijiahao.baidu.com/builder/rc/edit', {\n credentials: 'include',\n })\n const html = await response.text()\n\n const match = html.match(/window\\.__BJH__INIT__AUTH__\\s*=\\s*['\"]([^'\"]+)['\"]/)\n if (!match) {\n throw new Error('登录失效,请重新登录百家号')\n }\n\n const token = match[1]\n logger.debug('Auth token obtained')\n return token\n }\n\n private parseArticleResponse(text: string): BaijiahaoArticleResponse {\n const trimmed = text.trim().replace(/;$/, '')\n const json = trimmed.startsWith('{')\n ? trimmed\n : trimmed.replace(/^[^(]*\\(/, '').replace(/\\)$/, '')\n return JSON.parse(json) as BaijiahaoArticleResponse\n }\n\n async publish(article: Article, options?: PublishOptions): Promise<SyncResult> {\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n logger.info('Starting publish...')\n\n if (!this.userInfo) {\n const auth = await this.checkAuth()\n if (!auth.isAuthenticated) {\n throw new Error('请先登录百家号')\n }\n }\n\n this.authToken = await this.fetchAuthToken()\n\n let content = this.prepareContent(article.html || markdownToHtml(article.markdown))\n\n content = await this.processImages(\n content,\n (src) => this.uploadImageByUrl(src),\n {\n skipPatterns: ['baijiahao.baidu.com', 'bdstatic.com', 'bcebos.com'],\n onProgress: options?.onImageProgress,\n }\n )\n\n const cover = article.cover ? await this.uploadImageByUrl(article.cover) : null\n const body = new URLSearchParams({\n title: article.title,\n content: content,\n feed_cat: '1',\n len: String(content.length),\n activity_list: JSON.stringify([{ id: 408, is_checked: 0 }]),\n source_reprinted_allow: '0',\n original_status: '0',\n original_handler_status: '1',\n isBeautify: 'false',\n subtitle: article.summary || '',\n bjhtopic_id: '',\n bjhtopic_info: '',\n type: 'news',\n })\n\n if (cover) {\n this.appendCoverParams(body, cover.url)\n }\n\n const response = await this.runtime.fetch(\n 'https://baijiahao.baidu.com/pcui/article/publish',\n {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n 'token': this.authToken,\n },\n body,\n }\n )\n\n const text = await response.text()\n const res = this.parseArticleResponse(text)\n\n logger.debug('Publish response:', res)\n\n if (res.errmsg !== 'success' && res.errno !== 0) {\n throw new Error(res.errmsg || '发布失败')\n }\n\n const postId = res.ret?.article_id || res.data?.article_id || res.ret?.nid || res.data?.nid\n if (!postId) {\n throw new Error('发布成功但未返回文章 ID')\n }\n const rawPostUrl = res.ret?.url || res.data?.url || res.ret?.article_url || res.data?.article_url\n const postUrl = this.toPublicUrl(rawPostUrl)\n\n return this.createResult(true, {\n postId: postId,\n postUrl,\n })\n }).catch((error) => this.createResult(false, {\n error: (error as Error).message,\n }))\n }\n\n async getStatus(statusRef: PublishStatusRef): Promise<PublishStatusResult> {\n if (!statusRef.id) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: '百家号 statusRef 缺少文章 ID',\n checkedAt: Date.now(),\n }\n }\n\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n const item = await this.findArticle(statusRef.id!)\n if (!item) {\n return {\n platform: this.meta.id,\n state: 'not_found',\n message: '百家号文章列表未找到该文章',\n checkedAt: Date.now(),\n }\n }\n\n return this.mapArticleStatus(item, statusRef)\n })\n }\n\n private async findArticle(articleId: string): Promise<BaijiahaoListItem | null> {\n // ponytail: scans recent pages; use a search/index endpoint if Baijiahao exposes one.\n for (let page = 1; page <= 5; page++) {\n const url = new URL('https://baijiahao.baidu.com/pcui/article/lists')\n url.searchParams.set('currentPage', String(page))\n url.searchParams.set('pageSize', '20')\n url.searchParams.set('search', '')\n url.searchParams.set('type', '')\n url.searchParams.set('collection', '')\n url.searchParams.set('startDate', '')\n url.searchParams.set('endDate', '')\n url.searchParams.set('clearBeforeFetch', 'false')\n url.searchParams.set('dynamic', '1')\n\n const response = await this.runtime.fetch(url.toString(), {\n credentials: 'include',\n headers: { 'X-Requested-With': 'XMLHttpRequest' },\n })\n const res = await response.json() as BaijiahaoListResponse\n if (res.errno !== 0) {\n throw new Error(res.errmsg || '百家号文章状态查询失败')\n }\n\n const match = res.data?.list?.find((item) => (\n String(item.article_id || item.id || item.nid) === articleId\n ))\n if (match) return match\n }\n\n return null\n }\n\n private async mapArticleStatus(item: BaijiahaoListItem, statusRef: PublishStatusRef): Promise<PublishStatusResult> {\n const checkedAt = Date.now()\n const status = String(item.status || '')\n const articleId = String(item.article_id || item.id || item.nid || statusRef.id || '')\n const publicUrl = this.toPublicUrl(item.share_url || item.url)\n\n if (this.isPublishedItem(item)) {\n const resolvedUrl = publicUrl || await this.resolvePublishedPublicUrl(articleId)\n if (!resolvedUrl) {\n return {\n platform: this.meta.id,\n state: 'reviewing',\n message: '百家号管理端已发布,但公开页链接尚未通过官方页面数据确认,继续轮询',\n checkedAt,\n }\n }\n return {\n platform: this.meta.id,\n state: 'published',\n postUrl: resolvedUrl,\n message: '百家号文章状态: 已发布',\n checkedAt,\n }\n }\n\n const reason = item.audit_msg || item.secure_not_pass_reason || item.quality_not_pass_reason\n if (/reject|fail|nopass|not_pass|forbid|withdraw|delete/i.test(status) || reason) {\n return {\n platform: this.meta.id,\n state: 'rejected',\n message: `百家号文章状态: 未通过${reason ? `,原因: ${reason}` : ''}`,\n checkedAt,\n }\n }\n\n if (status === 'analyze' || status === 'audit' || status === 'checking' || !publicUrl) {\n return {\n platform: this.meta.id,\n state: 'reviewing',\n message: '百家号文章状态: 审核中',\n checkedAt,\n }\n }\n\n return {\n platform: this.meta.id,\n state: 'unknown',\n postUrl: publicUrl || statusRef.url,\n message: `百家号文章状态: ${status || '未知'}`,\n checkedAt,\n }\n }\n\n private isPublishedItem(item: BaijiahaoListItem): boolean {\n const status = String(item.status || '')\n return status === 'publish'\n || String(item.is_published) === '1'\n || item.dxxFinalAuditResult === 'publish'\n || item.secure_status === 'publish'\n || item.quality_status === 'publish'\n }\n\n private async resolvePublishedPublicUrl(articleId: string): Promise<string | undefined> {\n if (!articleId || !this.runtime.tabs?.query || !this.runtime.tabs?.create || !this.runtime.tabs?.executeScript) {\n return undefined\n }\n\n const pageUrl = `https://baijiahao.baidu.com/s?id=${encodeURIComponent(articleId)}`\n const tabId = await this.getPublishedPageTabId(articleId, pageUrl)\n if (!tabId) return undefined\n\n for (let attempt = 0; attempt < 3; attempt++) {\n const snapshot = await this.readPublishedPageSnapshot(tabId, articleId)\n if (snapshot?.matchesArticle) {\n return this.toPublicUrl(snapshot.readsrcLink)\n }\n await this.sleep(1000)\n }\n\n return undefined\n }\n\n private async getPublishedPageTabId(articleId: string, pageUrl: string): Promise<number | null> {\n const tabs = await this.runtime.tabs?.query('*://baijiahao.baidu.com/*')\n const existing = tabs?.find(tab => tab.url && this.urlMatchesArticleId(tab.url, articleId))\n if (existing?.id) return existing.id\n\n const tab = await this.runtime.tabs?.create(pageUrl, false)\n if (!tab?.id) return null\n\n if (this.runtime.tabs?.waitForLoad) {\n await this.runtime.tabs.waitForLoad(tab.id, 30000).catch((error) => {\n logger.debug('Baijiahao public page load wait failed:', error)\n })\n }\n await this.sleep(1000)\n return tab.id\n }\n\n private async readPublishedPageSnapshot(tabId: number, articleId: string): Promise<BaijiahaoPublicPageSnapshot | null> {\n try {\n return await this.runtime.tabs!.executeScript<BaijiahaoPublicPageSnapshot, [string]>(\n tabId,\n (expectedArticleId) => {\n const pageWindow = window as Window & {\n jsonData?: {\n bsData?: {\n nid?: string\n superlanding?: Array<{\n itemData?: {\n title?: string\n header?: { title?: string }\n readsrc?: { link?: string }\n }\n }>\n }\n }\n }\n const bsData = pageWindow.jsonData?.bsData\n const itemData = bsData?.superlanding?.[0]?.itemData\n const readsrcLink = itemData?.readsrc?.link || ''\n const href = location.href\n\n const getId = (raw: string): string => {\n try {\n return new URL(raw, location.href).searchParams.get('id') || ''\n } catch {\n return ''\n }\n }\n\n return {\n href,\n title: itemData?.header?.title || itemData?.title || document.querySelector('h1')?.textContent || document.title,\n readsrcLink,\n nid: bsData?.nid,\n hasJsonData: Boolean(pageWindow.jsonData),\n matchesArticle: Boolean(bsData) && getId(readsrcLink) === expectedArticleId,\n }\n },\n [articleId],\n )\n } catch (error) {\n logger.debug('Baijiahao public page read failed:', error)\n return null\n }\n }\n\n private urlMatchesArticleId(rawUrl: string, articleId: string): boolean {\n try {\n const url = new URL(rawUrl)\n return url.hostname === 'baijiahao.baidu.com'\n && url.pathname === '/s'\n && url.searchParams.get('id') === articleId\n } catch {\n return false\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n }\n\n private toPublicUrl(url?: string): string | undefined {\n if (url && !url.includes('/builder/preview/')) {\n return url.replace(/^http:/, 'https:')\n }\n return undefined\n }\n\n private appendCoverParams(body: URLSearchParams, coverUrl: string): void {\n const coverImages = JSON.stringify([{\n src: coverUrl,\n cropData: {},\n machine_chooseimg: 0,\n isLegal: 1,\n cover_source_tag: 'local',\n }])\n const coverImagesMap = JSON.stringify([{\n src: coverUrl,\n origin_src: coverUrl,\n }])\n\n body.set('cover_layout', 'one')\n body.set('cover_images', coverImages)\n body.set('_cover_images_map', coverImagesMap)\n body.set('usingImgFilter', 'false')\n body.set('source', 'upload')\n body.set('cover_source', 'upload')\n body.set('cover_image_source', JSON.stringify({ wide_cover_image_source: 'local' }))\n }\n\n private prepareContent(html: string): string {\n return this.replaceTablesWithText(this.replaceLinksWithUrls(html))\n }\n\n private replaceLinksWithUrls(html: string): string {\n return html.replace(\n /<a\\b[^>]*href=([\"'])(.*?)\\1[^>]*>([\\s\\S]*?)<\\/a>/gi,\n (_match, _quote, href, label) => {\n const text = this.textFromHtml(label)\n if (!href || href.startsWith('#') || href.toLowerCase().startsWith('javascript:')) return text\n return text === href ? text : `${text || href}(${this.decodeHtml(href)})`\n },\n )\n }\n\n private replaceTablesWithText(html: string): string {\n // Same pragmatic fallback as NetEase: Baijiahao strips table bodies from public articles.\n return html.replace(/<table\\b[\\s\\S]*?<\\/table>/gi, (table) => {\n const headers: string[] = []\n const rows: string[][] = []\n\n for (const rowMatch of table.matchAll(/<tr\\b[\\s\\S]*?<\\/tr>/gi)) {\n const rowHtml = rowMatch[0]\n const cells = [...rowHtml.matchAll(/<t([hd])\\b[^>]*>([\\s\\S]*?)<\\/t[hd]>/gi)]\n const values = cells.map(cell => this.textFromHtml(cell[2]))\n if (values.length === 0) continue\n\n const isHeader = cells.every(cell => cell[1].toLowerCase() === 'h')\n if (headers.length === 0 && isHeader) {\n headers.push(...values)\n continue\n }\n rows.push(values)\n }\n\n return rows.map((row) => {\n const parts = row.map((value, index) => headers[index] ? `${headers[index]}: ${value}` : value)\n return `<p>${this.escapeHtml(parts.join(' | '))}</p>`\n }).join('')\n })\n }\n\n private textFromHtml(html: string): string {\n return this.decodeHtml(html\n .replace(/<br\\s*\\/?>/gi, ' ')\n .replace(/<[^>]+>/g, '')\n .replace(/\\s+/g, ' ')\n .trim())\n }\n\n private decodeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/ /g, ' ')\n }\n\n private escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n }\n\n protected async uploadImageByUrl(src: string): Promise<ImageUploadResult> {\n const imageResponse = await fetch(src)\n if (!imageResponse.ok) {\n throw new Error('图片下载失败: ' + src)\n }\n const imageBlob = await imageResponse.blob()\n\n const formData = new FormData()\n formData.append('media', imageBlob, 'image.jpg')\n formData.append('type', 'image')\n formData.append('app_id', '1589639493090963')\n formData.append('is_waterlog', '1')\n formData.append('save_material', '1')\n formData.append('no_compress', '0')\n formData.append('is_events', '')\n formData.append('article_type', 'news')\n\n const uploadUrl = 'https://baijiahao.baidu.com/pcui/picture/uploadproxy'\n const uploadResponse = await this.runtime.fetch(uploadUrl, {\n method: 'POST',\n credentials: 'include',\n body: formData,\n })\n\n const res = await uploadResponse.json() as {\n errno: number\n errmsg: string\n ret?: { https_url: string }\n }\n\n logger.debug('Image upload response:', res)\n\n if (res.errmsg !== 'success' || !res.ret?.https_url) {\n throw new Error(res.errmsg || '图片上传失败')\n }\n\n return {\n url: res.ret.https_url,\n }\n }\n}\n","/**\n * B站适配器\n */\nimport { CodeAdapter, type ImageUploadResult } from '../code-adapter'\nimport type { Article, AuthResult, PublishStatusRef, PublishStatusResult, SyncResult, PlatformMeta } from '../../types'\nimport type { PublishOptions } from '../types'\nimport { createLogger } from '../../lib/logger'\nimport md5Lib from 'js-md5'\nimport { marked } from 'marked'\n\nconst logger = createLogger('Bilibili')\nconst jsMd5 = md5Lib as unknown as (message: string) => string\nconst WBI_MIXIN_KEY_ENC_TAB = [\n 46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49, 33, 9, 42, 19, 29, 28,\n 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40, 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54,\n 21, 56, 59, 6, 63, 57, 62, 11, 36, 20, 34, 44, 52,\n]\n\ninterface BilibiliUserInfo {\n mid: number\n uname: string\n face: string\n isLogin: boolean\n}\n\ninterface BilibiliNavData extends BilibiliUserInfo {\n wbi_img?: {\n img_url: string\n sub_url: string\n }\n}\n\ninterface BilibiliWbiKeys {\n imgKey: string\n subKey: string\n}\n\ntype BilibiliOpusResponseData = Partial<\n Record<'cvid' | 'cvid_str' | 'aid' | 'id' | 'dyn_id' | 'dyn_id_str' | 'dyn_rid', string | number>\n>\ntype BilibiliOpusParagraph = Record<string, unknown>\ntype BilibiliOpusTextNode = Record<string, unknown>\ninterface BilibiliCoverInfo {\n url: string\n width?: number\n height?: number\n size?: number\n}\n\ninterface BilibiliDynamicItem {\n id_str?: string\n visible?: boolean\n type?: string\n basic?: {\n in_audit?: boolean\n jump_url?: string\n rid_str?: string\n }\n modules?: {\n module_dynamic?: {\n major?: {\n article?: {\n title?: string\n jump_url?: string\n }\n opus?: {\n title?: string\n jump_url?: string\n }\n }\n }\n }\n}\n\ninterface BilibiliDynamicDetailResponse {\n code: number\n message?: string\n data?: {\n item?: BilibiliDynamicItem\n }\n}\n\ninterface BilibiliSpaceFeedResponse {\n code: number\n message?: string\n data?: {\n items?: BilibiliDynamicItem[]\n offset?: string\n has_more?: boolean\n }\n}\n\ninterface InlineStyle {\n bold?: boolean\n italic?: boolean\n strikethrough?: boolean\n underline?: boolean\n code?: boolean\n fontSize?: number\n fontLevel?: string\n}\n\nconst DEFAULT_FONT_SIZE = 17\nconst DEFAULT_FONT_LEVEL = 'regular'\nconst HEADING_STYLES: Record<number, { fontSize: number; fontLevel: string }> = {\n 1: { fontSize: 24, fontLevel: 'xxLarge' },\n 2: { fontSize: 22, fontLevel: 'xLarge' },\n 3: { fontSize: 20, fontLevel: 'large' },\n 4: { fontSize: 18, fontLevel: 'regular' },\n 5: { fontSize: 16, fontLevel: 'regular' },\n 6: { fontSize: 14, fontLevel: 'regular' },\n}\nconst LIST_THEMES = {\n sorted: ['arabic_num', 'lower_letter', 'roman_num'],\n unsorted: ['dot', 'square', 'circle'],\n}\n\ntype MarkedToken = Record<string, unknown> & {\n type?: string\n raw?: string\n text?: string\n href?: string\n lang?: string\n depth?: number\n ordered?: boolean\n start?: number\n tokens?: MarkedToken[]\n items?: MarkedListItem[]\n header?: MarkedTableCell[]\n rows?: MarkedTableCell[][]\n}\n\ntype MarkedListItem = Record<string, unknown> & {\n text?: string\n task?: boolean\n checked?: boolean\n tokens?: MarkedToken[]\n}\n\ntype MarkedTableCell = Record<string, unknown> & {\n text?: string\n tokens?: MarkedToken[]\n}\n\nexport class BilibiliAdapter extends CodeAdapter {\n readonly meta: PlatformMeta = {\n id: 'bilibili',\n name: '哔哩哔哩',\n icon: 'https://www.bilibili.com/favicon.ico',\n homepage: 'https://member.bilibili.com/platform/upload/text',\n capabilities: ['article', 'image_upload', 'cover', 'tags'],\n }\n\n /** 预处理配置: B站使用 HTML,移除外链 */\n readonly preprocessConfig = {\n outputFormat: 'html' as const,\n removeLinks: true,\n }\n\n private userInfo: BilibiliUserInfo | null = null\n private csrf: string = ''\n private wbiKeys: BilibiliWbiKeys | null = null\n\n /** B站 API 需要的 Header 规则 */\n private readonly HEADER_RULES = [\n {\n urlFilter: '*://api.bilibili.com/*',\n headers: {\n Origin: 'https://member.bilibili.com',\n Referer: 'https://member.bilibili.com/',\n },\n resourceTypes: ['xmlhttprequest'],\n },\n ]\n\n async checkAuth(): Promise<AuthResult> {\n try {\n const res = await this.get<{\n code: number\n data?: BilibiliNavData\n }>('https://api.bilibili.com/x/web-interface/nav?build=0&mobi_app=web')\n\n logger.debug('checkAuth response:', res)\n\n if (res.code === 0 && res.data?.isLogin) {\n this.userInfo = res.data\n this.wbiKeys = this.extractWbiKeys(res.data.wbi_img)\n await this.fetchCsrf()\n\n return {\n isAuthenticated: true,\n userId: String(res.data.mid),\n username: res.data.uname,\n avatar: res.data.face,\n }\n }\n\n return { isAuthenticated: false }\n } catch (error) {\n logger.debug('checkAuth: not logged in -', error)\n return { isAuthenticated: false, error: (error as Error).message }\n }\n }\n\n private async fetchCsrf(): Promise<void> {\n try {\n if (this.runtime.getCookie) {\n const value = await this.runtime.getCookie('.bilibili.com', 'bili_jct')\n this.csrf = value || ''\n }\n logger.debug('CSRF token:', this.csrf ? 'obtained' : 'not found')\n } catch (e) {\n logger.error('Failed to get CSRF:', e)\n }\n }\n\n async publish(article: Article, options?: PublishOptions): Promise<SyncResult> {\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n logger.info('Starting publish...')\n\n if (!this.userInfo) {\n const auth = await this.checkAuth()\n if (!auth.isAuthenticated) {\n throw new Error('请先登录B站')\n }\n }\n\n if (!this.csrf) {\n throw new Error('获取 CSRF token 失败,请刷新页面后重试')\n }\n\n let markdown = article.markdown || ''\n let html = article.html || ''\n\n if (markdown.trim()) {\n markdown = await this.processImages(markdown, (src) => this.uploadImageByUrl(src), {\n skipPatterns: ['hdslb.com', 'bilibili.com', 'biliimg.com'],\n onProgress: options?.onImageProgress,\n })\n } else {\n html = await this.processImages(html, (src) => this.uploadImageByUrl(src), {\n skipPatterns: ['hdslb.com', 'bilibili.com', 'biliimg.com'],\n onProgress: options?.onImageProgress,\n })\n }\n\n await this.ensureWbiKeys()\n\n const cover = article.cover\n ? await this.uploadImageByUrl(article.cover).then((result) => this.createCoverInfo(result))\n : undefined\n const payload = this.createOpusPayload(article, { markdown, html }, cover)\n const signedParams = this.signWbiParams({\n csrf: this.csrf,\n gaia_source: 'main_web',\n dm_img_switch: '0',\n 'w_opus_req.upload_id': payload.opus_req.upload_id,\n })\n const publishUrl = `https://api.bilibili.com/x/dynamic/feed/create/opus?${new URLSearchParams(signedParams)}`\n\n const res = await this.postJson<{\n code: number\n message?: string\n data?: BilibiliOpusResponseData\n }>(publishUrl, payload as unknown as Record<string, unknown>)\n\n logger.debug('Publish response:', res)\n\n if (res.code !== 0) {\n throw new Error(res.message || `发布失败: ${res.code}`)\n }\n\n const postId = this.resolvePostId(res.data)\n\n return this.createResult(true, {\n postId,\n postUrl: this.resolvePostUrl(res.data),\n statusData: this.userInfo ? { hostMid: this.userInfo.mid } : undefined,\n })\n }).catch((error) =>\n this.createResult(false, {\n error: (error as Error).message,\n }),\n )\n }\n\n async getStatus(statusRef: PublishStatusRef): Promise<PublishStatusResult> {\n if (!statusRef.id) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: 'B站 statusRef 缺少动态 ID',\n checkedAt: Date.now(),\n }\n }\n\n const hostMid = this.readStatusHostMid(statusRef)\n if (hostMid) {\n const item = await this.findDynamicInSpaceFeed(statusRef.id, hostMid)\n if (item) return this.mapDynamicStatus(item, statusRef)\n }\n\n const detail = await this.get<BilibiliDynamicDetailResponse>(\n `https://api.bilibili.com/x/polymer/web-dynamic/v1/detail?id=${encodeURIComponent(statusRef.id)}`,\n )\n if (detail.code === 0 && detail.data?.item) {\n return this.mapDynamicStatus(detail.data.item, statusRef)\n }\n\n if (detail.message?.includes('MISS_ARTICLE_DATA')) {\n return {\n platform: this.meta.id,\n state: 'reviewing',\n message: 'B站文章详情暂不可读,可能仍在审核或同步中',\n checkedAt: Date.now(),\n }\n }\n\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: detail.message || `B站文章状态查询失败: ${detail.code}`,\n checkedAt: Date.now(),\n }\n }\n\n private readStatusHostMid(statusRef: PublishStatusRef): string {\n const value = statusRef.data?.hostMid\n if (typeof value === 'string' || typeof value === 'number') return String(value)\n return ''\n }\n\n private async findDynamicInSpaceFeed(dynamicId: string, hostMid: string): Promise<BilibiliDynamicItem | null> {\n let offset = ''\n\n for (let page = 0; page < 5; page += 1) {\n const url = new URL('https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space')\n url.searchParams.set('host_mid', hostMid)\n url.searchParams.set('features', 'itemOpusStyle')\n if (offset) url.searchParams.set('offset', offset)\n\n const res = await this.get<BilibiliSpaceFeedResponse>(url.toString())\n if (res.code !== 0) return null\n\n const item = res.data?.items?.find((entry) => String(entry.id_str || '') === String(dynamicId))\n if (item) return item\n\n if (!res.data?.has_more || !res.data.offset) break\n offset = res.data.offset\n }\n\n return null\n }\n\n private mapDynamicStatus(item: BilibiliDynamicItem, statusRef: PublishStatusRef): PublishStatusResult {\n const postUrl = this.normalizePublicUrl(\n item.modules?.module_dynamic?.major?.opus?.jump_url ||\n item.modules?.module_dynamic?.major?.article?.jump_url ||\n item.basic?.jump_url ||\n statusRef.url,\n )\n\n if (item.basic?.in_audit) {\n return {\n platform: this.meta.id,\n state: 'reviewing',\n message: 'B站文章仍在审核中',\n postUrl,\n checkedAt: Date.now(),\n }\n }\n\n if (item.visible === false) {\n return {\n platform: this.meta.id,\n state: 'reviewing',\n message: 'B站文章暂未公开可见',\n postUrl,\n checkedAt: Date.now(),\n }\n }\n\n return {\n platform: this.meta.id,\n state: 'published',\n postUrl,\n checkedAt: Date.now(),\n }\n }\n\n private createOpusPayload(\n article: Article,\n content: { markdown?: string; html?: string },\n cover?: BilibiliCoverInfo,\n ) {\n const tags = article.tags?.filter(Boolean).slice(0, 10)\n const articlePayload: Record<string, unknown> = {\n category_id: 15,\n list_id: 0,\n originality: 0,\n reproduced: 1,\n }\n\n if (tags?.length) {\n articlePayload.biz_tags = tags\n }\n if (cover) {\n articlePayload.cover = [cover]\n }\n\n return {\n raw_content: '',\n opus_req: {\n upload_id: this.createUploadId(),\n opus: {\n opus_source: 2,\n title: article.title,\n content: this.contentToOpusContent(content),\n article: articlePayload,\n pub_info: {\n editor_version: 'eva3-4.0.0',\n },\n },\n scene: 12,\n meta: {\n app_meta: {\n from: 'create.article.web',\n mobi_app: 'web',\n },\n },\n option: {\n aigc: 2,\n close_comment: 0,\n up_choose_comment: 0,\n private_pub: 2,\n },\n },\n }\n }\n\n private contentToOpusContent(content: { markdown?: string; html?: string }): {\n paragraphs: BilibiliOpusParagraph[]\n } {\n if (content.markdown?.trim()) {\n return this.markdownToOpusContent(content.markdown)\n }\n\n return this.htmlToOpusContent(content.html || '')\n }\n\n private markdownToOpusContent(markdown: string): {\n paragraphs: BilibiliOpusParagraph[]\n } {\n const tokens = marked.lexer(markdown, {\n gfm: true,\n breaks: true,\n }) as MarkedToken[]\n\n const paragraphs = tokens.flatMap((token) => this.markdownTokenToParagraphs(token))\n\n if (paragraphs.length === 0) {\n throw new Error('文章内容为空,无法发布到B站')\n }\n\n return { paragraphs }\n }\n\n private markdownTokenToParagraphs(token: MarkedToken): BilibiliOpusParagraph[] {\n switch (token.type) {\n case 'space':\n return []\n\n case 'heading':\n return [\n this.createHeadingParagraph(\n this.inlineTokensToNodes(token.tokens || [{ type: 'text', text: token.text || '' }]),\n Number(token.depth || 1),\n ),\n ]\n\n case 'paragraph':\n return this.inlineParagraphs(token.tokens, token.text)\n\n case 'blockquote':\n return this.createBlockquoteParagraphs(token)\n\n case 'list':\n return this.createListParagraphs(token)\n\n case 'code':\n return [this.createCodeBlockParagraph(String(token.text || ''), String(token.lang || ''))]\n\n case 'table':\n return this.createTableParagraphs(token)\n\n case 'hr':\n return [this.createLineParagraph()]\n\n case 'html':\n return this.htmlToOpusContent(String(token.text || '')).paragraphs\n\n default:\n return this.inlineParagraphs(token.tokens, token.text)\n }\n }\n\n private inlineParagraphs(\n tokens?: MarkedToken[],\n fallback = '',\n style: InlineStyle = {},\n ): BilibiliOpusParagraph[] {\n const paragraphs: BilibiliOpusParagraph[] = []\n let nodes: BilibiliOpusTextNode[] = []\n let textRun: MarkedToken[] = []\n\n const flush = () => {\n if (nodes.length > 0) {\n paragraphs.push(this.createTextParagraph(nodes))\n nodes = []\n }\n }\n const flushTextRun = () => {\n if (textRun.length > 0) {\n nodes.push(...this.inlineTokensToNodes(textRun, style))\n textRun = []\n }\n }\n\n const inlineTokens = tokens?.length ? tokens : [{ type: 'text', text: fallback }]\n for (const token of inlineTokens) {\n if (token.type === 'br') {\n flushTextRun()\n flush()\n continue\n }\n\n if (token.type === 'image') {\n flushTextRun()\n flush()\n paragraphs.push(this.createImageParagraph(String(token.href || '')))\n continue\n }\n\n textRun.push(token)\n }\n\n flushTextRun()\n flush()\n return paragraphs\n }\n\n private inlineTokensToNodes(\n tokens: MarkedToken[] = [],\n style: InlineStyle = {},\n ): BilibiliOpusTextNode[] {\n const nodes: BilibiliOpusTextNode[] = []\n const baseUnderlineDepth = style.underline ? 1 : 0\n let underlineDepth = baseUnderlineDepth\n const activeStyle = (): InlineStyle => ({\n ...style,\n underline: underlineDepth > 0,\n })\n\n for (const token of tokens) {\n switch (token.type) {\n case 'strong':\n nodes.push(...this.inlineTokensToNodes(token.tokens, { ...activeStyle(), bold: true }))\n break\n\n case 'em':\n nodes.push(...this.inlineTokensToNodes(token.tokens, { ...activeStyle(), italic: true }))\n break\n\n case 'del':\n nodes.push(...this.inlineTokensToNodes(token.tokens, { ...activeStyle(), strikethrough: true }))\n break\n\n case 'codespan':\n nodes.push(this.createWordNode(String(token.text || ''), { ...activeStyle(), code: true }))\n break\n\n case 'link':\n nodes.push(...this.inlineTokensToNodes(token.tokens, activeStyle()))\n break\n\n case 'br':\n nodes.push(this.createWordNode('\\n', activeStyle()))\n break\n\n case 'image':\n if (token.text) {\n nodes.push(this.createWordNode(String(token.text), activeStyle()))\n }\n break\n\n case 'html':\n const html = String(token.text || token.raw || '').trim()\n if (/^<u\\b[^>]*>$/i.test(html)) {\n underlineDepth += 1\n break\n }\n if (/^<\\/u>$/i.test(html)) {\n underlineDepth = Math.max(baseUnderlineDepth, underlineDepth - 1)\n break\n }\n nodes.push(...this.htmlInlineToNodes(html, activeStyle()))\n break\n\n default:\n if (token.tokens?.length) {\n nodes.push(...this.inlineTokensToNodes(token.tokens, activeStyle()))\n } else if (token.text) {\n nodes.push(this.createWordNode(String(token.text), activeStyle()))\n }\n }\n }\n\n return this.mergeAdjacentNodes(nodes)\n }\n\n private htmlInlineToNodes(html: string, style: InlineStyle = {}): BilibiliOpusTextNode[] {\n const underlineMatch = html.match(/^<u\\b[^>]*>([\\s\\S]*)<\\/u>$/i)\n if (underlineMatch) {\n return [this.createWordNode(this.stripHtml(underlineMatch[1]), { ...style, underline: true })]\n }\n\n const brOnly = /^<br\\s*\\/?>$/i.test(html.trim())\n if (brOnly) {\n return [this.createWordNode('\\n', style)]\n }\n\n const text = this.stripHtml(html)\n return text ? [this.createWordNode(text, style)] : []\n }\n\n private createListParagraphs(\n token: MarkedToken,\n level = 1,\n combineHash = this.createCombineHash('list'),\n ): BilibiliOpusParagraph[] {\n const paraType = token.ordered ? 5 : 6\n const start = token.ordered ? Number(token.start || 1) : 1\n\n return (token.items || []).flatMap((item, index) =>\n this.createListItemParagraphs(\n item,\n paraType,\n level,\n token.ordered ? start + index : index + 1,\n combineHash,\n ),\n )\n }\n\n private createListItemParagraphs(\n item: MarkedListItem,\n paraType: number,\n level: number,\n order: number,\n combineHash: string,\n ): BilibiliOpusParagraph[] {\n const paragraphs: BilibiliOpusParagraph[] = []\n let hasListParagraph = false\n\n for (const token of item.tokens || []) {\n if (token.type === 'list') {\n paragraphs.push(...this.createListParagraphs(token, level + 1))\n continue\n }\n\n const nodes = this.markdownBlockTokenToInlineNodes(token, item)\n if (nodes.length === 0) continue\n\n if (!hasListParagraph) {\n paragraphs.push(this.createListParagraph(paraType, nodes, level, order, combineHash))\n hasListParagraph = true\n } else {\n paragraphs.push(this.createTextParagraph(nodes, { combine_hash: combineHash }))\n }\n }\n\n if (!hasListParagraph) {\n paragraphs.unshift(\n this.createListParagraph(paraType, [], level, order, combineHash),\n )\n }\n\n return paragraphs\n }\n\n private markdownBlockTokenToInlineNodes(\n token: MarkedToken,\n item?: MarkedListItem,\n ): BilibiliOpusTextNode[] {\n const prefix = item?.task ? `${item.checked ? '[x]' : '[ ]'} ` : ''\n const nodes = prefix ? [this.createWordNode(prefix)] : []\n\n if (token.type === 'code') {\n nodes.push(this.createWordNode(String(token.text || ''), { code: true }))\n return this.mergeAdjacentNodes(nodes)\n }\n\n nodes.push(\n ...this.inlineTokensToNodes(token.tokens || [{ type: 'text', text: token.text || '' }]),\n )\n return this.mergeAdjacentNodes(nodes)\n }\n\n private createCodeBlockParagraph(code: string, lang = ''): BilibiliOpusParagraph {\n return {\n para_type: 8,\n code: {\n lang,\n content: code,\n },\n }\n }\n\n private createTableParagraphs(token: MarkedToken): BilibiliOpusParagraph[] {\n const table = token.raw?.trim() || this.tableToMarkdown(token)\n return table ? [this.createCodeBlockParagraph(table, 'markdown')] : []\n }\n\n private tableToMarkdown(token: MarkedToken): string {\n const header = this.tableCellsToMarkdownRow(token.header || [])\n const delimiter = this.tableCellsToMarkdownRow((token.header || []).map(() => ({ text: '---' })))\n const rows = (token.rows || []).map((row) => this.tableCellsToMarkdownRow(row))\n return [header, delimiter, ...rows].filter(Boolean).join('\\n')\n }\n\n private tableCellsToMarkdownRow(cells: MarkedTableCell[]): string {\n const values = cells\n .map((cell) => this.inlineTokensToPlainText(cell.tokens, cell.text))\n .map((value) => value.replace(/\\s+/g, ' ').trim())\n .filter(Boolean)\n\n if (values.length === 0) return ''\n return `| ${values.join(' | ')} |`\n }\n\n private inlineTokensToPlainText(tokens?: MarkedToken[], fallback = ''): string {\n const inlineTokens = tokens?.length ? tokens : [{ type: 'text', text: fallback }]\n return inlineTokens\n .map((token) => {\n if (token.tokens?.length) return this.inlineTokensToPlainText(token.tokens)\n if (token.type === 'image') return token.text || ''\n return token.text || ''\n })\n .join('')\n }\n\n private createBlockquoteParagraphs(\n token: MarkedToken,\n combineHash = this.createCombineHash('blockquote'),\n ): BilibiliOpusParagraph[] {\n const paragraphs: BilibiliOpusParagraph[] = []\n\n for (const child of token.tokens || []) {\n if (child.type === 'blockquote') {\n paragraphs.push(...this.createBlockquoteParagraphs(child, combineHash))\n continue\n }\n\n if (child.type !== 'paragraph' && child.type !== 'heading' && child.type !== 'text') {\n continue\n }\n\n let nodes = this.inlineTokensToNodes(\n child.tokens || [{ type: 'text', text: child.text || '' }],\n )\n if (child.type === 'heading') {\n nodes = this.applyWordTypography(nodes, Number(child.depth || 1))\n }\n\n paragraphs.push(this.createReferenceParagraph(nodes, { combine_hash: combineHash }))\n }\n\n if (paragraphs.length === 0) {\n paragraphs.push(this.createReferenceParagraph([], { combine_hash: combineHash }))\n }\n\n return paragraphs\n }\n\n private createTextParagraph(\n nodes: BilibiliOpusTextNode[],\n format: Record<string, unknown> = {},\n ): BilibiliOpusParagraph {\n return {\n para_type: 1,\n format,\n text: {\n nodes,\n },\n }\n }\n\n private createHeadingParagraph(nodes: BilibiliOpusTextNode[], level: number): BilibiliOpusParagraph {\n const format: Record<string, unknown> = {}\n if (level >= 1 && level <= 3) {\n format.heading_type = level\n }\n\n return {\n para_type: 9,\n format,\n text: {\n nodes: this.applyWordTypography(nodes, level),\n },\n }\n }\n\n private createReferenceParagraph(\n nodes: BilibiliOpusTextNode[],\n format: Record<string, unknown> = {},\n ): BilibiliOpusParagraph {\n return {\n para_type: 4,\n format,\n text: {\n nodes,\n },\n }\n }\n\n private createLineParagraph(): BilibiliOpusParagraph {\n return {\n para_type: 3,\n line: {\n line_type: 1,\n },\n }\n }\n\n private createListParagraph(\n paraType: number,\n nodes: BilibiliOpusTextNode[],\n level: number,\n order: number,\n combineHash: string,\n ): BilibiliOpusParagraph {\n return {\n para_type: paraType,\n format: {\n align: 0,\n list_format: {\n level,\n order,\n theme: this.getListTheme(paraType, level),\n },\n combine_hash: combineHash,\n },\n text: {\n nodes,\n },\n }\n }\n\n private createImageParagraph(url: string): BilibiliOpusParagraph {\n return {\n para_type: 2,\n pic: {\n style: 0,\n pics: [\n {\n url: this.normalizeImageUrl(url),\n width: 0,\n height: 0,\n size: 0,\n },\n ],\n },\n }\n }\n\n private createWordNode(words: string, style: InlineStyle = {}): BilibiliOpusTextNode {\n const wordStyle: Record<string, boolean> = {}\n if (style.bold) wordStyle.bold = true\n if (style.italic) wordStyle.italic = true\n if (style.strikethrough) wordStyle.strikethrough = true\n if (style.underline) wordStyle.underline = true\n\n const word: Record<string, unknown> = {\n words: this.decodeHtmlEntities(words),\n font_size: style.fontSize || DEFAULT_FONT_SIZE,\n color: '',\n dark_color: '',\n style: wordStyle,\n font_level: style.fontLevel || DEFAULT_FONT_LEVEL,\n }\n\n if (style.code) {\n word.bg_style = {\n style: 1,\n color: {\n color: '#F1F2F3',\n dark_color: '',\n },\n }\n }\n\n return {\n node_type: 1,\n word,\n }\n }\n\n private applyWordTypography(nodes: BilibiliOpusTextNode[], level: number): BilibiliOpusTextNode[] {\n const headingStyle = HEADING_STYLES[level] || HEADING_STYLES[1]\n return nodes.map((node) => {\n if (node.node_type !== 1 || !node.word) return node\n const word = node.word as Record<string, unknown>\n return {\n ...node,\n word: {\n ...word,\n font_size: headingStyle.fontSize,\n font_level: headingStyle.fontLevel,\n },\n }\n })\n }\n\n private getListTheme(paraType: number, level: number): string {\n const themes = paraType === 5 ? LIST_THEMES.sorted : LIST_THEMES.unsorted\n return themes[(level - 1) % themes.length]\n }\n\n private createCombineHash(prefix: string): string {\n return `${prefix}_${Date.now()}_${Math.random()}`\n }\n\n private mergeAdjacentNodes(nodes: BilibiliOpusTextNode[]): BilibiliOpusTextNode[] {\n const merged: BilibiliOpusTextNode[] = []\n\n for (const node of nodes) {\n const words = this.getNodeWords(node)\n if (!words) continue\n\n const previous = merged[merged.length - 1]\n if (previous && this.haveSameWordStyle(previous, node)) {\n const previousWord = previous.word as Record<string, unknown>\n previousWord.words = `${previousWord.words || ''}${words}`\n } else {\n merged.push(node)\n }\n }\n\n return merged\n }\n\n private getNodeWords(node: BilibiliOpusTextNode): string {\n const word = node.word as Record<string, unknown> | undefined\n return typeof word?.words === 'string' ? word.words : ''\n }\n\n private haveSameWordStyle(a: BilibiliOpusTextNode, b: BilibiliOpusTextNode): boolean {\n const aw = a.word as Record<string, unknown> | undefined\n const bw = b.word as Record<string, unknown> | undefined\n return JSON.stringify({\n style: aw?.style,\n font_size: aw?.font_size,\n font_level: aw?.font_level,\n color: aw?.color,\n dark_color: aw?.dark_color,\n bg_style: aw?.bg_style,\n }) === JSON.stringify({\n style: bw?.style,\n font_size: bw?.font_size,\n font_level: bw?.font_level,\n color: bw?.color,\n dark_color: bw?.dark_color,\n bg_style: bw?.bg_style,\n })\n }\n\n private htmlToOpusContent(html: string): {\n paragraphs: BilibiliOpusParagraph[]\n } {\n const images: Array<{\n url: string\n width: number\n height: number\n size: number\n }> = []\n const withoutScripts = html.replace(/<(script|style)[^>]*>[\\s\\S]*?<\\/\\1>/gi, '')\n const withImageTokens = withoutScripts.replace(/<img\\b[^>]*>/gi, (tag) => {\n const src = this.extractHtmlAttr(tag, 'src')\n if (!src) return ''\n\n const index = images.length\n images.push({\n url: this.normalizeImageUrl(src),\n width: this.toNumber(\n this.extractHtmlAttr(tag, 'data-width') || this.extractHtmlAttr(tag, 'width'),\n ),\n height: this.toNumber(\n this.extractHtmlAttr(tag, 'data-height') || this.extractHtmlAttr(tag, 'height'),\n ),\n size: this.toNumber(\n this.extractHtmlAttr(tag, 'data-size') || this.extractHtmlAttr(tag, 'size'),\n ),\n })\n\n return `\\n__BILIBILI_IMAGE_${index}__\\n`\n })\n\n const text = this.htmlToReadableText(withImageTokens)\n\n const paragraphs: BilibiliOpusParagraph[] = []\n const tokenRegex = /__BILIBILI_IMAGE_(\\d+)__/g\n let cursor = 0\n let match: RegExpExecArray | null\n\n const appendText = (value: string) => {\n for (const line of value.split(/\\n+/)) {\n const words = line.trim()\n if (words) {\n paragraphs.push(this.createTextParagraph([this.createWordNode(words)]))\n }\n }\n }\n\n while ((match = tokenRegex.exec(text)) !== null) {\n appendText(text.slice(cursor, match.index))\n const image = images[Number(match[1])]\n if (image) {\n paragraphs.push(this.createImageParagraph(image.url))\n }\n cursor = match.index + match[0].length\n }\n\n appendText(text.slice(cursor))\n\n if (paragraphs.length === 0) {\n throw new Error('文章内容为空,无法发布到B站')\n }\n\n return { paragraphs }\n }\n\n private htmlToReadableText(html: string): string {\n const structured = html\n .replace(/<pre\\b[^>]*>([\\s\\S]*?)<\\/pre>/gi, (_match, body: string) => {\n const code = this.htmlInlineToText(body).trim()\n return code ? `\\n\\`\\`\\`\\n${code}\\n\\`\\`\\`\\n` : '\\n'\n })\n .replace(/<h([1-6])\\b[^>]*>([\\s\\S]*?)<\\/h\\1>/gi, (_match, _level: string, body: string) => {\n const heading = this.htmlInlineToText(body).trim()\n return heading ? `\\n${heading}\\n` : '\\n'\n })\n .replace(/<table\\b[^>]*>([\\s\\S]*?)<\\/table>/gi, (_match, body: string) => {\n const table = this.htmlTableToText(body)\n return table ? `\\n${table}\\n` : '\\n'\n })\n .replace(/<(ul|ol)\\b[^>]*>([\\s\\S]*?)<\\/\\1>/gi, (_match, tag: string, body: string) => {\n const ordered = tag.toLowerCase() === 'ol'\n let index = 0\n const items = [...body.matchAll(/<li\\b[^>]*>([\\s\\S]*?)<\\/li>/gi)]\n .map((item) => {\n const text = this.htmlInlineToText(item[1]).replace(/\\s+/g, ' ').trim()\n if (!text) return ''\n index += 1\n return `${ordered ? `${index}、` : '•'} ${text}`\n })\n .filter(Boolean)\n return items.length ? `\\n${items.join('\\n')}\\n` : '\\n'\n })\n .replace(/<blockquote\\b[^>]*>([\\s\\S]*?)<\\/blockquote>/gi, (_match, body: string) => {\n const quote = this.htmlInlineToText(body)\n .split(/\\n+/)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((line) => `引用:${line}`)\n .join('\\n')\n return quote ? `\\n${quote}\\n` : '\\n'\n })\n\n return this.htmlInlineToText(structured)\n }\n\n private htmlTableToText(html: string): string {\n const rows = [...html.matchAll(/<tr\\b[^>]*>([\\s\\S]*?)<\\/tr>/gi)]\n .map((row) => [...row[1].matchAll(/<t[hd]\\b[^>]*>([\\s\\S]*?)<\\/t[hd]>/gi)]\n .map((cell) => this.htmlInlineToText(cell[1]).replace(/\\s+/g, ' ').trim()))\n .filter((row) => row.length > 0)\n\n if (rows.length === 0) return ''\n\n const lines = rows.map((row) => row.join(' | '))\n return lines.join('\\n')\n }\n\n private htmlInlineToText(html: string): string {\n return this.stripHtml(html)\n }\n\n private stripHtml(html: string): string {\n return this.decodeHtmlEntities(\n html\n .replace(/<br\\s*\\/?>/gi, '\\n')\n .replace(/<\\/(p|div|section|article|li|tr|pre|h[1-6])>/gi, '\\n')\n .replace(/<[^>]+>/g, ''),\n )\n }\n\n private createUploadId(): string {\n const mid = this.userInfo?.mid || 0\n const timestamp = Math.floor(Date.now() / 1000)\n const random = Math.floor(Math.random() * 10000)\n .toString()\n .padStart(4, '0')\n return `${mid}_${timestamp}_${random}`\n }\n\n private async ensureWbiKeys(): Promise<void> {\n if (this.wbiKeys) return\n\n const res = await this.get<{\n code: number\n data?: BilibiliNavData\n }>('https://api.bilibili.com/x/web-interface/nav?build=0&mobi_app=web')\n\n if (res.code === 0 && res.data?.wbi_img) {\n this.wbiKeys = this.extractWbiKeys(res.data.wbi_img)\n }\n\n if (!this.wbiKeys) {\n throw new Error('获取 B站 WBI 签名 key 失败,请刷新页面后重试')\n }\n }\n\n private extractWbiKeys(wbiImg?: BilibiliNavData['wbi_img']): BilibiliWbiKeys | null {\n if (!wbiImg) return null\n\n const imgKey = this.extractFilename(wbiImg.img_url)\n const subKey = this.extractFilename(wbiImg.sub_url)\n\n if (!imgKey || !subKey) return null\n return { imgKey, subKey }\n }\n\n private signWbiParams(params: Record<string, string>): Record<string, string> {\n if (!this.wbiKeys) {\n throw new Error('B站 WBI 签名 key 未获取')\n }\n\n const mixinKey = WBI_MIXIN_KEY_ENC_TAB.map(\n (index) => `${this.wbiKeys!.imgKey}${this.wbiKeys!.subKey}`[index],\n )\n .filter(Boolean)\n .join('')\n .slice(0, 32)\n const wts = Math.round(Date.now() / 1000).toString()\n const signedParams: Record<string, string> = { ...params, wts }\n const query = Object.keys(signedParams)\n .sort()\n .map((key) => {\n const value = signedParams[key].replace(/[!'()*]/g, '')\n return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`\n })\n .join('&')\n\n return {\n ...signedParams,\n w_rid: jsMd5(query + mixinKey),\n }\n }\n\n private resolvePostId(data?: BilibiliOpusResponseData): string | undefined {\n const id =\n data?.cvid ??\n data?.cvid_str ??\n data?.aid ??\n data?.id ??\n data?.dyn_id_str ??\n data?.dyn_id ??\n data?.dyn_rid\n return id === undefined ? undefined : String(id)\n }\n\n private resolvePostUrl(data?: BilibiliOpusResponseData): string {\n const cvid = data?.cvid ?? data?.cvid_str ?? data?.aid ?? data?.id\n if (cvid !== undefined) {\n return `https://www.bilibili.com/read/cv${cvid}`\n }\n\n const dynId = data?.dyn_id_str ?? data?.dyn_id\n if (dynId !== undefined) {\n return `https://t.bilibili.com/${dynId}`\n }\n\n return 'https://member.bilibili.com/platform/upload-manager/opus'\n }\n\n private extractFilename(url: string): string {\n return url.substring(url.lastIndexOf('/') + 1).split('.')[0] || ''\n }\n\n private extractHtmlAttr(tag: string, name: string): string {\n const match = tag.match(new RegExp(`\\\\s${name}=([\"'])(.*?)\\\\1`, 'i'))\n return match?.[2] || ''\n }\n\n private normalizeImageUrl(url: string): string {\n return url.replace(/^\\/\\//, 'https://').replace(/@.*$/, '')\n }\n\n private normalizePublicUrl(url?: string): string | undefined {\n if (!url) return undefined\n if (url.startsWith('//')) return `https:${url}`\n if (url.startsWith('/')) return `https://www.bilibili.com${url}`\n return url\n }\n\n private async createCoverInfo(result: ImageUploadResult): Promise<BilibiliCoverInfo> {\n const url = this.normalizeImageUrl(result.url)\n const cover: BilibiliCoverInfo = {\n url: this.toOfficialCoverUrl(url),\n }\n\n try {\n const response = await this.runtime.fetch(`${url}@info`, { credentials: 'include' })\n const info = await response.json() as {\n width?: number\n height?: number\n file_size?: number\n }\n if (Number.isFinite(info.width)) cover.width = info.width\n if (Number.isFinite(info.height)) cover.height = info.height\n if (Number.isFinite(info.file_size)) cover.size = Number(info.file_size) / 1024\n } catch {\n const size = Number(result.attrs?.size)\n if (Number.isFinite(size) && size > 0) cover.size = size\n }\n\n return cover\n }\n\n private toOfficialCoverUrl(url: string): string {\n return url.replace(/^https:\\/\\//, 'http://')\n }\n\n private toNumber(value?: string): number {\n const number = Number(value)\n return Number.isFinite(number) ? number : 0\n }\n\n private decodeHtmlEntities(value: string): string {\n return value.replace(/&(#x?[0-9a-f]+|[a-z]+);/gi, (_, entity: string) => {\n if (entity[0] === '#') {\n const radix = entity[1]?.toLowerCase() === 'x' ? 16 : 10\n const codePoint = parseInt(entity.slice(radix === 16 ? 2 : 1), radix)\n return Number.isFinite(codePoint) ? String.fromCodePoint(codePoint) : _\n }\n\n const namedEntities: Record<string, string> = {\n amp: '&',\n lt: '<',\n gt: '>',\n quot: '\"',\n apos: \"'\",\n nbsp: ' ',\n }\n\n return namedEntities[entity.toLowerCase()] ?? _\n })\n }\n\n protected async uploadImageByUrl(src: string): Promise<ImageUploadResult> {\n if (!this.csrf) {\n throw new Error('CSRF token 未获取')\n }\n\n const imageResponse = await fetch(src)\n if (!imageResponse.ok) {\n throw new Error('图片下载失败: ' + src)\n }\n const imageBlob = await imageResponse.blob()\n\n const formData = new FormData()\n formData.append('binary', imageBlob, 'image.jpg')\n formData.append('csrf', this.csrf)\n\n const uploadUrl = 'https://api.bilibili.com/x/article/creative/article/upcover'\n const uploadResponse = await this.runtime.fetch(uploadUrl, {\n method: 'POST',\n credentials: 'include',\n body: formData,\n })\n\n const res = (await uploadResponse.json()) as {\n code: number\n message?: string\n data?: {\n url: string\n size: number\n }\n }\n\n logger.debug('Image upload response:', res)\n\n if (res.code !== 0 || !res.data?.url) {\n throw new Error(res.message || '图片上传失败')\n }\n\n return {\n url: res.data.url,\n attrs: {\n size: String(res.data.size),\n },\n }\n }\n}\n","/**\n * 博客园 (cnblogs.com) 适配器\n */\nimport { CodeAdapter, type ImageUploadResult } from '../code-adapter'\nimport type { Article, AuthResult, PublishStatusRef, PublishStatusResult, SyncResult, PlatformMeta } from '../../types'\nimport type { PublishOptions } from '../types'\nimport { createLogger } from '../../lib/logger'\n\nconst logger = createLogger('Cnblogs')\n\ninterface CnblogsPostDetail {\n id?: string | number\n title?: string\n isPublished?: boolean\n isDraft?: boolean\n postType?: number\n url?: string | null\n error?: string\n}\n\ninterface CnblogsPostListResponse {\n postList?: CnblogsPostDetail[]\n errors?: string[]\n error?: string\n}\n\nexport class CnblogsAdapter extends CodeAdapter {\n readonly meta: PlatformMeta = {\n id: 'cnblogs',\n name: '博客园',\n icon: 'https://www.cnblogs.com/favicon.ico',\n homepage: 'https://www.cnblogs.com',\n capabilities: ['article', 'image_upload'],\n }\n\n /** 预处理配置: 博客园使用 Markdown 格式 */\n readonly preprocessConfig = {\n outputFormat: 'markdown' as const,\n }\n\n private xsrfToken: string | null = null\n\n /** 博客园 API 需要的 Header 规则 */\n private readonly HEADER_RULES = [\n {\n urlFilter: '*://i.cnblogs.com/*',\n headers: {\n 'Origin': 'https://i.cnblogs.com',\n 'Referer': 'https://i.cnblogs.com/',\n },\n resourceTypes: ['xmlhttprequest'],\n },\n {\n urlFilter: '*://upload.cnblogs.com/*',\n headers: {\n 'Origin': 'https://i.cnblogs.com',\n 'Referer': 'https://i.cnblogs.com/',\n },\n resourceTypes: ['xmlhttprequest'],\n },\n ]\n\n /**\n * 从 cookie 中获取 XSRF-TOKEN\n */\n private async getXsrfToken(): Promise<string | null> {\n if (this.xsrfToken) {\n return this.xsrfToken\n }\n\n try {\n // 先访问页面以触发 cookie 设置\n await this.runtime.fetch('https://i.cnblogs.com/posts/edit', {\n method: 'GET',\n credentials: 'include',\n })\n\n // 使用 cookies API 获取 XSRF-TOKEN\n if (this.runtime.getCookie) {\n logger.debug('Trying to get XSRF-TOKEN via getCookie API...')\n\n // 尝试不同的域名格式\n const domains = ['i.cnblogs.com', '.cnblogs.com', 'cnblogs.com']\n for (const domain of domains) {\n const value = await this.runtime.getCookie(domain, 'XSRF-TOKEN')\n logger.debug(`getCookie ${domain} result:`, value ? `${value.substring(0, 30)}...` : 'null')\n if (value) {\n this.xsrfToken = value\n logger.debug('Got XSRF-TOKEN from cookies API')\n return this.xsrfToken\n }\n }\n } else {\n logger.warn('getCookie API not available')\n }\n\n logger.warn('Could not find XSRF-TOKEN')\n return null\n } catch (error) {\n logger.error('Failed to get XSRF-TOKEN:', error)\n return null\n }\n }\n\n async checkAuth(): Promise<AuthResult> {\n try {\n const response = await this.runtime.fetch('https://home.cnblogs.com/user/CurrentUserInfo', {\n method: 'GET',\n credentials: 'include',\n })\n\n const text = await response.text()\n\n // 解析 HTML 响应获取用户信息\n // 页面结构: <a href=\"/u/xxx/\"><img class=\"pfs\" src=\"...\"></a>\n const avatarMatch = text.match(/<img[^>]+class=\"pfs\"[^>]+src=\"([^\"]+)\"/)\n const linkMatch = text.match(/href=\"\\/u\\/([^/]+)\\/\"/)\n\n if (!linkMatch) {\n return { isAuthenticated: false }\n }\n\n const uid = linkMatch[1]\n const avatar = avatarMatch ? avatarMatch[1] : undefined\n\n return {\n isAuthenticated: true,\n userId: uid,\n username: uid,\n avatar,\n }\n } catch (error) {\n logger.debug('checkAuth: not logged in -', error)\n return { isAuthenticated: false, error: (error as Error).message }\n }\n }\n\n async publish(article: Article, options?: PublishOptions): Promise<SyncResult> {\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n logger.info('Starting publish to cnblogs...')\n const auth = await this.checkAuth()\n if (!auth.isAuthenticated) {\n throw new Error('请先登录博客园')\n }\n\n // 1. Get XSRF-TOKEN\n const xsrfToken = await this.getXsrfToken()\n logger.info('XSRF-TOKEN:', xsrfToken ? `${xsrfToken.substring(0, 20)}...` : 'null')\n if (!xsrfToken) {\n throw new Error('获取 XSRF-TOKEN 失败,请刷新页面后重试')\n }\n\n // 保存 xsrfToken 供 uploadImageByUrl 使用\n this.xsrfToken = xsrfToken\n\n // 2. 处理图片上传\n let markdown = article.markdown || ''\n logger.debug('Markdown before processImages:', markdown.substring(0, 200))\n\n markdown = await this.processImages(\n markdown,\n (src) => this.uploadImageByUrl(src),\n {\n skipPatterns: ['cnblogs.com', 'img2024.cnblogs.com', 'img2023.cnblogs.com'],\n onProgress: options?.onImageProgress,\n }\n )\n\n logger.debug('Markdown after processImages:', markdown.substring(0, 200))\n const cover = article.cover ? (await this.uploadImageByUrl(article.cover)).url : null\n\n // 3. Build request headers\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-xsrf-token': xsrfToken,\n }\n\n logger.debug('Request headers:', JSON.stringify(headers))\n logger.debug('Markdown content length:', markdown.length)\n\n // 4. 直接发布\n const now = new Date().toISOString()\n const response = await this.runtime.fetch('https://i.cnblogs.com/api/posts', {\n method: 'POST',\n credentials: 'include',\n headers,\n body: JSON.stringify({\n id: null,\n postType: 2, // 2 = 文章, 1 = 随笔\n accessPermission: 0,\n title: article.title,\n url: null,\n postBody: markdown,\n categoryIds: null,\n categories: null,\n collectionIds: [],\n inSiteCandidate: false,\n inSiteHome: false,\n siteCategoryId: null,\n blogTeamIds: null,\n isPublished: true,\n displayOnHomePage: true,\n isAllowComments: true,\n includeInMainSyndication: true,\n isPinned: false,\n showBodyWhenPinned: false,\n isOnlyForRegisterUser: false,\n isUpdateDateAdded: false,\n entryName: null,\n description: article.summary || null,\n featuredImage: cover,\n tags: this.resolveTags(article),\n password: null,\n publishAt: null,\n datePublished: now,\n dateUpdated: null,\n isMarkdown: true,\n isDraft: false,\n autoDesc: null,\n changePostType: false,\n blogId: 0,\n author: null,\n removeScript: false,\n clientInfo: null,\n changeCreatedTime: false,\n canChangeCreatedTime: false,\n isContributeToImpressiveBugActivity: false,\n usingEditorId: 5,\n sourceUrl: null,\n }),\n })\n\n // 检查响应\n const responseText = await response.text()\n logger.debug('Create post response:', response.status, responseText.substring(0, 300))\n\n if (!response.ok) {\n // 检查是否是认证错误\n if (response.status === 401 || response.status === 403) {\n throw new Error('未登录或登录已过期,请重新登录博客园')\n }\n throw new Error(`发布失败: ${response.status} - ${responseText}`)\n }\n\n let responseData: { id?: number; blogId?: number; error?: string }\n try {\n responseData = JSON.parse(responseText)\n } catch {\n throw new Error(`发布失败: 响应不是有效 JSON - ${responseText.substring(0, 100)}`)\n }\n\n if (!responseData.id) {\n throw new Error(responseData.error || '发布失败: 无效响应')\n }\n\n const postId = String(responseData.id)\n const blogUser = auth.userId || auth.username\n const postUrl = blogUser\n ? `https://www.cnblogs.com/${encodeURIComponent(blogUser)}/articles/${postId}`\n : `https://i.cnblogs.com/articles/edit;postId=${postId}`\n\n logger.debug('Post published:', postId)\n\n return this.createResult(true, {\n postId,\n postUrl,\n })\n }).catch((error) => this.createResult(false, {\n error: (error as Error).message,\n }))\n }\n\n async getStatus(statusRef: PublishStatusRef): Promise<PublishStatusResult> {\n const postId = statusRef.id || this.extractPostIdFromUrl(statusRef.url)\n if (!postId) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: '博客园 statusRef 缺少文章 ID',\n checkedAt: Date.now(),\n }\n }\n\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n const post = await this.findManagedPost(postId)\n if (!post) {\n return {\n platform: this.meta.id,\n state: 'not_found',\n message: '博客园管理端文章列表未找到该文章',\n checkedAt: Date.now(),\n }\n }\n\n return this.mapManagedPostStatus(post, statusRef)\n })\n }\n\n private async findManagedPost(postId: string): Promise<CnblogsPostDetail | null> {\n const pageSize = 50\n for (let pageIndex = 1; pageIndex <= 5; pageIndex++) {\n const response = await this.runtime.fetch(\n `https://i.cnblogs.com/api/posts/list?postType=2&pageIndex=${pageIndex}&pageSize=${pageSize}`,\n {\n method: 'GET',\n credentials: 'include',\n },\n )\n const responseText = await response.text()\n\n if (!response.ok) {\n throw new Error(`博客园状态查询失败: HTTP ${response.status} - ${responseText.substring(0, 200)}`)\n }\n\n let list: CnblogsPostListResponse\n try {\n list = JSON.parse(responseText) as CnblogsPostListResponse\n } catch {\n throw new Error(`博客园状态查询失败: 响应不是有效 JSON - ${responseText.substring(0, 100)}`)\n }\n\n const error = list.error || list.errors?.join('; ')\n if (error) {\n throw new Error(error)\n }\n\n const posts = list.postList || []\n const matched = posts.find(post => String(post.id) === postId)\n if (matched) return matched\n if (posts.length < pageSize) return null\n }\n return null\n }\n\n private mapManagedPostStatus(post: CnblogsPostDetail, statusRef: PublishStatusRef): PublishStatusResult {\n if (post.isPublished === true && post.isDraft !== true) {\n return {\n platform: this.meta.id,\n state: 'published',\n postUrl: this.resolvePublicUrl(statusRef, post),\n checkedAt: Date.now(),\n }\n }\n\n if (post.isPublished === false || post.isDraft === true) {\n return {\n platform: this.meta.id,\n state: 'reviewing',\n postUrl: statusRef.url,\n message: `not published or draft: isPublished=${post.isPublished ?? 'unknown'}, isDraft=${post.isDraft ?? 'unknown'}`,\n checkedAt: Date.now(),\n }\n }\n\n return {\n platform: this.meta.id,\n state: 'unknown',\n postUrl: statusRef.url,\n message: `博客园状态字段缺失: isPublished=${post.isPublished ?? 'unknown'}, isDraft=${post.isDraft ?? 'unknown'}`,\n checkedAt: Date.now(),\n }\n }\n\n private extractPostIdFromUrl(url?: string): string {\n if (!url) return ''\n const articleMatch = url.match(/\\/articles\\/(\\d+)/)\n if (articleMatch) return articleMatch[1]\n const postIdMatch = url.match(/[?;&]postId=(\\d+)/)\n return postIdMatch?.[1] || ''\n }\n\n private resolvePublicUrl(statusRef: PublishStatusRef, post: CnblogsPostDetail): string | undefined {\n if (statusRef.url?.startsWith('https://www.cnblogs.com/')) return statusRef.url\n if (typeof post.url === 'string' && post.url.startsWith('https://www.cnblogs.com/')) return post.url\n return statusRef.url\n }\n\n private resolveTags(article: Article): string[] | null {\n const tags = article.tags?.map(tag => tag.trim()).filter(Boolean).slice(0, 10)\n return tags?.length ? tags : null\n }\n\n /**\n * 上传图片到博客园\n * 使用新版 CORS 上传接口\n */\n protected async uploadImageByUrl(src: string): Promise<ImageUploadResult> {\n if (!this.xsrfToken) {\n throw new Error('XSRF-TOKEN 未获取')\n }\n\n // 下载图片\n const imageResponse = await fetch(src)\n if (!imageResponse.ok) {\n throw new Error('图片下载失败: ' + src)\n }\n const imageBlob = await imageResponse.blob()\n\n // 构建 FormData\n const formData = new FormData()\n formData.append('image', imageBlob, 'image.png')\n formData.append('app', 'blog')\n formData.append('uploadType', 'Select')\n\n // 上传图片\n const uploadResponse = await this.runtime.fetch(\n 'https://upload.cnblogs.com/v2/images/cors-upload',\n {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'x-xsrf-token': this.xsrfToken,\n },\n body: formData,\n }\n )\n\n const responseText = await uploadResponse.text()\n logger.debug('Image upload raw response:', responseText)\n\n if (!uploadResponse.ok) {\n throw new Error(`图片上传失败: ${uploadResponse.status} - ${responseText}`)\n }\n\n let res: Record<string, unknown>\n try {\n res = JSON.parse(responseText)\n } catch {\n throw new Error(`图片上传失败: 响应不是 JSON - ${responseText.substring(0, 100)}`)\n }\n\n logger.debug('Image upload parsed response:', JSON.stringify(res))\n\n // 尝试不同的响应格式\n const imageUrl = res.data || res.url || res.imageUrl || res.src\n if (!imageUrl || typeof imageUrl !== 'string') {\n throw new Error(`图片上传失败: 无法获取图片 URL - ${JSON.stringify(res)}`)\n }\n\n logger.info('Image uploaded:', imageUrl)\n return {\n url: imageUrl,\n }\n }\n}\n","/**\n * CSDN 适配器\n */\nimport { CodeAdapter, type ImageUploadResult } from '../code-adapter'\nimport type {\n Article,\n AuthResult,\n SyncResult,\n PlatformMeta,\n PublishStatusRef,\n PublishStatusResult,\n} from '../../types'\nimport type { PublishOptions } from '../types'\nimport { createLogger } from '../../lib/logger'\nimport { markdownToHtml } from '../../lib/turndown'\n\nconst logger = createLogger('CSDN')\n\ninterface CSDNUserInfo {\n csdnid: string\n username: string\n avatarurl: string\n}\n\ninterface CSDNArticleListItem {\n articleId?: string | number\n ArticleId?: string | number\n id?: string | number\n url?: string\n status?: string | number\n reason?: string\n rejectReason?: string\n auditReason?: string\n msg?: string\n}\n\ninterface CSDNArticleListResponse {\n code?: number\n message?: string\n msg?: string\n data?: {\n list?: CSDNArticleListItem[]\n } | CSDNArticleListItem[]\n}\n\nexport class CSDNAdapter extends CodeAdapter {\n readonly meta: PlatformMeta = {\n id: 'csdn',\n name: 'CSDN',\n icon: 'https://g.csdnimg.cn/static/logo/favicon32.ico',\n homepage: 'https://editor.csdn.net/md/',\n capabilities: ['article', 'image_upload', 'tags', 'cover'],\n }\n\n /** 预处理配置: CSDN 使用 Markdown 格式 */\n readonly preprocessConfig = {\n outputFormat: 'markdown' as const,\n }\n\n private userInfo: CSDNUserInfo | null = null\n\n // CSDN API 签名密钥\n private readonly API_KEY = '203803574'\n private readonly API_SECRET = '9znpamsyl2c7cdrr9sas0le9vbc3r6ba'\n\n /** CSDN API 需要的 Header 规则 */\n private readonly HEADER_RULES = [\n {\n urlFilter: '*://bizapi.csdn.net/*',\n headers: {\n 'Origin': 'https://editor.csdn.net',\n 'Referer': 'https://editor.csdn.net/',\n },\n resourceTypes: ['xmlhttprequest'],\n },\n {\n urlFilter: '*://imgservice.csdn.net/*',\n headers: {\n 'Origin': 'https://editor.csdn.net',\n 'Referer': 'https://editor.csdn.net/',\n },\n resourceTypes: ['xmlhttprequest'],\n },\n {\n urlFilter: '*://csdn-img-blog.obs.cn-north-4.myhuaweicloud.com/*',\n headers: {\n 'Origin': 'https://editor.csdn.net',\n 'Referer': 'https://editor.csdn.net/',\n },\n resourceTypes: ['xmlhttprequest'],\n },\n ]\n\n async checkAuth(): Promise<AuthResult> {\n try {\n // 使用带签名的 API\n const apiPath = '/blog-console-api/v3/editor/getBaseInfo'\n const headers = await this.signRequest(apiPath, 'GET')\n\n const response = await this.runtime.fetch(\n `https://bizapi.csdn.net${apiPath}`,\n {\n method: 'GET',\n credentials: 'include',\n headers,\n }\n )\n\n const res = await response.json() as {\n code: number\n data?: {\n name: string\n nickname: string\n avatar: string\n blog_url: string\n }\n }\n\n logger.debug('checkAuth response:', res)\n\n if (res.code === 200 && res.data?.name) {\n this.userInfo = {\n csdnid: res.data.name,\n username: res.data.nickname || res.data.name,\n avatarurl: res.data.avatar,\n }\n return {\n isAuthenticated: true,\n userId: res.data.name,\n username: res.data.nickname || res.data.name,\n avatar: res.data.avatar,\n }\n }\n\n return { isAuthenticated: false }\n } catch (error) {\n logger.debug('checkAuth: not logged in -', error)\n return { isAuthenticated: false, error: (error as Error).message }\n }\n }\n\n /**\n * 生成 UUID\n */\n private createUuid(): string {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = Math.random() * 16 | 0\n const v = c === 'x' ? r : (r & 0x3 | 0x8)\n return v.toString(16)\n })\n }\n\n /**\n * HMAC-SHA256 签名 (使用 Web Crypto API)\n */\n private async hmacSha256(message: string, secret: string): Promise<string> {\n const encoder = new TextEncoder()\n const keyData = encoder.encode(secret)\n const messageData = encoder.encode(message)\n\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n keyData,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign']\n )\n\n const signature = await crypto.subtle.sign('HMAC', cryptoKey, messageData)\n\n // 转换为 Base64\n const bytes = new Uint8Array(signature)\n let binary = ''\n for (let i = 0; i < bytes.byteLength; i++) {\n binary += String.fromCharCode(bytes[i])\n }\n return btoa(binary)\n }\n\n /**\n * 生成 CSDN API 签名\n * 签名格式: METHOD\\nAccept\\nContent-MD5\\nContent-Type\\n\\nHeaders\\nPath\n */\n private async signRequest(\n apiPath: string,\n method: 'GET' | 'POST' = 'POST',\n options: { includeStage?: boolean } = {},\n ): Promise<Record<string, string>> {\n const nonce = this.createUuid()\n const signedHeaders: Record<string, string> = {\n 'x-ca-key': this.API_KEY,\n 'x-ca-nonce': nonce,\n }\n if (options.includeStage) {\n signedHeaders['x-ca-stage'] = ''\n }\n\n const signatureHeaders = Object.keys(signedHeaders).sort()\n const canonicalHeaders = signatureHeaders\n .map(key => `${key}:${signedHeaders[key]}`)\n .join('\\n')\n const contentType = method === 'POST' ? 'application/json' : ''\n const signStr = [\n method,\n '*/*',\n '',\n contentType,\n '',\n canonicalHeaders,\n this.canonicalizeResource(apiPath),\n ].join('\\n')\n\n logger.debug('Sign string:', JSON.stringify(signStr))\n\n const signature = await this.hmacSha256(signStr, this.API_SECRET)\n\n const headers: Record<string, string> = {\n 'accept': '*/*',\n ...signedHeaders,\n 'x-ca-signature': signature,\n 'x-ca-signature-headers': signatureHeaders.join(','),\n }\n\n if (method === 'POST') {\n headers['content-type'] = 'application/json'\n }\n\n return headers\n }\n\n private canonicalizeResource(apiPath: string): string {\n const url = new URL(apiPath, 'https://bizapi.csdn.net')\n const params = Array.from(url.searchParams.entries())\n .filter(([, value]) => value !== undefined)\n .sort(([leftKey, leftValue], [rightKey, rightValue]) =>\n leftKey === rightKey ? leftValue.localeCompare(rightValue) : leftKey.localeCompare(rightKey)\n )\n\n if (params.length === 0) return url.pathname\n\n const query = params\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)\n .join('&')\n return `${url.pathname}?${query}`\n }\n\n private resolveTags(article: Article): string {\n const tags = article.tags?.map(tag => tag.trim()).filter(Boolean).slice(0, 5)\n return tags?.length ? tags.join(',') : 'Wechatsync'\n }\n\n private async postSaveArticle(\n apiPath: string,\n headers: Record<string, string>,\n payload: Record<string, unknown>,\n ): Promise<string> {\n const pageText = await this.postSaveArticleFromPage(apiPath, headers, payload)\n if (pageText !== null) return pageText\n\n const response = await this.runtime.fetch(\n `https://bizapi.csdn.net${apiPath}`,\n {\n method: 'POST',\n credentials: 'include',\n headers,\n body: JSON.stringify(payload),\n }\n )\n return response.text()\n }\n\n private async postSaveArticleFromPage(\n apiPath: string,\n headers: Record<string, string>,\n payload: Record<string, unknown>,\n ): Promise<string | null> {\n if (!this.runtime.tabs?.query || !this.runtime.tabs.executeScript) {\n return null\n }\n\n const tabId = await this.getCsdnTabId()\n if (!tabId) return null\n\n const result = await this.runtime.tabs.executeScript<{\n ok: boolean\n status: number\n statusText: string\n text: string\n }, [string, Record<string, string>, Record<string, unknown>]>(\n tabId,\n async (requestUrl, requestHeaders, requestPayload) => {\n const response = await fetch(requestUrl, {\n method: 'POST',\n credentials: 'include',\n headers: requestHeaders,\n body: JSON.stringify(requestPayload),\n })\n return {\n ok: response.ok,\n status: response.status,\n statusText: response.statusText,\n text: await response.text(),\n }\n },\n [`https://bizapi.csdn.net${apiPath}`, headers, payload],\n )\n\n if (!result.ok) {\n throw new Error(`CSDN 发布接口请求失败: HTTP ${result.status} ${result.text.slice(0, 200)}`)\n }\n\n return result.text\n }\n\n private async getCsdnTabId(): Promise<number | null> {\n const patterns = ['*://mp.csdn.net/*', '*://editor.csdn.net/*']\n for (const pattern of patterns) {\n const tabs = await this.runtime.tabs?.query(pattern)\n const tab = tabs?.find(item => typeof item.id === 'number')\n if (tab?.id) return tab.id\n }\n\n if (!this.runtime.tabs?.create) return null\n\n const tab = await this.runtime.tabs.create('https://mp.csdn.net/mp_blog/creation/editor', false)\n if (this.runtime.tabs.waitForLoad) {\n await this.runtime.tabs.waitForLoad(tab.id, 30000).catch((error) => {\n logger.debug('CSDN tab load wait failed:', error)\n })\n }\n return tab.id\n }\n\n async publish(article: Article, options?: PublishOptions): Promise<SyncResult> {\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n logger.info('Starting publish...')\n\n // 1. 确保已登录\n if (!this.userInfo) {\n const auth = await this.checkAuth()\n if (!auth.isAuthenticated) {\n throw new Error('请先登录 CSDN')\n }\n }\n\n // Use pre-processed markdown content directly\n let markdown = article.markdown || ''\n\n // Process images in markdown\n markdown = await this.processImages(\n markdown,\n (src) => this.uploadImageByUrl(src),\n {\n skipPatterns: ['csdnimg.cn', 'csdn.net'],\n onProgress: options?.onImageProgress,\n }\n )\n\n // CSDN stores both fields; content must mirror the uploaded-image markdown.\n const htmlContent = markdownToHtml(markdown)\n const cover = await this.resolveCover(article)\n\n // Generate signature and publish article. CSDN's public editor uses the\n // same endpoint for drafts and publish; pubStatus/status select the action.\n const apiPath = '/blog-console-api/v3/mdeditor/saveArticle'\n const headers = await this.signRequest(apiPath)\n\n const payload = {\n title: article.title,\n markdowncontent: markdown,\n content: htmlContent,\n readType: 'public',\n level: 0,\n tags: this.resolveTags(article),\n status: 0,\n categories: '',\n type: 'original',\n original_link: '',\n authorized_status: false,\n Description: article.summary || '',\n resource_url: '',\n not_auto_saved: '1',\n source: 'pc_mdeditor',\n cover_images: cover.images,\n cover_type: cover.type,\n is_new: 1,\n vote_id: 0,\n resource_id: '',\n pubStatus: 'publish',\n creation_statement: 0,\n creator_activity_id: '',\n }\n\n const text = await this.postSaveArticle(apiPath, headers, payload)\n const res = JSON.parse(text) as {\n code: number\n message?: string\n msg?: string\n data?: { id?: string | number; article_id?: string | number; url?: string }\n }\n\n logger.debug('Publish response:', res)\n\n const postId = String(res.data?.id || res.data?.article_id || '')\n if (res.code !== 200 || !postId) {\n throw new Error(res.msg || res.message || '发布文章失败')\n }\n\n const postUrl = res.data?.url || (\n this.userInfo?.csdnid\n ? `https://blog.csdn.net/${this.userInfo.csdnid}/article/details/${postId}`\n : `https://mp.csdn.net/mp_blog/creation/editor/${postId}`\n )\n\n return this.createResult(true, {\n postId,\n postUrl,\n })\n }).catch((error) => this.createResult(false, {\n error: (error as Error).message,\n }))\n }\n\n async getStatus(statusRef: PublishStatusRef): Promise<PublishStatusResult> {\n const postId = statusRef.id || this.extractPostIdFromUrl(statusRef.url)\n if (!postId) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: 'CSDN statusRef 缺少文章 ID',\n checkedAt: Date.now(),\n }\n }\n\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n const item = await this.findManagedArticle(postId)\n if (!item) {\n return {\n platform: this.meta.id,\n state: 'not_found',\n message: 'CSDN 管理端文章列表未找到该文章',\n checkedAt: Date.now(),\n }\n }\n\n return this.mapManagedStatus(item, statusRef, postId)\n })\n }\n\n private async findManagedArticle(postId: string): Promise<CSDNArticleListItem | null> {\n const pageSize = 20\n for (let page = 1; page <= 5; page++) {\n const query = new URLSearchParams({\n status: 'all_v3',\n pageSize: String(pageSize),\n })\n if (page > 1) query.set('page', String(page))\n\n const apiPath = `/blog/phoenix/console/v1/article/list?${query.toString()}`\n const headers = await this.signRequest(apiPath, 'GET', { includeStage: true })\n const response = await this.runtime.fetch(`https://bizapi.csdn.net${apiPath}`, {\n method: 'GET',\n credentials: 'include',\n headers,\n })\n const responseText = await response.text()\n\n if (!response.ok) {\n throw new Error(`CSDN 状态查询失败: HTTP ${response.status} - ${responseText.substring(0, 200)}`)\n }\n\n let res: CSDNArticleListResponse\n try {\n res = JSON.parse(responseText) as CSDNArticleListResponse\n } catch {\n throw new Error(`CSDN 状态查询失败: 响应不是有效 JSON - ${responseText.substring(0, 100)}`)\n }\n\n if (res.code !== undefined && res.code !== 200) {\n throw new Error(res.msg || res.message || `CSDN 状态查询失败: code=${res.code}`)\n }\n\n const list = Array.isArray(res.data) ? res.data : (res.data?.list || [])\n const matched = list.find(item => this.getArticleId(item) === postId)\n if (matched) return matched\n if (list.length < pageSize) return null\n }\n\n return null\n }\n\n private mapManagedStatus(\n item: CSDNArticleListItem,\n statusRef: PublishStatusRef,\n postId: string,\n ): PublishStatusResult {\n const status = String(item.status ?? '')\n const postUrl = this.resolvePublicUrl(item, statusRef, postId)\n const reason = item.reason || item.rejectReason || item.auditReason || item.msg\n\n if (status === '1') {\n return {\n platform: this.meta.id,\n state: 'published',\n postUrl,\n checkedAt: Date.now(),\n }\n }\n\n if (status === '16' || status === '7') {\n return {\n platform: this.meta.id,\n state: 'reviewing',\n postUrl,\n message: `CSDN 文章状态: 审核中,status=${status}`,\n checkedAt: Date.now(),\n }\n }\n\n if (status === '6' || status === '9' || status === '99') {\n return {\n platform: this.meta.id,\n state: 'rejected',\n postUrl,\n message: reason ? `CSDN 文章状态: 未通过,原因: ${reason}` : `CSDN 文章状态: 未通过,status=${status}`,\n checkedAt: Date.now(),\n }\n }\n\n if (status === '2') {\n return {\n platform: this.meta.id,\n state: 'reviewing',\n postUrl,\n message: 'CSDN 文章状态: 草稿',\n checkedAt: Date.now(),\n }\n }\n\n return {\n platform: this.meta.id,\n state: 'unknown',\n postUrl,\n message: `CSDN 状态字段未知: status=${status || 'missing'}`,\n checkedAt: Date.now(),\n }\n }\n\n private getArticleId(item: CSDNArticleListItem): string {\n return String(item.articleId ?? item.ArticleId ?? item.id ?? '')\n }\n\n private extractPostIdFromUrl(url?: string): string {\n if (!url) return ''\n const match = url.match(/\\/article\\/details\\/(\\d+)/)\n return match?.[1] || ''\n }\n\n private resolvePublicUrl(\n item: CSDNArticleListItem,\n statusRef: PublishStatusRef,\n postId: string,\n ): string | undefined {\n if (typeof item.url === 'string' && item.url.startsWith('https://blog.csdn.net/')) {\n return item.url\n }\n if (statusRef.url?.startsWith('https://blog.csdn.net/')) return statusRef.url\n if (this.userInfo?.csdnid) return `https://blog.csdn.net/${this.userInfo.csdnid}/article/details/${postId}`\n return statusRef.url\n }\n\n /**\n * 通过 Blob 上传图片(覆盖基类方法)\n * 需要设置动态请求头规则以支持 MCP 调用\n */\n async uploadImage(file: Blob, _filename?: string): Promise<string> {\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n // 转为 data URI 然后调用 uploadImageByUrl\n const dataUri = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => resolve(reader.result as string)\n reader.onerror = reject\n reader.readAsDataURL(file)\n })\n const result = await this.uploadImageByUrl(dataUri)\n return result.url\n })\n }\n\n /**\n * 通过 URL 上传图片\n */\n protected async uploadImageByUrl(src: string): Promise<ImageUploadResult> {\n // 1. 下载图片\n const imageResponse = await fetch(src)\n if (!imageResponse.ok) {\n throw new Error('图片下载失败: ' + src)\n }\n const imageBlob = await imageResponse.blob()\n\n // 2. 获取文件扩展名\n const ext = src.split('.').pop()?.toLowerCase()?.split('?')[0] || 'jpg'\n const validExt = ['jpg', 'jpeg', 'png', 'gif', 'webp'].includes(ext) ? ext : 'jpg'\n\n // 3. 获取上传签名 (新 API: bizapi.csdn.net)\n const apiPath = '/resource-api/v1/image/direct/upload/signature'\n const headers = await this.signRequest(apiPath, 'POST')\n\n const signatureRes = await this.runtime.fetch(\n `https://bizapi.csdn.net${apiPath}`,\n {\n method: 'POST',\n credentials: 'include',\n headers,\n body: JSON.stringify({\n imageTemplate: '',\n appName: 'direct_blog_markdown',\n imageSuffix: validExt,\n }),\n }\n )\n\n const signatureData = await signatureRes.json() as {\n code: number\n data?: {\n filePath: string\n host: string\n accessId: string\n policy: string\n signature: string\n callbackUrl: string\n callbackBody: string\n callbackBodyType: string\n customParam: {\n rtype: string\n filePath: string\n isAudit: number\n 'x-image-app': string\n type: string\n 'x-image-suffix': string\n username: string\n }\n }\n }\n\n logger.debug('Upload signature response:', signatureData)\n\n if (signatureData.code !== 200 || !signatureData.data) {\n logger.warn('Failed to get upload signature, using original URL')\n return { url: src }\n }\n\n const uploadData = signatureData.data\n const customParam = uploadData.customParam\n\n // 4. 上传到华为云 OBS\n const formData = new FormData()\n formData.append('key', uploadData.filePath)\n formData.append('policy', uploadData.policy)\n formData.append('signature', uploadData.signature)\n formData.append('callbackBody', uploadData.callbackBody)\n formData.append('callbackBodyType', uploadData.callbackBodyType)\n formData.append('callbackUrl', uploadData.callbackUrl)\n formData.append('AccessKeyId', uploadData.accessId)\n formData.append('x:rtype', customParam.rtype)\n formData.append('x:filePath', customParam.filePath)\n formData.append('x:isAudit', String(customParam.isAudit))\n formData.append('x:x-image-app', customParam['x-image-app'])\n formData.append('x:type', customParam.type)\n formData.append('x:x-image-suffix', customParam['x-image-suffix'])\n formData.append('x:username', customParam.username)\n formData.append('file', imageBlob, `image.${validExt}`)\n\n const obsResponse = await this.runtime.fetch(uploadData.host, {\n method: 'POST',\n body: formData,\n })\n\n const obsRes = await obsResponse.json() as {\n code: number\n data?: { imageUrl: string }\n }\n\n logger.debug('OBS upload response:', obsRes)\n\n if (obsRes.code !== 200 || !obsRes.data?.imageUrl) {\n logger.warn('OBS upload failed, using original URL')\n return { url: src }\n }\n\n return {\n url: obsRes.data.imageUrl,\n }\n }\n\n private async resolveCover(article: Article): Promise<{ images: string[]; type: number }> {\n if (!article.cover) {\n return { images: [], type: 0 }\n }\n\n const uploaded = await this.uploadImageByUrl(article.cover)\n return { images: [uploaded.url], type: 1 }\n }\n}\n","/**\n * 51CTO 适配器\n * https://blog.51cto.com\n *\n * 新版图片上传流程:\n * 1. getUploadSign - 获取上传签名\n * 2. getUploadConfig - 获取腾讯云 COS 上传凭证\n * 3. 上传到腾讯云 COS\n */\nimport { CodeAdapter, ImageUploadResult } from '../code-adapter'\nimport type {\n Article,\n AuthResult,\n SyncResult,\n PlatformMeta,\n PublishStatusRef,\n PublishStatusResult,\n} from '../../types'\n\ninterface UploadSignResponse {\n code: number\n msg: string\n data: {\n allows: string\n sizeLimit: number\n sizeLimitMessage: string\n url: string\n sign: string\n }\n}\n\ninterface UploadConfigResponse {\n code: number\n msg: string\n data: {\n url: string\n fields: {\n key: string\n policy: string\n 'x-amz-algorithm': string\n 'x-amz-signature': string\n 'x-amz-credential': string\n 'X-Amz-Date': string\n }\n }\n}\n\ninterface CategoryResponse {\n status: number\n msg?: string\n data?: Array<{\n id: string | number\n item?: Array<{ id: string | number }>\n }>\n}\n\ninterface ManagerListItem {\n blog_id?: string | number\n title?: string\n abstract?: string\n type?: string | number\n is_hide?: string | number\n blog_url?: string\n msg?: string\n reason?: string\n}\n\ninterface ManagerListResponse {\n status: number\n msg?: string\n data?: {\n list?: ManagerListItem[]\n }\n}\n\nexport class Cto51Adapter extends CodeAdapter {\n meta: PlatformMeta = {\n id: '51cto',\n name: '51CTO',\n icon: 'https://blog.51cto.com/favicon.ico',\n homepage: 'https://blog.51cto.com/blogger/publish',\n capabilities: ['article', 'image_upload', 'tags', 'cover'],\n }\n\n /** 预处理配置: 51CTO 使用 Markdown 格式 */\n readonly preprocessConfig = {\n outputFormat: 'markdown' as const,\n }\n\n private csrf: string | null = null\n private userPath: string | null = null\n private category: { pid: string; cateId: string } | null = null\n\n /** 51CTO API 需要的 Header 规则 */\n private readonly HEADER_RULES = [\n {\n urlFilter: '*://blog.51cto.com/*',\n headers: {\n Origin: 'https://blog.51cto.com',\n Referer: 'https://blog.51cto.com/blogger/publish',\n },\n resourceTypes: ['xmlhttprequest'],\n },\n ]\n\n private readonly STATUS_HEADER_RULES = [\n {\n urlFilter: '*://blog.51cto.com/creative-center-ajax/list*',\n headers: {\n Origin: 'https://blog.51cto.com',\n Referer: 'https://blog.51cto.com/creative-center/manager',\n },\n resourceTypes: ['xmlhttprequest'],\n },\n ]\n\n /**\n * 检查登录状态\n */\n async checkAuth(): Promise<AuthResult> {\n try {\n const response = await this.runtime.fetch('https://blog.51cto.com/blogger/publish', {\n credentials: 'include',\n })\n const html = await response.text()\n\n // 解析页面获取用户信息\n const imgMatch = html.match(/<li class=\"more user\">\\s*<a[^>]*href=\"([^\"]+)\"[^>]*>\\s*<img[^>]*src=\"([^\"]+)\"/)\n if (!imgMatch) {\n return { isAuthenticated: false, error: '未登录' }\n }\n\n const userLink = imgMatch[1]\n const avatar = imgMatch[2]\n const userPath = userLink.replace(/^https?:\\/\\/blog\\.51cto\\.com\\//, '').replace(/^\\/+/, '')\n const uid = userPath.split('/').filter(Boolean).pop() || ''\n this.userPath = userPath || uid\n\n // 获取 csrf token\n const csrfMatch = html.match(/<meta\\s+name=\"csrf-token\"\\s+content=\"([^\"]+)\"/)\n if (csrfMatch) {\n this.csrf = csrfMatch[1]\n }\n\n return {\n isAuthenticated: true,\n userId: uid,\n username: uid,\n avatar: avatar,\n }\n } catch (error) {\n return { isAuthenticated: false, error: (error as Error).message }\n }\n }\n\n /**\n * 获取上传签名\n */\n private async getUploadSign(): Promise<UploadSignResponse['data']> {\n const response = await this.runtime.fetch('https://blog.51cto.com/getUploadSign', {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\n 'X-Requested-With': 'XMLHttpRequest',\n 'Referer': 'https://blog.51cto.com/blogger/publish',\n 'Origin': 'https://blog.51cto.com',\n },\n body: 'upload_type=image',\n })\n\n const res: UploadSignResponse = await response.json()\n if (res.code !== 0) {\n throw new Error(res.msg || '获取上传签名失败')\n }\n return res.data\n }\n\n /**\n * 获取上传配置 (腾讯云 COS 凭证)\n */\n private async getUploadConfig(\n uploadSign: string,\n ext: string,\n filename: string\n ): Promise<UploadConfigResponse['data']> {\n const response = await this.runtime.fetch('https://blog.51cto.com/getUploadConfig', {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\n 'X-Requested-With': 'XMLHttpRequest',\n },\n body: new URLSearchParams({\n upload_type: 'image',\n upload_sign: uploadSign,\n ext: ext,\n name: filename,\n }).toString(),\n })\n\n const res: UploadConfigResponse = await response.json()\n if (res.code !== 0) {\n throw new Error(res.msg || '获取上传配置失败')\n }\n return res.data\n }\n\n /**\n * 上传图片到腾讯云 COS\n */\n private async uploadToCOS(\n cosUrl: string,\n fields: UploadConfigResponse['data']['fields'],\n file: File\n ): Promise<string> {\n const formData = new FormData()\n\n // 按顺序添加字段 (顺序很重要)\n formData.append('key', fields.key)\n formData.append('policy', fields.policy)\n formData.append('x-amz-algorithm', fields['x-amz-algorithm'])\n formData.append('x-amz-signature', fields['x-amz-signature'])\n formData.append('x-amz-credential', fields['x-amz-credential'])\n formData.append('X-Amz-Date', fields['X-Amz-Date'])\n formData.append('Content-Type', file.type)\n formData.append('file', file)\n\n const response = await this.runtime.fetch(cosUrl, {\n method: 'POST',\n body: formData,\n })\n\n if (!response.ok) {\n throw new Error(`上传到 COS 失败: ${response.status}`)\n }\n\n // 返回图片 URL (通过 51cto CDN)\n return `https://s2.51cto.com/${fields.key}`\n }\n\n /**\n * 上传图片\n */\n async uploadImageByUrl(url: string): Promise<ImageUploadResult> {\n // 下载图片\n const imageResponse = await this.runtime.fetch(url)\n const blob = await imageResponse.blob()\n\n // 确定文件扩展名和 MIME 类型\n const mimeType = blob.type || 'image/jpeg'\n const ext = mimeType.split('/')[1] || 'jpeg'\n const filename = `${Date.now()}.${ext}`\n const file = new File([blob], filename, { type: mimeType })\n\n // Step 1: 获取上传签名\n const signData = await this.getUploadSign()\n\n // Step 2: 获取上传配置\n const configData = await this.getUploadConfig(signData.sign, mimeType, filename)\n\n // Step 3: 上传到腾讯云 COS\n const imageUrl = await this.uploadToCOS(configData.url, configData.fields, file)\n\n return { url: imageUrl }\n }\n\n /**\n * 发布文章\n */\n async publish(article: Article): Promise<SyncResult> {\n const now = Date.now()\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n // 确保已获取 csrf\n if (!this.csrf) {\n const auth = await this.checkAuth()\n if (!auth.isAuthenticated) {\n throw new Error('未登录')\n }\n }\n\n // 优先使用 markdown,处理图片\n const hasMarkdown = !!article.markdown\n let content = article.markdown || article.html || ''\n content = await this.processImages(content, (src) => this.uploadImageByUrl(src))\n const coverUrls = article.cover ? [(await this.uploadImageByUrl(article.cover)).url] : []\n const category = await this.resolveCategory()\n\n // 构建请求数据\n const postData: Record<string, string> = {\n title: article.title,\n content: content,\n pid: category.pid,\n cate_id: category.cateId,\n custom_id: '0',\n tag: this.resolveTags(article),\n abstract: article.summary || '',\n banner_type: coverUrls.length ? '1' : '0',\n blog_type: '1',\n copy_code: '1',\n is_hide: '0',\n top_time: '0',\n is_comment: '0',\n is_old: hasMarkdown ? '0' : '2',\n blog_id: '',\n did: '',\n work_id: '',\n class_id: '',\n subjectId: '',\n import_type: '-1',\n invite_code: '',\n raffle: '',\n orig: '',\n _csrf: this.csrf || '',\n }\n\n const body = new URLSearchParams(postData)\n for (const url of coverUrls) body.append('img_urls[]', url)\n\n const response = await this.runtime.fetch('https://blog.51cto.com/blogger/publish', {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\n 'X-Requested-With': 'XMLHttpRequest',\n 'Accept': 'application/json, text/javascript, */*; q=0.01',\n },\n body: body.toString(),\n })\n\n const res = await response.json()\n\n if (res.status !== 1 || !res.data) {\n throw new Error(res.msg || '发布失败')\n }\n\n const postId = this.extractPostId(res.data)\n const postUrl = this.extractPostUrl(res.data, postId)\n\n return {\n platform: this.meta.id,\n success: true,\n postId,\n postUrl,\n timestamp: now,\n }\n }).catch((error) => ({\n platform: this.meta.id,\n success: false,\n error: (error as Error).message,\n timestamp: now,\n }))\n }\n\n async getStatus(statusRef: PublishStatusRef): Promise<PublishStatusResult> {\n const articleId = statusRef.id || this.extractPostIdFromUrl(statusRef.url)\n if (!articleId) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: '51CTO statusRef 缺少文章 ID',\n checkedAt: Date.now(),\n }\n }\n\n return this.withHeaderRules(this.STATUS_HEADER_RULES, async () => {\n const item = await this.findManagedArticle(articleId)\n if (!item) {\n return {\n platform: this.meta.id,\n state: 'not_found',\n message: '51CTO 管理列表未找到该文章',\n checkedAt: Date.now(),\n }\n }\n\n return this.mapManagedStatus(item, statusRef)\n })\n }\n\n private extractPostId(data: Record<string, unknown>): string {\n const id = data.blog_id ?? data.id ?? data.article_id ?? data.bid ?? data.did\n if (!id) {\n throw new Error('发布失败: 响应缺少文章 ID')\n }\n return String(id)\n }\n\n private extractPostUrl(data: Record<string, unknown>, postId: string): string {\n const url = data.url ?? data.link\n if (typeof url === 'string' && url) {\n return url.startsWith('http') ? url : `https://blog.51cto.com${url.startsWith('/') ? '' : '/'}${url}`\n }\n return `https://blog.51cto.com/${this.userPath || 'blogger'}/${postId}`\n }\n\n private resolveTags(article: Article): string {\n return article.tags?.map(tag => tag.trim()).filter(Boolean).slice(0, 5).join(',') || ''\n }\n\n private async resolveCategory(): Promise<{ pid: string; cateId: string }> {\n if (this.category) return this.category\n\n const response = await this.runtime.fetch('https://blog.51cto.com/category/get-child', {\n credentials: 'include',\n })\n const res = await response.json() as CategoryResponse\n const parent = res.data?.find(item => item.id)\n const child = parent?.item?.find(item => item.id)\n if (res.status !== 1 || !parent) {\n throw new Error(res.msg || '获取51CTO分类失败')\n }\n\n this.category = {\n pid: String(parent.id),\n cateId: String(child?.id || parent.id),\n }\n return this.category\n }\n\n private async findManagedArticle(articleId: string): Promise<ManagerListItem | null> {\n for (const type of [0, 1, 2, 3, 6]) {\n for (let page = 1; page <= 5; page++) {\n const list = await this.listManagedArticles(type, page)\n const match = list.find(item => String(item.blog_id) === articleId)\n if (match) return { ...match, type: match.type ?? type }\n if (list.length === 0) break\n }\n }\n\n return null\n }\n\n private async listManagedArticles(type: number, page: number): Promise<ManagerListItem[]> {\n const params: Record<string, string | number | boolean> = {\n type,\n blog_type: 0,\n year: '',\n month: '',\n ccid: '',\n flag: false,\n level: '',\n }\n if (page > 1) params.page = page\n\n const response = await this.runtime.fetch('https://blog.51cto.com/creative-center-ajax/list', {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\n 'X-Requested-With': 'XMLHttpRequest',\n Accept: 'application/json, text/javascript, */*; q=0.01',\n },\n body: new URLSearchParams({ data: JSON.stringify(params) }).toString(),\n })\n\n const res = await response.json() as ManagerListResponse\n if (res.status !== 1) {\n throw new Error(res.msg || '51CTO 文章状态查询失败')\n }\n\n return res.data?.list || []\n }\n\n private mapManagedStatus(item: ManagerListItem, statusRef: PublishStatusRef): PublishStatusResult {\n const checkedAt = Date.now()\n const type = String(item.type ?? '')\n\n if (type === '2') {\n return {\n platform: this.meta.id,\n state: 'published',\n postUrl: item.blog_url || statusRef.url,\n message: '51CTO 文章状态: 公开',\n checkedAt,\n }\n }\n\n if (type === '1') {\n return {\n platform: this.meta.id,\n state: 'reviewing',\n message: '51CTO 文章状态: 待审核',\n checkedAt,\n }\n }\n\n if (type === '6') {\n const reason = item.reason || item.msg\n return {\n platform: this.meta.id,\n state: 'rejected',\n message: `51CTO 文章状态: 未通过${reason ? `,原因: ${reason}` : ''}`,\n checkedAt,\n }\n }\n\n if (type === '3' || String(item.is_hide) === '1') {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: '51CTO 文章状态: 私密',\n checkedAt,\n }\n }\n\n return {\n platform: this.meta.id,\n state: 'unknown',\n postUrl: item.blog_url || statusRef.url,\n message: `51CTO 文章状态: ${type || '未知'}`,\n checkedAt,\n }\n }\n\n private extractPostIdFromUrl(url?: string): string | undefined {\n return url?.match(/\\/(\\d+)(?:[/?#]|$)/)?.[1]\n }\n}\n","/**\n * 抖音图文适配器\n *\n * 只复现创作者中心公开前端的 HTTP/API 行为:\n * - 通过创作者中心接口检查登录态\n * - 通过 ImageX 上传图片\n * - 通过 aweme/create_v2 直接发布图文\n *\n * 不点击平台 UI,不逆向私有算法。若平台返回二次验证/风控,直接暴露给用户处理。\n */\nimport { CodeAdapter, type ImageUploadResult } from '../code-adapter'\nimport type { Article, AuthResult, PublishStatusRef, PublishStatusResult, SyncResult, PlatformMeta } from '../../types'\nimport type { PublishOptions } from '../types'\nimport { crc32, signAWS4 } from '../../lib/aws4'\nimport { createLogger } from '../../lib/logger'\n\nconst logger = createLogger('Douyin')\n\nconst CREATOR_ORIGIN = 'https://creator.douyin.com'\nconst IMAGEX_HOST = 'https://imagex.bytedanceapi.com'\nconst IMAGEX_SERVICE_ID = 'jm8ajry58r'\nconst IMAGEX_REGION = 'cn-north-1'\nconst IMAGEX_SERVICE = 'imagex'\nconst DOUYIN_READ_AID = '2906'\nconst MAX_IMAGE_COUNT = 35\nconst MAX_TITLE_LENGTH = 20\nconst MAX_CAPTION_TEXT_LENGTH = 160\n\ninterface DouyinApiResponse<T = unknown> {\n status_code?: number\n code?: number\n err_no?: number\n message?: string\n status_msg?: string\n err_msg?: string\n data?: T\n [key: string]: unknown\n}\n\ninterface DouyinUserData {\n uid?: string | number\n user_id?: string | number\n sec_uid?: string\n nickname?: string\n name?: string\n avatar?: string\n avatar_url?: string\n avatar_thumb?: {\n url_list?: string[]\n }\n user?: DouyinUserData\n user_info?: DouyinUserData\n}\n\ninterface DouyinImageXToken {\n accessKeyId: string\n secretAccessKey: string\n sessionToken: string\n}\n\ninterface DouyinUploadAuthData {\n auth?: string | Record<string, unknown>\n client_ip?: string\n stsToken?: Record<string, unknown>\n token?: Record<string, unknown>\n [key: string]: unknown\n}\n\ninterface ImageXUploadAddress {\n StoreInfos: Array<{\n StoreUri: string\n Auth: string\n UploadID?: string\n }>\n UploadHosts: string[]\n SessionKey: string\n}\n\ninterface ImageXApplyResponse {\n Result?: {\n UploadAddress?: ImageXUploadAddress\n }\n result?: {\n UploadAddress?: ImageXUploadAddress\n }\n}\n\ninterface ImageXCommitResult {\n Results?: Array<{\n Uri?: string\n UriStatus?: number\n }>\n PluginResult?: Array<{\n ImageUri?: string\n ImageWidth?: number\n ImageHeight?: number\n ImageSize?: number\n FileName?: string\n }>\n}\n\ninterface ImageXCommitResponse {\n Result?: ImageXCommitResult\n result?: ImageXCommitResult\n}\n\ninterface UploadedDouyinImage {\n uri: string\n url: string\n width: number\n height: number\n}\n\ninterface PublishResponseData {\n item_id?: string | number\n aweme_id?: string | number\n id?: string | number\n}\n\ninterface DouyinItemStatusData {\n id?: string | number\n item_id?: string | number\n aweme_id?: string | number\n review_status?: string | number\n reviewStatus?: string | number\n status?: string | number\n item_status?: string | number\n itemStatus?: string | number\n audit_status?: string | number\n auditStatus?: string | number\n review?: {\n status?: string | number\n }\n visibility?: string | number\n status_msg?: string\n status_message?: string\n message?: string\n reason?: string\n reject_reason?: string\n audit_msg?: string\n share_url?: string\n url?: string\n [key: string]: unknown\n}\n\ninterface DouyinItemDetailResponse extends DouyinApiResponse<DouyinItemStatusData> {\n BaseResp?: {\n StatusCode?: number\n StatusMessage?: string\n }\n id?: string | number\n item_id?: string | number\n aweme_id?: string | number\n review_status?: string | number\n status?: string | number\n item_status?: string | number\n item?: DouyinItemStatusData\n}\n\ninterface DouyinItemMgetResponse extends DouyinApiResponse {\n items?: DouyinItemStatusData[]\n}\n\ninterface TextPayload {\n title: string\n text: string\n textExtra: Array<Record<string, unknown>>\n bodyText: string\n}\n\nexport class DouyinAdapter extends CodeAdapter {\n readonly meta: PlatformMeta = {\n id: 'douyin',\n name: '抖音图文',\n icon: 'https://www.douyin.com/favicon.ico',\n homepage: `${CREATOR_ORIGIN}/creator-micro/content/upload?default-tab=3`,\n capabilities: ['article', 'image_upload'],\n }\n\n readonly preprocessConfig = {\n outputFormat: 'html' as const,\n removeLinks: true,\n removeIframes: true,\n removeComments: true,\n processLazyImages: true,\n convertTablesToText: true,\n }\n\n private userInfo: DouyinUserData | null = null\n private cachedImageXToken: DouyinImageXToken | null = null\n\n private readonly HEADER_RULES = [\n {\n urlFilter: '*://creator.douyin.com/*',\n headers: {\n Origin: CREATOR_ORIGIN,\n Referer: `${CREATOR_ORIGIN}/creator-micro/content/upload?default-tab=3`,\n },\n resourceTypes: ['xmlhttprequest'],\n },\n {\n urlFilter: '*://imagex.bytedanceapi.com/*',\n headers: {\n Origin: CREATOR_ORIGIN,\n Referer: `${CREATOR_ORIGIN}/creator-micro/content/upload?default-tab=3`,\n },\n resourceTypes: ['xmlhttprequest'],\n },\n ]\n\n async checkAuth(): Promise<AuthResult> {\n const endpoints = [\n `${CREATOR_ORIGIN}/web/api/media/user/info/`,\n `${CREATOR_ORIGIN}/aweme/v1/creator/user/info/`,\n `${CREATOR_ORIGIN}/aweme/v1/creator/pc/user/info/`,\n ]\n\n for (const endpoint of endpoints) {\n try {\n const res = await this.get<DouyinApiResponse<DouyinUserData>>(endpoint)\n const user = this.extractUserData(res)\n if (this.isSuccessResponse(res) && user) {\n this.userInfo = user\n return {\n isAuthenticated: true,\n userId: this.stringifyId(user.uid ?? user.user_id ?? user.sec_uid),\n username: user.nickname || user.name,\n avatar: user.avatar || user.avatar_url || user.avatar_thumb?.url_list?.[0],\n }\n }\n } catch (error) {\n logger.debug(`checkAuth failed for ${endpoint}:`, error)\n }\n }\n\n return { isAuthenticated: false }\n }\n\n async publish(article: Article, options?: PublishOptions): Promise<SyncResult> {\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n logger.info('Starting publish...')\n\n if (!this.userInfo) {\n const auth = await this.checkAuth()\n if (!auth.isAuthenticated) {\n throw new Error('请先登录抖音创作者中心')\n }\n }\n\n const imageUrls = await this.renderMarkdownImageUrls(article)\n if (imageUrls.length === 0) {\n throw new Error('抖音图文发布至少需要一张 Markdown 渲染图片')\n }\n\n const images: UploadedDouyinImage[] = []\n for (const src of imageUrls) {\n options?.onImageProgress?.(images.length + 1, imageUrls.length)\n images.push(await this.uploadDouyinImageByUrl(src))\n }\n\n const textPayload = this.buildTextPayload(article)\n const item = this.buildPublishItem(images, textPayload)\n const publishUrl = `${CREATOR_ORIGIN}/web/api/media/aweme/create_v2/?read_aid=${DOUYIN_READ_AID}`\n const response = await this.postCreatorJson<DouyinApiResponse<PublishResponseData>>(\n publishUrl,\n { item },\n { preferPageContext: true },\n )\n\n this.assertPublishSuccess(response)\n\n const postId = this.stringifyId(\n response.data?.item_id ??\n response.data?.aweme_id ??\n response.data?.id ??\n response.item_id ??\n response.aweme_id ??\n response.id,\n )\n\n return this.createResult(true, {\n postId,\n postUrl: postId\n ? `https://www.douyin.com/note/${encodeURIComponent(postId)}`\n : `${CREATOR_ORIGIN}/creator-micro/content/manage`,\n statusData: {\n userId: this.stringifyId(this.userInfo?.uid ?? this.userInfo?.user_id) ?? null,\n },\n })\n }).catch((error) => this.createResult(false, {\n error: (error as Error).message,\n }))\n }\n\n async uploadImage(file: Blob, _filename?: string): Promise<string> {\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n const uploaded = await this.uploadDouyinImage(file)\n return uploaded.url\n })\n }\n\n async getStatus(statusRef: PublishStatusRef): Promise<PublishStatusResult> {\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n const id = this.resolveStatusId(statusRef)\n if (!id) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: 'statusRef does not include a Douyin item id',\n checkedAt: Date.now(),\n }\n }\n\n const userId = this.getStatusUserId(statusRef) || await this.resolveCurrentUserId()\n const detail = await this.fetchItemDetail(id, userId)\n if (detail.error) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: detail.error,\n checkedAt: Date.now(),\n }\n }\n\n let item = detail.item\n if (!item) {\n const mget = await this.fetchItemMget(id, userId)\n if (mget.error) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: mget.error,\n checkedAt: Date.now(),\n }\n }\n item = mget.item\n }\n\n if (!item) {\n return {\n platform: this.meta.id,\n state: 'not_found',\n message: '抖音创作者中心未找到该图文',\n checkedAt: Date.now(),\n }\n }\n\n return this.mapDouyinItemStatus(item, statusRef, id)\n })\n }\n\n private resolveStatusId(statusRef: PublishStatusRef): string {\n const directId = this.stringifyId(statusRef.id)\n if (directId) return directId\n\n const url = statusRef.url || ''\n const match = url.match(/\\/(?:note|video)\\/([^/?#]+)/)\n return match?.[1] ? decodeURIComponent(match[1]) : ''\n }\n\n private getStatusUserId(statusRef: PublishStatusRef): string {\n return this.stringifyId(statusRef.data?.userId || statusRef.data?.uid) || ''\n }\n\n private async resolveCurrentUserId(): Promise<string> {\n if (this.userInfo) {\n return this.stringifyId(this.userInfo.uid ?? this.userInfo.user_id) || ''\n }\n\n try {\n const auth = await this.checkAuth()\n return auth.isAuthenticated ? (auth.userId || '') : ''\n } catch (error) {\n logger.debug('Douyin status auth probe failed:', error)\n return ''\n }\n }\n\n private async fetchItemDetail(\n id: string,\n userId: string,\n ): Promise<{ item?: DouyinItemStatusData; error?: string }> {\n const url = new URL(`${CREATOR_ORIGIN}/web/api/creator/item/${encodeURIComponent(id)}`)\n url.searchParams.set('fields', this.getStatusFields())\n url.searchParams.set('app_id', DOUYIN_READ_AID)\n if (userId) url.searchParams.set('user_id', userId)\n\n try {\n const response = await this.get<DouyinItemDetailResponse>(url.toString(), {\n Accept: 'application/json, text/plain, */*',\n })\n return this.extractDetailStatusItem(response)\n } catch (error) {\n return { error: this.formatStatusError(error) }\n }\n }\n\n private async fetchItemMget(\n id: string,\n userId: string,\n ): Promise<{ item?: DouyinItemStatusData; error?: string }> {\n const url = new URL(`${CREATOR_ORIGIN}/web/api/creator/item/mget`)\n url.searchParams.set('ids', id)\n url.searchParams.set('fields', this.getStatusFields())\n if (userId) url.searchParams.set('UserID', userId)\n\n try {\n const response = await this.get<DouyinItemMgetResponse>(url.toString(), {\n Accept: 'application/json, text/plain, */*',\n })\n return this.extractMgetStatusItem(response, id)\n } catch (error) {\n return { error: this.formatStatusError(error) }\n }\n }\n\n private extractDetailStatusItem(\n response: DouyinItemDetailResponse,\n ): { item?: DouyinItemStatusData; error?: string } {\n const apiError = this.readApiError(response)\n if (apiError) return { error: apiError }\n\n const dataItem = this.toStatusItem(response.data)\n if (dataItem) return { item: dataItem }\n\n const nestedItem = this.toStatusItem(response.item)\n if (nestedItem) return { item: nestedItem }\n\n return { item: this.toStatusItem(response) }\n }\n\n private extractMgetStatusItem(\n response: DouyinItemMgetResponse,\n id: string,\n ): { item?: DouyinItemStatusData; error?: string } {\n const apiError = this.readApiError(response)\n if (apiError) return { error: apiError }\n\n const data = response.data\n const dataItems = data && typeof data === 'object' && Array.isArray((data as { items?: unknown }).items)\n ? (data as { items: DouyinItemStatusData[] }).items\n : undefined\n const items = response.items || dataItems || []\n const item = items.find((candidate) => {\n const candidateId = this.stringifyId(candidate.id ?? candidate.item_id ?? candidate.aweme_id)\n return candidateId === id\n }) || items[0]\n\n return { item: this.toStatusItem(item) }\n }\n\n private toStatusItem(value: unknown): DouyinItemStatusData | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined\n const record = value as DouyinItemStatusData\n const hasIdentity = this.stringifyId(record.id ?? record.item_id ?? record.aweme_id)\n const hasStatus = this.readStatusValue(record) !== undefined\n return hasIdentity || hasStatus ? record : undefined\n }\n\n private readApiError(response: DouyinApiResponse): string {\n const baseResp = (response as DouyinItemDetailResponse).BaseResp\n const code = response.status_code ?? response.code ?? response.err_no ?? baseResp?.StatusCode\n if (code === undefined || code === 0) return ''\n return response.message || response.status_msg || response.err_msg || baseResp?.StatusMessage || `抖音状态接口返回错误: ${code}`\n }\n\n private mapDouyinItemStatus(\n item: DouyinItemStatusData,\n statusRef: PublishStatusRef,\n id: string,\n ): PublishStatusResult {\n const value = this.readStatusValue(item)\n const reason = this.readStatusReason(item)\n const postUrl = this.resolveDouyinPublicUrl(item, statusRef, id)\n const checkedAt = Date.now()\n\n if (this.isRejectedStatus(value)) {\n return {\n platform: this.meta.id,\n state: 'rejected',\n message: reason ? `抖音图文状态: 未通过,原因: ${reason}` : '抖音图文状态: 未通过',\n postUrl,\n checkedAt,\n }\n }\n\n if (this.isReviewingStatus(value)) {\n return {\n platform: this.meta.id,\n state: 'reviewing',\n message: '抖音图文状态: 审核中',\n postUrl,\n checkedAt,\n }\n }\n\n if (this.isPublishedStatus(value)) {\n return {\n platform: this.meta.id,\n state: 'published',\n message: '抖音图文状态: 已发布',\n postUrl,\n checkedAt,\n }\n }\n\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: reason ? `抖音图文状态未知: ${reason}` : '抖音图文状态未知',\n postUrl,\n checkedAt,\n }\n }\n\n private readStatusValue(item: DouyinItemStatusData): string | number | undefined {\n return item.review_status ??\n item.reviewStatus ??\n item.audit_status ??\n item.auditStatus ??\n item.item_status ??\n item.itemStatus ??\n item.review?.status ??\n item.status ??\n item.visibility\n }\n\n private readStatusReason(item: DouyinItemStatusData): string {\n return [\n item.reject_reason,\n item.reason,\n item.audit_msg,\n item.status_message,\n item.status_msg,\n item.message,\n ].find((value): value is string => typeof value === 'string' && value.trim().length > 0)?.trim() || ''\n }\n\n private isPublishedStatus(value: unknown): boolean {\n const normalized = this.normalizeStatusValue(value)\n if ([2, 102, 140, 143].includes(normalized.numberValue ?? Number.NaN)) return true\n return /^(pass|available|selfavailable|friendsavailable|published|online|success)$/i.test(normalized.text)\n }\n\n private isReviewingStatus(value: unknown): boolean {\n const normalized = this.normalizeStatusValue(value)\n if ([1, 3, 5, 6, 141, 144].includes(normalized.numberValue ?? Number.NaN)) return true\n return /(inprocess|wait|reviewing|waitreview|review_advice|review_friend_see|audit|processing)/i.test(normalized.text)\n }\n\n private isRejectedStatus(value: unknown): boolean {\n const normalized = this.normalizeStatusValue(value)\n if ([4, 22].includes(normalized.numberValue ?? Number.NaN)) return true\n return /(reject|delete|ban|abnormal|not[_-]?pass|failed|violation)/i.test(normalized.text)\n }\n\n private normalizeStatusValue(value: unknown): { text: string; numberValue?: number } {\n const text = value === undefined || value === null ? '' : String(value).replace(/\\s+/g, '')\n const numberValue = text && /^-?\\d+$/.test(text) ? Number(text) : undefined\n return { text, numberValue }\n }\n\n private resolveDouyinPublicUrl(\n item: DouyinItemStatusData,\n statusRef: PublishStatusRef,\n id: string,\n ): string {\n const candidate = [item.share_url, item.url, statusRef.url].find((value) =>\n typeof value === 'string' && /^https:\\/\\/www\\.douyin\\.com\\/(?:note|video)\\//.test(value)\n )\n return candidate || `https://www.douyin.com/note/${encodeURIComponent(id)}`\n }\n\n private getStatusFields(): string {\n return [\n 'review_status',\n 'review',\n 'status',\n 'item_status',\n 'visibility',\n 'aweme_id',\n 'item_id',\n 'id',\n 'reason',\n 'reject_reason',\n 'audit_msg',\n 'status_msg',\n 'share_url',\n 'url',\n ].join(',')\n }\n\n private formatStatusError(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n }\n\n protected async uploadImageByUrl(src: string): Promise<ImageUploadResult> {\n const uploaded = await this.uploadDouyinImageByUrl(src)\n return {\n url: uploaded.url,\n attrs: {\n 'data-douyin-uri': uploaded.uri,\n width: uploaded.width,\n height: uploaded.height,\n },\n }\n }\n\n private async postCreatorJson<T>(\n url: string,\n body: Record<string, unknown>,\n options?: { preferPageContext?: boolean },\n ): Promise<T> {\n if (options?.preferPageContext) {\n const pageResult = await this.postCreatorJsonFromPage<T>(url, body)\n if (pageResult) return pageResult\n }\n\n const response = await this.runtime.fetch(url, {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json, text/plain, */*',\n },\n body: JSON.stringify(body),\n })\n\n const text = await response.text()\n if (!response.ok) {\n if (this.looksLikeSecondVerify(text) || response.status === 401 || response.status === 403) {\n throw new Error('抖音要求二次验证,请在创作者中心完成安全验证后重试')\n }\n throw new Error(`抖音接口请求失败: HTTP ${response.status} ${text.slice(0, 200)}`)\n }\n\n return this.parseJsonText<T>(text)\n }\n\n private async postCreatorJsonFromPage<T>(\n url: string,\n body: Record<string, unknown>,\n ): Promise<T | null> {\n if (!this.runtime.tabs?.query || !this.runtime.tabs?.executeScript) {\n return null\n }\n\n const tabId = await this.getCreatorTabId()\n if (!tabId) {\n return null\n }\n\n try {\n const result = await this.runtime.tabs.executeScript<{\n ok: boolean\n status: number\n statusText: string\n text: string\n }, [string, Record<string, unknown>]>(\n tabId,\n async (requestUrl, requestBody) => {\n const response = await fetch(requestUrl, {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json, text/plain, */*',\n },\n body: JSON.stringify(requestBody),\n })\n return {\n ok: response.ok,\n status: response.status,\n statusText: response.statusText,\n text: await response.text(),\n }\n },\n [url, body],\n )\n\n if (!result.ok) {\n if (this.looksLikeSecondVerify(result.text) || result.status === 401 || result.status === 403) {\n throw new Error('抖音要求二次验证,请在创作者中心完成安全验证后重试')\n }\n throw new Error(`抖音页面上下文请求失败: HTTP ${result.status} ${result.text.slice(0, 200)}`)\n }\n\n return this.parseJsonText<T>(result.text)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n if (this.looksLikeSecondVerify(message)) {\n throw error\n }\n logger.debug('Creator page request failed, falling back to extension fetch:', error)\n return null\n }\n }\n\n private async getCreatorTabId(): Promise<number | null> {\n const existingTabs = await this.runtime.tabs?.query('*://creator.douyin.com/*')\n const existingTab = existingTabs?.find(tab => typeof tab.id === 'number')\n if (existingTab?.id) {\n return existingTab.id\n }\n\n if (!this.runtime.tabs?.create) {\n return null\n }\n\n const tab = await this.runtime.tabs.create(`${CREATOR_ORIGIN}/creator-micro/home`, false)\n if (this.runtime.tabs.waitForLoad) {\n await this.runtime.tabs.waitForLoad(tab.id, 30000).catch((error) => {\n logger.debug('Creator tab load wait failed:', error)\n })\n }\n return tab.id\n }\n\n private extractUserData(response: DouyinApiResponse<DouyinUserData>): DouyinUserData | null {\n const data = response.data || (response as unknown as DouyinUserData)\n return data.user || data.user_info || data || null\n }\n\n private isSuccessResponse(response: DouyinApiResponse): boolean {\n const code = response.status_code ?? response.code ?? response.err_no\n return code === undefined || code === 0\n }\n\n private async renderMarkdownImageUrls(article: Article): Promise<string[]> {\n if (!this.runtime.renderMarkdownToImages) {\n throw new Error('当前运行时不支持 Markdown 转图文,请在浏览器扩展环境中发布')\n }\n\n const markdown = article.markdown?.trim()\n if (!markdown) {\n throw new Error('抖音图文发布需要 Markdown 内容用于生成图片')\n }\n\n const images = await this.runtime.renderMarkdownToImages(markdown, {\n title: article.title,\n theme: 'clean',\n width: 1080,\n height: 1440,\n scale: 1,\n maxPages: MAX_IMAGE_COUNT,\n })\n\n return images\n .sort((a, b) => a.index - b.index)\n .map((image) => image.src)\n .filter((src) => src.trim())\n }\n\n private buildTextPayload(article: Article): TextPayload {\n const title = this.limitText(article.title.trim(), MAX_TITLE_LENGTH)\n const bodyText = this.extractCaptionText(article)\n const divider = title && !title.endsWith('。') ? '。' : ''\n const text = `${title}${divider}${bodyText ? `\\n${bodyText}` : ''}`.trim()\n const textExtra: Array<Record<string, unknown>> = []\n\n if (title) {\n textExtra.push({\n start: 0,\n end: title.length,\n hashtag_id: 0,\n hashtag_name: '',\n type: 7,\n })\n if (divider) {\n textExtra.push({\n start: title.length,\n end: title.length + divider.length,\n hashtag_id: 0,\n hashtag_name: '',\n type: 8,\n })\n }\n }\n\n if (!text) {\n throw new Error('抖音图文发布需要标题或正文')\n }\n\n return { title, text, textExtra, bodyText }\n }\n\n private extractBodyText(article: Article): string {\n return this.normalizeText(\n article.markdown\n .replace(/!\\[[^\\]]*]\\([^)]+\\)/g, '')\n .replace(/\\[([^\\]]+)]\\([^)]+\\)/g, '$1')\n .replace(/^#{1,6}\\s+/gm, '')\n .replace(/[*_`>#-]/g, ' '),\n )\n }\n\n private extractCaptionText(article: Article): string {\n const summary = article.summary?.trim()\n const source = summary || this.extractBodyText(article)\n return this.normalizeText(source)\n .replace(/\\n+/g, ' ')\n .slice(0, MAX_CAPTION_TEXT_LENGTH)\n .trim()\n }\n\n private normalizeText(value: string): string {\n return this.decodeHtmlEntities(value)\n .replace(/\\r/g, '')\n .replace(/[ \\t]+/g, ' ')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim()\n }\n\n private limitText(value: string, maxLength: number): string {\n return Array.from(value).slice(0, maxLength).join('').trim()\n }\n\n private buildPublishItem(\n images: UploadedDouyinImage[],\n textPayload: TextPayload,\n ): Record<string, unknown> {\n return {\n common: {\n media_type: 2,\n images: images.map((image) => ({\n uri: image.uri,\n width: image.width,\n height: image.height,\n })),\n text: textPayload.text,\n text_extra: JSON.stringify(textPayload.textExtra),\n activity: '[]',\n challenges: '[]',\n mentions: '[]',\n hashtag_source: '',\n item_title: textPayload.title,\n caption: textPayload.bodyText,\n title_permission: 1,\n download: 1,\n visibility_type: 0,\n is_new_update: 1,\n },\n cover: {\n poster: images[0].uri,\n },\n }\n }\n\n private async uploadDouyinImageByUrl(src: string): Promise<UploadedDouyinImage> {\n const blob = await this.loadImageBlob(src)\n return this.uploadDouyinImage(blob)\n }\n\n private async loadImageBlob(src: string): Promise<Blob> {\n if (src.startsWith('data:')) {\n return fetch(src).then((res) => res.blob())\n }\n\n const response = await this.runtime.fetch(src, {\n method: 'GET',\n credentials: 'include',\n })\n if (!response.ok) {\n throw new Error(`下载抖音图文图片失败: HTTP ${response.status}`)\n }\n return response.blob()\n }\n\n private async uploadDouyinImage(file: Blob): Promise<UploadedDouyinImage> {\n const token = await this.getImageXToken()\n const size = await this.detectImageSize(file)\n const uploadAddress = await this.applyImageUpload(token)\n await this.uploadToTOS(uploadAddress, file)\n const commitResult = await this.commitImageUpload(token, uploadAddress.SessionKey)\n\n const pluginResult = commitResult.PluginResult?.[0]\n const committedUri = pluginResult?.ImageUri || commitResult.Results?.[0]?.Uri\n const storeUri = uploadAddress.StoreInfos[0]?.StoreUri\n const uri = committedUri || storeUri\n\n if (!uri) {\n throw new Error('抖音 ImageX 上传失败: 未返回图片 URI')\n }\n\n return {\n uri,\n url: uri,\n width: pluginResult?.ImageWidth || size.width || 0,\n height: pluginResult?.ImageHeight || size.height || 0,\n }\n }\n\n private async getImageXToken(): Promise<DouyinImageXToken> {\n if (this.cachedImageXToken) {\n return this.cachedImageXToken\n }\n\n const response = await this.get<DouyinApiResponse<DouyinUploadAuthData>>(\n `${CREATOR_ORIGIN}/web/api/media/upload/auth/v5/`,\n )\n\n if (!this.isSuccessResponse(response)) {\n throw new Error(response.message || response.status_msg || response.err_msg || '获取抖音图片上传凭证失败')\n }\n\n const data = (response.data || response) as DouyinUploadAuthData\n const rawToken = data.auth ?? data.stsToken ?? data.token\n const tokenSource = typeof rawToken === 'string'\n ? this.parseJsonText<Record<string, unknown>>(rawToken)\n : rawToken\n\n const accessKeyId = this.pickString(tokenSource, [\n 'AccessKeyId',\n 'AccessKeyID',\n 'accessKeyId',\n 'access_key_id',\n ])\n const secretAccessKey = this.pickString(tokenSource, [\n 'SecretAccessKey',\n 'secretAccessKey',\n 'secret_access_key',\n ])\n const sessionToken = this.pickString(tokenSource, [\n 'SessionToken',\n 'sessionToken',\n 'session_token',\n ])\n\n if (!accessKeyId || !secretAccessKey || !sessionToken) {\n throw new Error('抖音图片上传凭证格式不正确')\n }\n\n this.cachedImageXToken = { accessKeyId, secretAccessKey, sessionToken }\n return this.cachedImageXToken\n }\n\n private async applyImageUpload(token: DouyinImageXToken): Promise<ImageXUploadAddress> {\n const url = `${IMAGEX_HOST}/?Action=ApplyImageUpload&Version=2018-08-01&ServiceId=${IMAGEX_SERVICE_ID}`\n const signResult = await signAWS4({\n method: 'GET',\n url,\n accessKeyId: token.accessKeyId,\n secretAccessKey: token.secretAccessKey,\n securityToken: token.sessionToken,\n region: IMAGEX_REGION,\n service: IMAGEX_SERVICE,\n })\n\n const response = await this.runtime.fetch(url, {\n method: 'GET',\n headers: signResult.headers,\n })\n const data = await response.json() as ImageXApplyResponse\n const uploadAddress = data.Result?.UploadAddress || data.result?.UploadAddress\n\n if (!uploadAddress?.StoreInfos?.[0] || !uploadAddress.UploadHosts?.[0] || !uploadAddress.SessionKey) {\n throw new Error('抖音 ImageX 申请上传地址失败')\n }\n\n return uploadAddress\n }\n\n private async uploadToTOS(uploadAddress: ImageXUploadAddress, file: Blob): Promise<void> {\n const storeInfo = uploadAddress.StoreInfos[0]\n const uploadHost = uploadAddress.UploadHosts[0]\n const uploadUrl = `https://${uploadHost}/${storeInfo.StoreUri}`\n const bytes = new Uint8Array(await file.arrayBuffer())\n\n const response = await this.runtime.fetch(uploadUrl, {\n method: 'PUT',\n headers: {\n Authorization: storeInfo.Auth,\n 'Content-Type': file.type || 'application/octet-stream',\n 'Content-CRC32': crc32(bytes),\n },\n body: file,\n })\n\n if (!response.ok) {\n throw new Error(`抖音 ImageX 上传文件失败: HTTP ${response.status} ${await response.text()}`)\n }\n }\n\n private async commitImageUpload(\n token: DouyinImageXToken,\n sessionKey: string,\n ): Promise<ImageXCommitResult> {\n const url = `${IMAGEX_HOST}/?Action=CommitImageUpload&Version=2018-08-01&ServiceId=${IMAGEX_SERVICE_ID}`\n const body = JSON.stringify({ SessionKey: sessionKey })\n const signResult = await signAWS4({\n method: 'POST',\n url,\n accessKeyId: token.accessKeyId,\n secretAccessKey: token.secretAccessKey,\n securityToken: token.sessionToken,\n region: IMAGEX_REGION,\n service: IMAGEX_SERVICE,\n headers: {\n 'content-type': 'application/json',\n },\n body,\n })\n\n const response = await this.runtime.fetch(url, {\n method: 'POST',\n headers: {\n ...signResult.headers,\n 'Content-Type': 'application/json',\n },\n body,\n })\n\n const data = await response.json() as ImageXCommitResponse\n const result = data.Result || data.result\n if (!result) {\n throw new Error('抖音 ImageX 提交上传失败')\n }\n return result\n }\n\n private assertPublishSuccess(response: DouyinApiResponse<PublishResponseData>): void {\n const responseText = JSON.stringify(response)\n if (this.looksLikeSecondVerify(responseText)) {\n throw new Error('抖音要求二次验证,请在创作者中心完成安全验证后重试')\n }\n\n const code = response.status_code ?? response.code ?? response.err_no\n if (code !== undefined && code !== 0) {\n throw new Error(\n response.message ||\n response.status_msg ||\n response.err_msg ||\n `抖音图文发布失败: ${code}`,\n )\n }\n }\n\n private looksLikeSecondVerify(value: string): boolean {\n return /captcha|verify|second|risk|security|secsdk|postPc|安全验证|风险|风控|验证码/i.test(value)\n }\n\n private async detectImageSize(blob: Blob): Promise<{ width: number; height: number }> {\n const bytes = new Uint8Array(await blob.arrayBuffer())\n\n if (bytes.length >= 24 && bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4e && bytes[3] === 0x47) {\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)\n return {\n width: view.getUint32(16),\n height: view.getUint32(20),\n }\n }\n\n for (let i = 2; i + 9 < bytes.length;) {\n if (bytes[i] !== 0xff) break\n const marker = bytes[i + 1]\n const length = (bytes[i + 2] << 8) + bytes[i + 3]\n if (marker >= 0xc0 && marker <= 0xc3) {\n return {\n height: (bytes[i + 5] << 8) + bytes[i + 6],\n width: (bytes[i + 7] << 8) + bytes[i + 8],\n }\n }\n i += 2 + length\n }\n\n return { width: 0, height: 0 }\n }\n\n private parseJsonText<T>(text: string): T {\n try {\n return JSON.parse(text) as T\n } catch {\n throw new Error(`抖音接口返回不是有效 JSON: ${text.slice(0, 200)}`)\n }\n }\n\n private pickString(source: unknown, keys: string[]): string {\n if (!source || typeof source !== 'object') return ''\n const record = source as Record<string, unknown>\n for (const key of keys) {\n const value = record[key]\n if (typeof value === 'string' && value) return value\n }\n return ''\n }\n\n private stringifyId(value: unknown): string | undefined {\n if (value === undefined || value === null || value === '') return undefined\n return String(value)\n }\n\n private decodeHtmlEntities(value: string): string {\n return value\n .replace(/&/g, '&')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/</g, '<')\n .replace(/>/g, '>')\n }\n}\n","/**\n * 掘金适配器\n */\nimport { CodeAdapter, type ImageUploadResult } from '../code-adapter'\nimport type {\n Article,\n AuthResult,\n PlatformMeta,\n PublishStatusRef,\n PublishStatusResult,\n SyncResult,\n} from '../../types'\nimport type { PublishOptions } from '../types'\nimport { crc32, signAWS4 } from '../../lib/aws4'\nimport { createLogger } from '../../lib/logger'\n\nconst logger = createLogger('Juejin')\n\n// ImageX 服务常量\nconst IMAGEX_AID = '2608'\nconst IMAGEX_SERVICE_ID = '73owjymdk6'\n\n// 生成 UUID (用于 ImageX API)\nfunction generateUUID(): string {\n return 'xxxxxxxxxxxxxxxx'.replace(/x/g, () =>\n Math.floor(Math.random() * 16).toString(16)\n ) + Date.now().toString()\n}\n\n// ImageX Token 响应类型\ninterface ImageXTokenResponse {\n data?: {\n token: {\n AccessKeyId: string\n SecretAccessKey: string\n SessionToken: string\n ExpiredTime: string // ISO 日期字符串 \"2026-01-14T00:15:24+08:00\"\n CurrentTime: string\n }\n }\n err_no?: number\n err_msg?: string\n}\n\n// 解析后的 Token\ninterface ImageXToken {\n AccessKeyId: string\n SecretAccessKey: string\n SessionToken: string\n ExpiredTime: number // Unix 时间戳(毫秒)\n}\n\n// ImageX ApplyUpload 响应类型\ninterface ImageXApplyUploadResponse {\n ResponseMetadata: {\n RequestId: string\n Action: string\n Version: string\n Service: string\n Region: string\n }\n Result: {\n RequestId: string\n UploadAddress: {\n StoreInfos: Array<{\n StoreUri: string\n Auth: string\n UploadID: string\n }>\n UploadHosts: string[]\n SessionKey: string\n }\n }\n}\n\n// ImageX CommitUpload 响应类型\ninterface ImageXCommitUploadResponse {\n ResponseMetadata: {\n RequestId: string\n Action: string\n Version: string\n Service: string\n Region: string\n }\n Result: {\n RequestId: string\n Results: Array<{\n Uri: string\n UriStatus: number\n }>\n PluginResult: Array<{\n FileName: string\n ImageUri: string\n ImageWidth: number\n ImageHeight: number\n ImageMd5: string\n ImageFormat: string\n ImageSize: number\n }>\n }\n}\n\ninterface JuejinCategory {\n category_id: string\n category_name: string\n category_url?: string\n}\n\ninterface JuejinTag {\n tag_id: string\n tag_name: string\n}\n\ninterface JuejinArticleDetailResponse {\n err_no?: number\n err_msg?: string\n data?: {\n article_info?: {\n status?: number\n audit_status?: number\n verify_status?: number\n }\n } | null\n}\n\nexport class JuejinAdapter extends CodeAdapter {\n readonly meta: PlatformMeta = {\n id: 'juejin',\n name: '掘金',\n icon: 'https://lf-web-assets.juejin.cn/obj/juejin-web/xitu_juejin_web/static/favicons/favicon-32x32.png',\n homepage: 'https://juejin.cn',\n capabilities: ['article', 'image_upload', 'categories', 'tags', 'cover'],\n }\n\n /** 预处理配置: 掘金使用 Markdown 格式 */\n readonly preprocessConfig = {\n outputFormat: 'markdown' as const,\n }\n\n private cachedCsrfToken: string | null = null\n private cachedImageXToken: ImageXToken | null = null\n private imageXTokenExpiry: number = 0\n private uuid: string = generateUUID()\n\n /** 掘金 API 需要的 Header 规则 */\n private readonly HEADER_RULES = [\n {\n urlFilter: '*://api.juejin.cn/*',\n headers: {\n 'Origin': 'https://juejin.cn',\n 'Referer': 'https://juejin.cn/',\n },\n resourceTypes: ['xmlhttprequest'],\n },\n {\n urlFilter: '*://imagex.bytedanceapi.com/*',\n headers: {\n 'Origin': 'https://juejin.cn',\n 'Referer': 'https://juejin.cn/',\n },\n resourceTypes: ['xmlhttprequest'],\n },\n ]\n\n async checkAuth(): Promise<AuthResult> {\n try {\n const response = await this.runtime.fetch('https://api.juejin.cn/user_api/v1/user/get', {\n method: 'GET',\n credentials: 'include',\n })\n\n const data = await response.json() as {\n data?: {\n user_id?: string\n user_name?: string\n avatar_large?: string\n }\n }\n\n if (data.data?.user_id) {\n return {\n isAuthenticated: true,\n userId: data.data.user_id,\n username: data.data.user_name,\n avatar: data.data.avatar_large,\n }\n }\n\n return { isAuthenticated: false }\n } catch (error) {\n logger.debug('checkAuth: not logged in -', error)\n return { isAuthenticated: false, error: (error as Error).message }\n }\n }\n\n /**\n * 获取 CSRF Token (参考 DSL juejin.transform.ts)\n */\n private async getCsrfToken(): Promise<string> {\n if (this.cachedCsrfToken) {\n return this.cachedCsrfToken\n }\n\n // 使用 runtime.fetch 以便 extension 能正确处理\n const response = await this.runtime.fetch('https://api.juejin.cn/user_api/v1/sys/token', {\n method: 'HEAD',\n headers: {\n 'x-secsdk-csrf-request': '1',\n 'x-secsdk-csrf-version': '1.2.10',\n },\n credentials: 'include',\n })\n\n const wareToken = response.headers.get('x-ware-csrf-token')\n if (!wareToken) {\n logger.warn('CSRF token not found in response headers')\n throw new Error('Failed to get CSRF token')\n }\n\n // Token 格式: \"0,{actual_token},86370000,success,{session_id}\"\n const parts = wareToken.split(',')\n if (parts.length < 2) {\n throw new Error('Invalid CSRF token format')\n }\n\n this.cachedCsrfToken = parts[1]\n logger.debug('Got CSRF token:', this.cachedCsrfToken.substring(0, 10) + '...')\n return this.cachedCsrfToken\n }\n\n async publish(article: Article, options?: PublishOptions): Promise<SyncResult> {\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n logger.info('Starting publish...')\n\n // 1. 获取 CSRF token\n const csrfToken = await this.getCsrfToken()\n\n // 2. 使用预处理好的 markdown(Content Script 已转换)\n // 掘金使用 Markdown 格式\n let markdown = article.markdown || ''\n\n // 3. 处理图片(上传到掘金图床)\n markdown = await this.processImages(\n markdown,\n (src) => this.uploadImageByUrl(src),\n {\n skipPatterns: [\n 'juejin.cn', 'p1-juejin', 'p3-juejin',\n 'p6-juejin', 'p9-juejin', 'byteimg.com'\n ],\n onProgress: options?.onImageProgress,\n }\n )\n\n const categoryId = await this.resolveCategoryId(article.category)\n const tagIds = await this.resolveTagIds(categoryId, article.tags)\n const coverImage = article.cover ? (await this.uploadImageByUrl(article.cover)).url : ''\n const draftPayload = {\n brief_content: article.summary || '',\n category_id: categoryId,\n cover_image: coverImage,\n edit_type: 10,\n html_content: 'deprecated',\n link_url: '',\n mark_content: markdown,\n tag_ids: tagIds,\n title: article.title,\n }\n\n // 4. 创建发布用草稿 (掘金公开前端流程先创建 draft,再 publish draft)\n const createResponse = await this.runtime.fetch(\n 'https://api.juejin.cn/content_api/v1/article_draft/create',\n {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n 'x-secsdk-csrf-token': csrfToken,\n },\n body: JSON.stringify(draftPayload),\n }\n )\n\n // 检查响应状态和内容\n const responseText = await createResponse.text()\n logger.debug('Create draft response:', createResponse.status, responseText.substring(0, 300))\n\n if (!createResponse.ok) {\n throw new Error(`创建草稿失败: ${createResponse.status} - ${responseText}`)\n }\n\n let createData: { data?: { id?: string }; err_msg?: string; err_no?: number }\n try {\n createData = JSON.parse(responseText)\n } catch {\n throw new Error(`创建草稿失败: 响应不是有效 JSON - ${responseText.substring(0, 100)}`)\n }\n\n // 检查业务错误\n if (createData.err_no && createData.err_no !== 0) {\n throw new Error(createData.err_msg || `创建草稿失败: 错误码 ${createData.err_no}`)\n }\n\n if (!createData.data?.id) {\n throw new Error(createData.err_msg || '创建草稿失败: 无效响应')\n }\n\n const draftId = createData.data.id\n logger.debug('Draft created:', draftId)\n\n // 5. 更新草稿,保持与历史 DSL 和掘金前端 publish 流程一致\n const updateResponse = await this.runtime.fetch(\n 'https://api.juejin.cn/content_api/v1/article_draft/update',\n {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n 'x-secsdk-csrf-token': csrfToken,\n },\n body: JSON.stringify({\n ...draftPayload,\n id: draftId,\n }),\n }\n )\n\n const updateText = await updateResponse.text()\n logger.debug('Update draft response:', updateResponse.status, updateText.substring(0, 300))\n\n if (!updateResponse.ok) {\n throw new Error(`更新草稿失败: ${updateResponse.status} - ${updateText}`)\n }\n\n let updateData: { err_msg?: string; err_no?: number }\n try {\n updateData = JSON.parse(updateText)\n } catch {\n throw new Error(`更新草稿失败: 响应不是有效 JSON - ${updateText.substring(0, 100)}`)\n }\n\n if (updateData.err_no !== undefined && updateData.err_no !== 0) {\n throw new Error(updateData.err_msg || `更新草稿失败: 错误码 ${updateData.err_no}`)\n }\n\n // 6. 发布草稿\n const publishResponse = await this.runtime.fetch(\n 'https://api.juejin.cn/content_api/v1/article/publish',\n {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n 'x-secsdk-csrf-token': csrfToken,\n },\n body: JSON.stringify({\n draft_id: draftId,\n sync_to_org: false,\n }),\n }\n )\n\n const publishText = await publishResponse.text()\n logger.debug('Publish response:', publishResponse.status, publishText.substring(0, 300))\n\n if (!publishResponse.ok) {\n throw new Error(`发布失败: ${publishResponse.status} - ${publishText}`)\n }\n\n let publishData: { data?: { article_id?: string }; err_msg?: string; err_no?: number }\n try {\n publishData = JSON.parse(publishText)\n } catch {\n throw new Error(`发布失败: 响应不是有效 JSON - ${publishText.substring(0, 100)}`)\n }\n\n if (publishData.err_no !== undefined && publishData.err_no !== 0) {\n throw new Error(publishData.err_msg || `发布失败: 错误码 ${publishData.err_no}`)\n }\n\n const articleId = publishData.data?.article_id\n if (!articleId) {\n throw new Error(publishData.err_msg || '发布失败: 无效响应')\n }\n\n const postUrl = `https://juejin.cn/post/${articleId}`\n\n return this.createResult(true, {\n postId: articleId,\n postUrl,\n })\n }).catch((error) => this.createResult(false, {\n error: (error as Error).message,\n }))\n }\n\n async getStatus(statusRef: PublishStatusRef): Promise<PublishStatusResult> {\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n if (!statusRef.id) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: '掘金 statusRef 缺少文章 ID',\n checkedAt: Date.now(),\n }\n }\n\n const res = await this.postJson<JuejinArticleDetailResponse>(\n 'https://api.juejin.cn/content_api/v1/article/detail',\n {\n article_id: statusRef.id,\n client_type: 2608,\n },\n )\n\n if (res.err_no === 404) {\n return {\n platform: this.meta.id,\n state: 'not_found',\n message: res.err_msg || '掘金文章不存在',\n checkedAt: Date.now(),\n }\n }\n\n if (res.err_no !== undefined && res.err_no !== 0) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: res.err_msg || `掘金状态查询失败: ${res.err_no}`,\n checkedAt: Date.now(),\n }\n }\n\n const info = res.data?.article_info\n if (info?.status === 1 && info.audit_status === 2) {\n return {\n platform: this.meta.id,\n state: 'published',\n postUrl: statusRef.url || `https://juejin.cn/post/${statusRef.id}`,\n checkedAt: Date.now(),\n }\n }\n\n return {\n platform: this.meta.id,\n state: 'reviewing',\n postUrl: statusRef.url,\n message: `status=${info?.status ?? 'unknown'}, audit_status=${info?.audit_status ?? 'unknown'}, verify_status=${info?.verify_status ?? 'unknown'}`,\n checkedAt: Date.now(),\n }\n })\n }\n\n private async resolveCategoryId(category?: string): Promise<string> {\n const categories = await this.fetchCategories()\n if (category) {\n const matched = categories.find(item =>\n item.category_id === category ||\n item.category_name === category ||\n item.category_url === category\n )\n return matched?.category_id || category\n }\n\n const defaultCategory = categories[0]?.category_id\n if (!defaultCategory) {\n throw new Error('发布失败: 掘金至少需要一个分类,但分类列表为空')\n }\n return defaultCategory\n }\n\n private async fetchCategories(): Promise<JuejinCategory[]> {\n const response = await this.runtime.fetch(\n 'https://api.juejin.cn/tag_api/v1/query_category_briefs',\n {\n method: 'GET',\n credentials: 'include',\n }\n )\n\n const data = await response.json() as {\n data?: JuejinCategory[]\n err_no?: number\n err_msg?: string\n }\n\n if (data.err_no !== undefined && data.err_no !== 0) {\n throw new Error(data.err_msg || `获取掘金分类失败: 错误码 ${data.err_no}`)\n }\n\n return data.data || []\n }\n\n private async resolveTagIds(categoryId: string, tags?: string[]): Promise<string[]> {\n const availableTags = await this.fetchTags(categoryId)\n const requestedTags = tags?.map(tag => tag.trim()).filter(Boolean) || []\n\n if (requestedTags.length) {\n const matchedTagIds = requestedTags.map(tag => {\n const matched = availableTags.find(item =>\n item.tag_id === tag ||\n item.tag_name === tag\n )\n if (!matched) {\n throw new Error(`发布失败: 掘金标签不存在或不属于当前分类: ${tag}`)\n }\n return matched.tag_id\n })\n return [...new Set(matchedTagIds)].slice(0, 3)\n }\n\n const defaultTag = availableTags[0]?.tag_id\n if (!defaultTag) {\n throw new Error('发布失败: 掘金至少需要一个标签,但标签列表为空')\n }\n return [defaultTag]\n }\n\n private async fetchTags(categoryId: string): Promise<JuejinTag[]> {\n const response = await this.runtime.fetch(\n 'https://api.juejin.cn/tag_api/v1/query_tag_list',\n {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n cursor: '0',\n limit: 20,\n sort_type: 1,\n category_id: categoryId,\n }),\n }\n )\n\n const data = await response.json() as {\n data?: Array<{ tag?: JuejinTag } | JuejinTag>\n err_no?: number\n err_msg?: string\n }\n\n if (data.err_no !== undefined && data.err_no !== 0) {\n throw new Error(data.err_msg || `获取掘金标签失败: 错误码 ${data.err_no}`)\n }\n\n const tags: JuejinTag[] = []\n for (const item of data.data || []) {\n if ('tag_id' in item && item.tag_id) {\n tags.push(item)\n } else if ('tag' in item && item.tag?.tag_id) {\n tags.push(item.tag)\n }\n }\n return tags\n }\n\n /**\n * 通过 Blob 上传图片(覆盖基类方法)\n * 需要设置动态请求头规则以支持 MCP 调用\n */\n async uploadImage(file: Blob, _filename?: string): Promise<string> {\n return this.withHeaderRules(this.HEADER_RULES, () => this.uploadImageBinaryInternal(file))\n }\n\n /**\n * 通过 URL 上传图片\n * 支持远程 URL 和 data URI,都使用 ImageX 流程\n */\n protected async uploadImageByUrl(src: string): Promise<ImageUploadResult> {\n try {\n let blob: Blob\n\n if (src.startsWith('data:')) {\n // data URI 直接转 blob\n logger.debug('Detected data URI, converting to blob')\n blob = await fetch(src).then(r => r.blob())\n } else {\n // 远程 URL:先下载再上传\n logger.debug('Downloading remote image:', src.substring(0, 80))\n const response = await this.runtime.fetch(src, {\n method: 'GET',\n })\n\n if (!response.ok) {\n logger.warn('Failed to download image:', response.status)\n return { url: src }\n }\n\n blob = await response.blob()\n }\n\n // 使用 ImageX 流程上传\n const url = await this.uploadImageBinaryInternal(blob)\n logger.debug('Uploaded image:', src.substring(0, 50), '->', url)\n return { url }\n } catch (error) {\n logger.warn('Failed to upload image by URL:', src, error)\n return { url: src } // 失败时返回原 URL\n }\n }\n\n /**\n * 获取 ImageX 上传凭证\n */\n private async getImageXToken(): Promise<ImageXToken> {\n // 检查缓存是否有效(提前 60 秒过期)\n if (this.cachedImageXToken && Date.now() < this.imageXTokenExpiry - 60000) {\n return this.cachedImageXToken\n }\n\n const url = `https://api.juejin.cn/imagex/v2/gen_token?aid=${IMAGEX_AID}&uuid=${this.uuid}&client=web`\n const response = await this.runtime.fetch(url, {\n method: 'GET',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n\n const responseText = await response.text()\n logger.debug('gen_token response:', responseText.substring(0, 500))\n\n let data: ImageXTokenResponse\n try {\n data = JSON.parse(responseText)\n } catch {\n throw new Error(`Invalid JSON response from gen_token: ${responseText.substring(0, 200)}`)\n }\n\n if (data.err_no && data.err_no !== 0) {\n throw new Error(data.err_msg || `Failed to get ImageX token: err_no=${data.err_no}`)\n }\n\n const tokenData = data.data?.token\n if (!tokenData || !tokenData.AccessKeyId || !tokenData.SecretAccessKey) {\n throw new Error(`Invalid ImageX token response: ${responseText.substring(0, 200)}`)\n }\n\n // 解析 ISO 日期为时间戳\n const expiredTime = new Date(tokenData.ExpiredTime).getTime()\n\n this.cachedImageXToken = {\n AccessKeyId: tokenData.AccessKeyId,\n SecretAccessKey: tokenData.SecretAccessKey,\n SessionToken: tokenData.SessionToken,\n ExpiredTime: expiredTime,\n }\n this.imageXTokenExpiry = expiredTime\n\n logger.debug('Got ImageX token, expires at:', tokenData.ExpiredTime)\n\n return this.cachedImageXToken\n }\n\n /**\n * 申请图片上传\n */\n private async applyImageUpload(token: ImageXToken): Promise<ImageXApplyUploadResponse['Result']['UploadAddress']> {\n const url = `https://imagex.bytedanceapi.com/?Action=ApplyImageUpload&Version=2018-08-01&ServiceId=${IMAGEX_SERVICE_ID}`\n\n // 生成 AWS4 签名\n const signResult = await signAWS4({\n method: 'GET',\n url,\n accessKeyId: token.AccessKeyId,\n secretAccessKey: token.SecretAccessKey,\n securityToken: token.SessionToken,\n region: 'cn-north-1',\n service: 'imagex',\n })\n\n const response = await this.runtime.fetch(url, {\n method: 'GET',\n headers: {\n ...signResult.headers,\n },\n })\n\n const data = await response.json() as ImageXApplyUploadResponse\n\n if (!data.Result?.UploadAddress) {\n throw new Error('Failed to apply image upload')\n }\n\n return data.Result.UploadAddress\n }\n\n /**\n * 上传文件到 TOS\n */\n private async uploadToTOS(\n uploadAddress: ImageXApplyUploadResponse['Result']['UploadAddress'],\n file: Blob\n ): Promise<void> {\n const storeInfo = uploadAddress.StoreInfos[0]\n const uploadHost = uploadAddress.UploadHosts[0]\n\n if (!storeInfo || !uploadHost) {\n throw new Error('Invalid upload address')\n }\n\n // 构建上传 URL\n const uploadUrl = `https://${uploadHost}/${storeInfo.StoreUri}`\n\n // 计算 CRC32\n const arrayBuffer = await file.arrayBuffer()\n const uint8Array = new Uint8Array(arrayBuffer)\n const crc32Value = crc32(uint8Array)\n\n logger.debug('Uploading to TOS:', uploadUrl, 'size:', file.size, 'crc32:', crc32Value)\n\n // 上传文件\n const response = await this.runtime.fetch(uploadUrl, {\n method: 'PUT',\n headers: {\n 'Authorization': storeInfo.Auth,\n 'Content-Type': file.type || 'application/octet-stream',\n 'Content-CRC32': crc32Value,\n },\n body: file,\n })\n\n if (!response.ok) {\n const text = await response.text()\n throw new Error(`TOS upload failed: ${response.status} ${text}`)\n }\n\n logger.debug('TOS upload success')\n }\n\n /**\n * 提交图片上传\n */\n private async commitImageUpload(\n token: ImageXToken,\n sessionKey: string\n ): Promise<ImageXCommitUploadResponse['Result']> {\n const url = `https://imagex.bytedanceapi.com/?Action=CommitImageUpload&Version=2018-08-01&SessionKey=${encodeURIComponent(sessionKey)}&ServiceId=${IMAGEX_SERVICE_ID}`\n\n // 生成 AWS4 签名\n const signResult = await signAWS4({\n method: 'POST',\n url,\n accessKeyId: token.AccessKeyId,\n secretAccessKey: token.SecretAccessKey,\n securityToken: token.SessionToken,\n region: 'cn-north-1',\n service: 'imagex',\n })\n\n const response = await this.runtime.fetch(url, {\n method: 'POST',\n headers: {\n ...signResult.headers,\n 'Content-Length': '0',\n },\n })\n\n const data = await response.json() as ImageXCommitUploadResponse\n\n if (!data.Result) {\n throw new Error('Failed to commit image upload')\n }\n\n return data.Result\n }\n\n /**\n * 获取图片 URL\n */\n private async getImageUrl(uri: string): Promise<string> {\n const url = `https://api.juejin.cn/imagex/v2/get_img_url?aid=${IMAGEX_AID}&uuid=${this.uuid}&uri=${encodeURIComponent(uri)}&img_type=private`\n\n const response = await this.runtime.fetch(url, {\n method: 'GET',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n\n const data = await response.json() as {\n data?: { main_url?: string; backup_url?: string }\n err_no?: number\n err_msg?: string\n }\n\n if (data.err_no && data.err_no !== 0) {\n throw new Error(data.err_msg || 'Failed to get image URL')\n }\n\n const imageUrl = data.data?.main_url || data.data?.backup_url\n if (!imageUrl) {\n throw new Error('Invalid image URL response')\n }\n\n return imageUrl\n }\n\n /**\n * 上传图片 (ImageX 方式) - 内部使用\n */\n private async uploadImageBinaryInternal(file: Blob): Promise<string> {\n // 1. 获取上传凭证\n const token = await this.getImageXToken()\n\n // 2. 申请上传\n const uploadAddress = await this.applyImageUpload(token)\n logger.debug('Apply upload success, session:', uploadAddress.SessionKey.substring(0, 50) + '...')\n\n // 3. 上传到 TOS\n await this.uploadToTOS(uploadAddress, file)\n\n // 4. 提交上传\n const commitResult = await this.commitImageUpload(token, uploadAddress.SessionKey)\n logger.debug('Commit upload success:', commitResult.Results?.[0]?.Uri)\n\n // 5. 获取图片 URL\n const storeUri = uploadAddress.StoreInfos[0]?.StoreUri\n if (!storeUri) {\n throw new Error('No store URI in upload address')\n }\n\n const imageUrl = await this.getImageUrl(storeUri)\n logger.debug('Got image URL:', imageUrl)\n\n return imageUrl\n }\n\n /**\n * 获取分类列表\n */\n async getCategories() {\n return (await this.fetchCategories()).map(c => ({\n id: c.category_id,\n name: c.category_name,\n }))\n }\n}\n","/**\n * 网易号适配器\n */\nimport { CodeAdapter, type ImageUploadResult } from '../code-adapter'\nimport type {\n Article,\n AuthResult,\n SyncResult,\n PlatformMeta,\n PublishStatusRef,\n PublishStatusResult,\n} from '../../types'\nimport type { PublishOptions } from '../types'\nimport { markdownToHtml } from '../../lib/turndown'\nimport { createLogger } from '../../lib/logger'\n\nconst logger = createLogger('Netease')\n\ninterface NeteaseAccountInfo {\n wemediaId: string\n realUserId?: string\n userId?: string\n tname?: string\n icon?: string\n keepSilent?: boolean\n faceDetectFlag?: boolean\n}\n\ninterface NeteasePostPageInfo {\n wemediaId: string\n onlineState?: number\n todayPubCount?: number\n maxDailyPublishCount?: number\n originalFlag?: number\n newProminentFlag?: number\n allowedRepost?: boolean\n hasRecommRight?: boolean | null\n}\n\ninterface NeteaseApiResponse<T = unknown> {\n code: number\n msg?: string\n data?: T\n}\n\ninterface NeteaseContentItem {\n articleId?: string | number\n docId?: string | number\n skipId?: string | number\n title?: string\n contentType?: number\n contentState?: number\n unrecomReason?: string\n refuseReason?: string\n reason?: string\n}\n\ninterface NeteaseContentListData {\n list?: NeteaseContentItem[]\n total?: number\n}\n\nexport class NeteaseAdapter extends CodeAdapter {\n readonly meta: PlatformMeta = {\n id: 'netease',\n name: '网易号',\n icon: 'https://mp.163.com/favicon.ico',\n homepage: 'https://mp.163.com/#/article-publish',\n capabilities: ['article', 'image_upload', 'cover'],\n }\n\n readonly preprocessConfig = {\n outputFormat: 'html' as const,\n convertTablesToText: true,\n }\n\n private accountInfo: NeteaseAccountInfo | null = null\n\n private readonly HEADER_RULES = [\n {\n urlFilter: '*://mp.163.com/*',\n headers: {\n Origin: 'https://mp.163.com',\n Referer: 'https://mp.163.com/',\n },\n resourceTypes: ['xmlhttprequest'],\n },\n ]\n\n async checkAuth(): Promise<AuthResult> {\n try {\n const response = await this.runtime.fetch(\n `https://mp.163.com/wemedia/navinfo.do?_=${Date.now()}`,\n {\n method: 'GET',\n credentials: 'include',\n headers: { Accept: 'application/json' },\n }\n )\n const res = await response.json() as NeteaseApiResponse<NeteaseAccountInfo>\n\n logger.debug('checkAuth response:', res)\n\n if (res.code !== 1 || !res.data?.wemediaId) {\n return { isAuthenticated: false, error: res.msg || '未登录' }\n }\n\n this.accountInfo = res.data\n return {\n isAuthenticated: true,\n userId: res.data.wemediaId,\n username: res.data.tname || res.data.realUserId || res.data.userId,\n avatar: res.data.icon,\n }\n } catch (error) {\n logger.debug('checkAuth: not logged in -', error)\n return { isAuthenticated: false, error: (error as Error).message }\n }\n }\n\n async publish(article: Article, options?: PublishOptions): Promise<SyncResult> {\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n logger.info('Starting publish...')\n\n if (!this.accountInfo) {\n const auth = await this.checkAuth()\n if (!auth.isAuthenticated) {\n throw new Error('请先登录网易号')\n }\n }\n\n if (this.accountInfo?.keepSilent) {\n throw new Error('账号被禁言,网易号拒绝发布')\n }\n if (this.accountInfo?.faceDetectFlag) {\n throw new Error('请先通过网易号实名认证后再发布内容')\n }\n\n const postPage = await this.fetchPostPageInfo()\n this.assertPublishAllowed(postPage)\n\n let content = this.prepareContent(article.html || markdownToHtml(article.markdown))\n content = await this.processImages(\n content,\n (src) => this.uploadImageByUrl(src),\n {\n skipPatterns: ['mp.163.com', 'dingyue.ws.126.net', 'mobilepics.ws.126.net'],\n onProgress: options?.onImageProgress,\n }\n )\n\n let cover = 'auto'\n let picUrl = ''\n if (article.cover) {\n const uploadedCover = await this.uploadImageByUrl(article.cover)\n cover = 'custom'\n picUrl = uploadedCover.url\n }\n\n const payload = new URLSearchParams({\n wemediaId: postPage.wemediaId,\n articleId: '-1',\n title: article.title,\n content,\n cover,\n operation: 'publish',\n scheduled: '0',\n firstPub: '2',\n onlineState: String(postPage.onlineState ?? 2),\n original: String(postPage.originalFlag ? 1 : 0),\n essayId: '',\n essayTitle: '不参加活动',\n essayUrl: '',\n essayClassify: '',\n })\n if (picUrl) payload.set('picUrl', picUrl)\n if (postPage.newProminentFlag === 1) payload.set('newProminentState', '0')\n if (postPage.allowedRepost) payload.set('allowedRepost', '1')\n\n const response = await this.runtime.fetch(\n `https://mp.163.com/wemedia/article/status/api/publishV2.do?_=${Date.now()}`,\n {\n method: 'POST',\n credentials: 'include',\n headers: {\n Accept: 'application/json, text/javascript, */*; q=0.01',\n 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\n },\n body: payload.toString(),\n }\n )\n const res = await response.json() as NeteaseApiResponse<string | Record<string, unknown>>\n\n logger.debug('Publish response:', res)\n\n if (res.code !== 1) {\n throw new Error(this.formatApiError(res))\n }\n\n const postId = this.extractPostId(res.data)\n || this.stringifyId((await this.findManagedArticleByTitle(article.title))?.articleId)\n return this.createResult(true, {\n postId,\n postUrl: postId\n ? `https://www.163.com/dy/article/${postId}.html`\n : 'https://mp.163.com/#/content-manage',\n statusData: { title: article.title },\n })\n }).catch((error) => this.createResult(false, {\n error: (error as Error).message,\n }))\n }\n\n async getStatus(statusRef: PublishStatusRef): Promise<PublishStatusResult> {\n const articleId = statusRef.id || this.extractPostIdFromUrl(statusRef.url)\n const title = typeof statusRef.data?.title === 'string' ? statusRef.data.title : ''\n\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n const item = (articleId ? await this.findManagedArticle(articleId) : null)\n || (title ? await this.findManagedArticleByTitle(title) : null)\n if (!item) {\n return {\n platform: this.meta.id,\n state: 'not_found',\n message: articleId ? '网易号内容管理列表未找到该文章' : '网易号 statusRef 缺少文章 ID,且无法通过标题定位文章',\n checkedAt: Date.now(),\n }\n }\n\n return this.mapManagedStatus(item, statusRef)\n })\n }\n\n protected async uploadImageByUrl(src: string): Promise<ImageUploadResult> {\n const imageResponse = await fetch(src)\n if (!imageResponse.ok) {\n throw new Error('图片下载失败: ' + src)\n }\n const imageBlob = await imageResponse.blob()\n\n const formData = new FormData()\n formData.append('file', imageBlob, 'image.jpg')\n formData.append('from', 'neteasecode_mp')\n\n const uploadResponse = await this.runtime.fetch(\n 'https://mp.163.com/api/v3/upload/picupload',\n {\n method: 'POST',\n credentials: 'include',\n body: formData,\n }\n )\n const res = await uploadResponse.json() as NeteaseApiResponse<{\n url?: string\n picUrl?: string\n } | Array<{ url?: string; picUrl?: string }>> & {\n url?: string\n picUrl?: string\n }\n\n logger.debug('Image upload response:', res)\n\n const data = Array.isArray(res.data) ? res.data[0] : res.data\n const url = data?.url || data?.picUrl || res.url || res.picUrl\n if (![1, 200].includes(res.code) || !url) {\n throw new Error(res.msg || '图片上传失败')\n }\n\n return { url }\n }\n\n private async fetchPostPageInfo(): Promise<NeteasePostPageInfo> {\n const wemediaId = this.accountInfo?.wemediaId\n if (!wemediaId) throw new Error('请先登录网易号')\n\n const params = new URLSearchParams({\n _: String(Date.now()),\n wemediaId,\n mediaId: wemediaId,\n })\n if (this.accountInfo?.realUserId) {\n params.set('realUserId', this.accountInfo.realUserId)\n }\n\n const response = await this.runtime.fetch(\n `https://mp.163.com/wemedia/article/postpage.do?${params.toString()}`,\n {\n method: 'GET',\n credentials: 'include',\n headers: { Accept: 'application/json' },\n }\n )\n const res = await response.json() as NeteaseApiResponse<NeteasePostPageInfo>\n\n logger.debug('postpage response:', res)\n\n if (res.code !== 1 || !res.data?.wemediaId) {\n throw new Error(res.msg || '网易号发布页初始化失败')\n }\n return res.data\n }\n\n private assertPublishAllowed(postPage: NeteasePostPageInfo): void {\n if ([1, 3, 9].includes(postPage.onlineState ?? 2)) {\n throw new Error('网易号账号未上线,暂不支持发布')\n }\n if (postPage.onlineState === 4) {\n throw new Error('网易号账号已下线,不能发布文章')\n }\n if (\n typeof postPage.todayPubCount === 'number' &&\n typeof postPage.maxDailyPublishCount === 'number' &&\n postPage.maxDailyPublishCount > 0 &&\n postPage.todayPubCount >= postPage.maxDailyPublishCount\n ) {\n throw new Error('今日发布数量已达最大值,网易号拒绝发布')\n }\n }\n\n private formatApiError(res: NeteaseApiResponse): string {\n if (res.code === 100025) return '账号被禁言,网易号拒绝发布'\n if (res.code === 100502 || res.code === 100503) {\n return res.msg || '网易号要求完成图形验证码验证'\n }\n return res.msg || `网易号发布失败: ${res.code}`\n }\n\n private prepareContent(html: string): string {\n return this.replaceTablesWithText(\n this.replaceCodeBlocksWithText(\n this.replaceLinksWithUrls(html),\n ),\n )\n }\n\n private replaceLinksWithUrls(html: string): string {\n return html.replace(\n /<a\\b[^>]*href=([\"'])(.*?)\\1[^>]*>([\\s\\S]*?)<\\/a>/gi,\n (_match, _quote, href, label) => {\n const text = this.textFromHtml(label)\n if (!href || href.startsWith('#') || href.toLowerCase().startsWith('javascript:')) return text\n return text === href ? text : `${text || href}(${this.decodeHtml(href)})`\n },\n )\n }\n\n private replaceTablesWithText(html: string): string {\n // ponytail: regex covers Markdown-generated tables; use a DOM parser if pasted arbitrary nested tables matter.\n return html.replace(/<table\\b[\\s\\S]*?<\\/table>/gi, (table) => {\n const headers: string[] = []\n const rows: string[][] = []\n\n for (const rowMatch of table.matchAll(/<tr\\b[\\s\\S]*?<\\/tr>/gi)) {\n const rowHtml = rowMatch[0]\n const cells = [...rowHtml.matchAll(/<t([hd])\\b[^>]*>([\\s\\S]*?)<\\/t[hd]>/gi)]\n const values = cells.map(cell => this.textFromHtml(cell[2]))\n if (values.length === 0) continue\n\n const isHeader = cells.every(cell => cell[1].toLowerCase() === 'h')\n if (headers.length === 0 && isHeader) {\n headers.push(...values)\n continue\n }\n rows.push(values)\n }\n\n return rows.map((row) => {\n const parts = row.map((value, index) => headers[index] ? `${headers[index]}: ${value}` : value)\n return `<p>${this.escapeHtml(parts.join(' | '))}</p>`\n }).join('')\n })\n }\n\n private replaceCodeBlocksWithText(html: string): string {\n return html.replace(/<pre\\b[^>]*>\\s*<code\\b[^>]*>([\\s\\S]*?)<\\/code>\\s*<\\/pre>/gi, (_match, code) => {\n const lines = this.decodeHtml(code\n .replace(/<br\\s*\\/?>/gi, '\\n')\n .replace(/<[^>]+>/g, ''))\n .split(/\\r?\\n/)\n .map(line => line.trimEnd())\n .filter(line => line.trim())\n\n if (lines.length === 0) return ''\n return [\n '<p>代码示例:</p>',\n ...lines.map(line => `<p>${this.escapeHtml(line)}</p>`),\n ].join('')\n })\n }\n\n private textFromHtml(html: string): string {\n return this.decodeHtml(html\n .replace(/<br\\s*\\/?>/gi, ' ')\n .replace(/<[^>]+>/g, '')\n .replace(/\\s+/g, ' ')\n .trim())\n }\n\n private decodeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/ /g, ' ')\n }\n\n private escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n }\n\n private extractPostId(data: unknown): string | undefined {\n if (typeof data === 'string') {\n const params = new URLSearchParams(data.startsWith('?') ? data.slice(1) : data)\n return params.get('docId') || params.get('articleId') || params.get('postId') || undefined\n }\n\n if (data && typeof data === 'object') {\n const record = data as Record<string, unknown>\n const id = record.docId || record.articleId || record.postId || record.id\n if (id) return String(id)\n }\n\n return undefined\n }\n\n private stringifyId(value: unknown): string | undefined {\n return value ? String(value) : undefined\n }\n\n private extractPostIdFromUrl(url?: string): string | undefined {\n return url?.match(/\\/article\\/([A-Z0-9]+)\\.html/i)?.[1]\n || url?.match(/[?&](?:articleId|docId|postId)=([^&#]+)/)?.[1]\n }\n\n private async findManagedArticle(articleId: string): Promise<NeteaseContentItem | null> {\n for (let pageNo = 1; pageNo <= 5; pageNo++) {\n const list = await this.listManagedArticles(pageNo)\n const match = list.find(item => [item.articleId, item.docId, item.skipId]\n .some(id => String(id || '') === articleId))\n if (match) return match\n if (list.length === 0) break\n }\n\n return null\n }\n\n private async findManagedArticleByTitle(title: string): Promise<NeteaseContentItem | null> {\n for (let pageNo = 1; pageNo <= 5; pageNo++) {\n const list = await this.listManagedArticles(pageNo, title)\n const match = list.find(item => item.title === title)\n if (match) return match\n if (list.length === 0) break\n }\n\n return null\n }\n\n private async listManagedArticles(pageNo: number, word = ''): Promise<NeteaseContentItem[]> {\n const response = await this.runtime.fetch('https://mp.163.com/wemedia/content/manage/list.do', {\n method: 'POST',\n credentials: 'include',\n headers: {\n Accept: 'application/json, text/plain, */*',\n 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\n },\n body: new URLSearchParams({\n pageNo: String(pageNo),\n size: '10',\n contentType: '1',\n word,\n }).toString(),\n })\n const res = await response.json() as NeteaseApiResponse<NeteaseContentListData> & NeteaseContentListData\n if ('code' in res && res.code !== 1) {\n throw new Error(res.msg || '网易号文章状态查询失败')\n }\n\n return res.data?.list || res.list || []\n }\n\n private async mapManagedStatus(item: NeteaseContentItem, statusRef: PublishStatusRef): Promise<PublishStatusResult> {\n const checkedAt = Date.now()\n const state = item.contentState\n const articleId = String(item.articleId || item.docId || item.skipId || statusRef.id || '')\n const publicUrl = articleId ? `https://www.163.com/dy/article/${articleId}.html` : statusRef.url\n const reason = item.unrecomReason || item.refuseReason || item.reason\n\n if (reason) {\n return {\n platform: this.meta.id,\n state: 'rejected',\n message: `网易号文章状态: 未通过,原因: ${reason}`,\n checkedAt,\n }\n }\n\n if ((state === 2 || state === 3) && publicUrl && await this.isPublicArticleAvailable(publicUrl)) {\n return {\n platform: this.meta.id,\n state: 'published',\n postUrl: publicUrl,\n message: '网易号文章状态: 已发布',\n checkedAt,\n }\n }\n\n if (state === 1 || state === 2) {\n return {\n platform: this.meta.id,\n state: 'reviewing',\n message: '网易号文章状态: 审核中',\n checkedAt,\n }\n }\n\n if (state === 3 || state === 7 || state === 9) {\n return {\n platform: this.meta.id,\n state: 'rejected',\n message: '网易号文章状态: 未通过',\n checkedAt,\n }\n }\n\n if (state === 4) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: '网易号文章状态: 已下线',\n checkedAt,\n }\n }\n\n return {\n platform: this.meta.id,\n state: 'unknown',\n postUrl: statusRef.url,\n message: `网易号文章状态: ${state ?? '未知'}`,\n checkedAt,\n }\n }\n\n private async isPublicArticleAvailable(url: string): Promise<boolean> {\n try {\n const response = await this.runtime.fetch(url, { credentials: 'omit' })\n return response.ok\n } catch {\n return false\n }\n }\n}\n","/**\n * 搜狐号适配器\n */\nimport { CodeAdapter, type ImageUploadResult } from '../code-adapter'\nimport type {\n Article,\n AuthResult,\n PublishStatusRef,\n PublishStatusResult,\n SyncResult,\n PlatformMeta,\n} from '../../types'\nimport type { PublishOptions } from '../types'\nimport { createLogger } from '../../lib/logger'\n\nconst logger = createLogger('Sohu')\n\ninterface SohuAccountInfo {\n id: string\n nickName: string\n avatar: string\n}\n\ninterface SohuNewsItem {\n id?: string | number\n userId?: string | number\n status?: number\n title?: string\n rejectReason?: string\n}\n\ninterface SohuNewsListResponse {\n code: number\n success?: boolean\n msg?: string\n data?: {\n news?: SohuNewsItem[]\n }\n}\n\n/**\n * 生成设备 ID (dv-id)\n */\nfunction generateDeviceId(): string {\n const chars = '0123456789abcdef'\n let result = ''\n for (let i = 0; i < 32; i++) {\n result += chars[Math.floor(Math.random() * chars.length)]\n }\n return result\n}\n\nexport class SohuAdapter extends CodeAdapter {\n readonly meta: PlatformMeta = {\n id: 'sohu',\n name: '搜狐号',\n icon: 'https://mp.sohu.com/favicon.ico',\n homepage: 'https://mp.sohu.com/mpfe/v3/main/first/page?newsType=1',\n capabilities: ['article', 'image_upload'],\n }\n\n /** 预处理配置: 搜狐号使用 HTML 格式 */\n readonly preprocessConfig = {\n outputFormat: 'html' as const,\n }\n\n private accountInfo: SohuAccountInfo | null = null\n private deviceId: string = generateDeviceId()\n private spCm: string = ''\n\n /** 搜狐号 API 需要的 Header 规则 */\n private readonly HEADER_RULES = [\n {\n urlFilter: '*://mp.sohu.com/*',\n headers: {\n 'Origin': 'https://mp.sohu.com',\n 'Referer': 'https://mp.sohu.com/',\n },\n resourceTypes: ['xmlhttprequest'],\n },\n ]\n\n async checkAuth(): Promise<AuthResult> {\n try {\n // 使用 /account/list 获取所有子账号(搜狐号支持多个子账号)\n const response = await this.runtime.fetch(\n `https://mp.sohu.com/mpbp/bp/account/list?_=${Date.now()}`,\n {\n method: 'GET',\n credentials: 'include',\n }\n )\n\n const res = await response.json() as {\n code: number\n data?: {\n data?: Array<{\n accounts: SohuAccountInfo[]\n }>\n }\n }\n\n logger.debug('checkAuth response:', res)\n\n if (res.code !== 2000000 || !res.data?.data?.[0]?.accounts?.length) {\n return { isAuthenticated: false }\n }\n\n // 收集所有子账号\n const allAccounts: SohuAccountInfo[] = []\n for (const group of res.data.data) {\n if (group.accounts) {\n allAccounts.push(...group.accounts)\n }\n }\n\n if (allAccounts.length === 0) {\n return { isAuthenticated: false }\n }\n\n // 默认使用第一个子账号\n this.accountInfo = allAccounts[0]\n logger.info(`Using account: ${this.accountInfo.nickName} (id: ${this.accountInfo.id})` +\n (allAccounts.length > 1 ? `, ${allAccounts.length} sub-accounts available` : ''))\n\n // 获取 mp-cv cookie 用于 sp-cm header\n await this.fetchSpCm()\n\n // 如果有多个子账号,在用户名中标注\n const displayName = allAccounts.length > 1\n ? `${this.accountInfo.nickName} (共${allAccounts.length}个子账号)`\n : this.accountInfo.nickName\n\n return {\n isAuthenticated: true,\n userId: String(this.accountInfo.id),\n username: displayName,\n avatar: this.accountInfo.avatar,\n }\n } catch (error) {\n logger.debug('checkAuth: not logged in -', error)\n return { isAuthenticated: false, error: (error as Error).message }\n }\n }\n\n /**\n * 获取 sp-cm 值 (从 cookie 或生成)\n */\n private async fetchSpCm(): Promise<void> {\n try {\n // 尝试通过 runtime 获取 cookie(如果支持)\n if (this.runtime.getCookie) {\n const cookieValue = await this.runtime.getCookie('.sohu.com', 'mp-cv')\n if (cookieValue) {\n this.spCm = cookieValue\n logger.debug('Got sp-cm from cookie:', this.spCm)\n return\n }\n }\n // fallback: 生成一个\n this.spCm = `100-${Date.now()}-${generateDeviceId()}`\n logger.debug('Generated sp-cm:', this.spCm)\n } catch (error) {\n // fallback: 生成一个\n this.spCm = `100-${Date.now()}-${generateDeviceId()}`\n logger.debug('Fallback sp-cm:', this.spCm)\n }\n }\n\n async publish(article: Article, options?: PublishOptions): Promise<SyncResult> {\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n logger.info('Starting publish...')\n\n // 1. 确保已登录\n if (!this.accountInfo) {\n const auth = await this.checkAuth()\n if (!auth.isAuthenticated) {\n throw new Error('请先登录搜狐号')\n }\n }\n\n // Use pre-processed HTML content directly\n let content = article.html || ''\n\n // Process images\n content = await this.processImages(\n content,\n (src) => this.uploadImageByUrl(src),\n {\n skipPatterns: ['sohu.com'],\n onProgress: options?.onImageProgress,\n }\n )\n const cover = article.cover ? (await this.uploadImageByUrl(article.cover)).url : ''\n\n // 4. 直接发布 (v2 API - JSON 格式)\n const postData = {\n title: article.title,\n brief: article.summary || '',\n content: content,\n channelId: 24,\n categoryId: -1,\n id: 0,\n userColumnId: 0,\n columnNewsIds: [],\n businessCode: 0,\n declareOriginal: false,\n cover,\n topicIds: [],\n isAd: 0,\n userLabels: '[]',\n reprint: false,\n customTags: this.resolveTags(article),\n infoResource: 0,\n sourceUrl: '',\n visibleToLoginedUsers: 0,\n attrIds: [],\n auto: true,\n accountId: Number(this.accountInfo!.id),\n }\n\n const response = await this.runtime.fetch(\n `https://mp.sohu.com/mpbp/bp/news/v4/news/publish/v2?accountId=${this.accountInfo!.id}`,\n {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Requested-With': 'XMLHttpRequest',\n 'dv-id': this.deviceId,\n 'sp-cm': this.spCm,\n },\n body: JSON.stringify(postData),\n }\n )\n\n const res = await response.json() as {\n success: boolean\n data?: string | number\n msg?: string\n }\n\n logger.debug(' Publish response:', res)\n\n if (!res.success) {\n throw new Error(res.msg || '发布失败')\n }\n\n const postId = res.data\n const postUrl = `https://mp.sohu.com/mpfe/v4/contentManagement/first/page?statusType=4`\n\n return this.createResult(true, {\n postId: String(postId),\n postUrl,\n })\n }).catch((error) => this.createResult(false, {\n error: (error as Error).message,\n }))\n }\n\n async getStatus(statusRef: PublishStatusRef): Promise<PublishStatusResult> {\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n if (!this.accountInfo) {\n const auth = await this.checkAuth()\n if (!auth.isAuthenticated) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: '请先登录搜狐号',\n checkedAt: Date.now(),\n }\n }\n }\n\n if (!statusRef.id) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: 'statusRef does not include an article id',\n checkedAt: Date.now(),\n }\n }\n\n const article = await this.findNewsItem(statusRef.id)\n if (!article) {\n return {\n platform: this.meta.id,\n state: 'not_found',\n message: '搜狐号文章列表中未找到该文章',\n checkedAt: Date.now(),\n }\n }\n\n return this.mapNewsStatus(article, statusRef)\n })\n }\n\n /**\n * 通过 URL 上传图片\n */\n protected async uploadImageByUrl(src: string): Promise<ImageUploadResult> {\n if (!this.accountInfo) {\n throw new Error('未登录')\n }\n\n // 1. 下载图片\n const imageResponse = await fetch(src)\n if (!imageResponse.ok) {\n throw new Error('图片下载失败: ' + src)\n }\n const imageBlob = await imageResponse.blob()\n\n // 2. 上传到搜狐\n const formData = new FormData()\n formData.append('file', imageBlob, 'image.jpg')\n formData.append('accountId', this.accountInfo.id)\n\n const uploadResponse = await this.runtime.fetch(\n 'https://mp.sohu.com/commons/front/outerUpload/image/file?accountId='+ this.accountInfo.id,\n {\n method: 'POST',\n credentials: 'include',\n body: formData,\n }\n )\n\n const res = await uploadResponse.json() as {\n url?: string\n msg?: string\n }\n\n logger.debug(' Image upload response:', res)\n if (!res.url) {\n throw new Error('图片上传失败:'+ (res.msg))\n }\n\n return {\n url: res.url,\n }\n }\n\n private async findNewsItem(articleId: string): Promise<SohuNewsItem | null> {\n const statusTypes = [1, 2, 4, 7, 3, 6, 5]\n\n for (const statusType of statusTypes) {\n const url = new URL('https://mp.sohu.com/mpbp/bp/news/v4/users/news')\n url.searchParams.set('psize', '20')\n url.searchParams.set('newsType', '0')\n url.searchParams.set('statusType', String(statusType))\n url.searchParams.set('columnId', '')\n url.searchParams.set('pno', '1')\n url.searchParams.set('streamId', '')\n url.searchParams.set('accountId', this.accountInfo!.id)\n url.searchParams.set('_', String(Date.now()))\n\n const response = await this.runtime.fetch(url.toString(), {\n method: 'GET',\n credentials: 'include',\n headers: {\n 'X-Requested-With': 'XMLHttpRequest',\n 'dv-id': this.deviceId,\n 'sp-cm': this.spCm,\n },\n })\n\n const res = await response.json() as SohuNewsListResponse\n logger.debug('Status list response:', { statusType, res })\n\n if (res.code !== 2000000) {\n throw new Error(res.msg || '搜狐号文章状态查询失败')\n }\n\n const match = res.data?.news?.find((item) => String(item.id) === articleId)\n if (match) return match\n }\n\n return null\n }\n\n private mapNewsStatus(article: SohuNewsItem, statusRef: PublishStatusRef): PublishStatusResult {\n const checkedAt = Date.now()\n const status = article.status\n\n if (status === 4 || status === 16) {\n return {\n platform: this.meta.id,\n state: 'published',\n postUrl: this.getPublicUrl(article, statusRef),\n message: '搜狐号文章状态: 已发布',\n checkedAt,\n }\n }\n\n if (status === 2 || status === 5) {\n return {\n platform: this.meta.id,\n state: 'reviewing',\n postUrl: statusRef.url,\n message: status === 5 ? '搜狐号文章状态: 定时发布' : '搜狐号文章状态: 审核中',\n checkedAt,\n }\n }\n\n if (status === 3 || status === 7 || status === 9) {\n const reason = article.rejectReason ? `,原因: ${article.rejectReason}` : ''\n return {\n platform: this.meta.id,\n state: 'rejected',\n postUrl: statusRef.url,\n message: `搜狐号文章状态: 未通过${reason}`,\n checkedAt,\n }\n }\n\n if (status === 1) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n postUrl: statusRef.url,\n message: '搜狐号文章状态: 草稿',\n checkedAt,\n }\n }\n\n return {\n platform: this.meta.id,\n state: 'unknown',\n postUrl: statusRef.url,\n message: `搜狐号文章状态: ${status ?? '未知'}`,\n checkedAt,\n }\n }\n\n private getPublicUrl(article: SohuNewsItem, statusRef: PublishStatusRef): string | undefined {\n const articleId = article.id ?? statusRef.id\n const userId = article.userId ?? this.accountInfo?.id\n if (articleId && userId) return `https://www.sohu.com/a/${articleId}_${userId}`\n return statusRef.url\n }\n\n private resolveTags(article: Article): string {\n return article.tags?.map(tag => tag.trim()).filter(Boolean).slice(0, 10).join(',') || ''\n }\n}\n","/**\n * 腾讯号/腾讯内容开放平台适配器\n */\nimport { CodeAdapter, type ImageUploadResult } from '../code-adapter'\nimport type {\n Article,\n AuthResult,\n PlatformMeta,\n PublishStatusRef,\n PublishStatusResult,\n SyncResult,\n} from '../../types'\nimport type { PublishOptions } from '../types'\nimport { markdownToHtml } from '../../lib/turndown'\nimport { createLogger } from '../../lib/logger'\n\nconst logger = createLogger('Tencent')\n\ninterface TencentUserInfo {\n mediaId?: string | number\n mediaid?: string | number\n id?: string | number\n name?: string\n mediaName?: string\n medianame?: string\n nick?: string\n avatar?: string\n header?: string\n Header?: string\n}\n\ninterface TencentApiResponse<T = unknown> {\n response?: {\n code?: number\n msg?: string\n message?: string\n }\n data?: T\n code?: number\n msg?: string\n message?: string\n}\n\ninterface TencentPublishData {\n articleId?: string | number\n articleid?: string | number\n article_id?: string | number\n id?: string | number\n url?: string\n articleUrl?: string\n}\n\ninterface TencentImageUploadResult extends ImageUploadResult {\n variants?: Record<string, string>\n}\n\ninterface TencentListItem {\n article_id?: string | number\n articleId?: string | number\n articleid?: string | number\n id?: string | number\n title?: string\n status?: string | number\n auditStatus?: string | number\n articleStatus?: string | number\n statusDesc?: string\n status_desc?: string\n reject_reason?: string\n reject_reason_msg?: string\n standard_reject_reason?: string\n revisableReason?: string\n pub_time?: string\n reason?: string\n rejectReason?: string\n url?: string\n articleUrl?: string\n article_url?: string\n}\n\ninterface TencentListData {\n list?: TencentListItem[]\n articles?: TencentListItem[]\n total?: number\n}\n\nexport class TencentAdapter extends CodeAdapter {\n readonly meta: PlatformMeta = {\n id: 'tencent',\n name: '腾讯号',\n icon: 'https://om.gtimg.cn/om/om_2.0/images/favicon_om.ico',\n homepage: 'https://om.qq.com/main/article/articlePublish',\n capabilities: ['article', 'image_upload', 'cover'],\n }\n\n readonly preprocessConfig = {\n outputFormat: 'html' as const,\n }\n\n private userInfo: TencentUserInfo | null = null\n\n private readonly HEADER_RULES = [\n {\n urlFilter: '*://om.qq.com/*',\n headers: {\n Origin: 'https://om.qq.com',\n Referer: 'https://om.qq.com/main/article/articlePublish',\n },\n resourceTypes: ['xmlhttprequest'],\n },\n ]\n\n async checkAuth(): Promise<AuthResult> {\n try {\n const tabId = await this.ensureTencentTab()\n const info = await this.runtime.tabs!.executeScript<TencentUserInfo | null, []>(tabId, () => {\n const maybeWindow = window as typeof window & { g_userInfo?: TencentUserInfo }\n return maybeWindow.g_userInfo || null\n }, [])\n if (!info || !this.userId(info)) return { isAuthenticated: false }\n\n this.userInfo = info\n return {\n isAuthenticated: true,\n userId: this.userId(info),\n username: info.mediaName || info.medianame || info.name || info.nick,\n avatar: info.avatar || info.header || info.Header,\n }\n } catch (error) {\n logger.debug('checkAuth: not logged in -', error)\n return { isAuthenticated: false, error: (error as Error).message }\n }\n }\n\n async publish(article: Article, options?: PublishOptions): Promise<SyncResult> {\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n const auth = await this.checkAuth()\n if (!auth.isAuthenticated) {\n throw new Error('请先登录腾讯号')\n }\n\n const prepared = await this.prepareArticleContent(article, options)\n const cover = article.cover ? await this.uploadCoverByUrl(article.cover) : null\n const summary = article.summary || prepared.pureText.slice(0, 120)\n const payload = {\n title: article.title,\n title2: '',\n type: '0',\n content: prepared.content,\n abstract: summary,\n tag: (article.tags || []).join(','),\n video: '',\n cover_type: cover ? 1 : 0,\n imgurl: cover?.url || '',\n imgurl_ext: cover?.variants ? JSON.stringify([cover.variants]) : '[]',\n category_id: article.category || '',\n orignal: 0,\n user_original: 0,\n music: '',\n activity: '',\n apply_olympic_flag: 0,\n apply_push_flag: 0,\n apply_reward_flag: 0,\n reward_flag: 0,\n survey_id: '',\n survey_name: '',\n source: '0',\n sub_source: '0',\n needpub: 1,\n mediaId: this.userInfo ? this.userId(this.userInfo) : '',\n }\n\n const saveRes = await this.callPublishService<TencentApiResponse<TencentPublishData>>('save', payload)\n logger.debug('save response:', saveRes)\n if (!this.isOk(saveRes)) {\n throw new Error(this.errorMessage(saveRes, '腾讯号保存失败'))\n }\n\n const postId = this.stringifyId(saveRes.data?.articleId || saveRes.data?.articleid || saveRes.data?.article_id || saveRes.data?.id)\n if (!postId) {\n throw new Error('腾讯号保存接口未返回文章 ID')\n }\n\n const publishRes = await this.callPublishService<TencentApiResponse<TencentPublishData>>('publish', {\n ...payload,\n articleId: postId,\n })\n logger.debug('publish response:', publishRes)\n if (!this.isOk(publishRes)) {\n throw new Error(this.errorMessage(publishRes, '腾讯号发布失败'))\n }\n\n return this.createResult(true, {\n postId,\n postUrl: publishRes.data?.articleUrl || publishRes.data?.url,\n statusData: {\n title: article.title,\n cover: cover?.url || '',\n },\n })\n }).catch((error) => this.createResult(false, {\n error: (error as Error).message,\n }))\n }\n\n async getStatus(statusRef: PublishStatusRef): Promise<PublishStatusResult> {\n const articleId = statusRef.id\n if (!articleId) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: '腾讯号 statusRef 缺少文章 ID',\n checkedAt: Date.now(),\n }\n }\n\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n for (let page = 1; page <= 5; page++) {\n const url = new URL('https://om.qq.com/marticle/article/list')\n url.searchParams.set('page', String(page))\n url.searchParams.set('index', String(page))\n url.searchParams.set('limit', '20')\n url.searchParams.set('type', '0')\n url.searchParams.set('category', 'all')\n url.searchParams.set('relogin', '1')\n\n const response = await this.runtime.fetch(url.toString(), {\n method: 'GET',\n credentials: 'include',\n headers: { Accept: 'application/json, text/javascript, */*; q=0.01' },\n })\n if (!response.ok) continue\n\n const res = await response.json() as TencentApiResponse<TencentListData>\n const list = res.data?.articles || res.data?.list || []\n const item = list.find(row => this.stringifyId(row.article_id || row.articleId || row.articleid || row.id) === articleId)\n if (item) return this.mapArticleStatus(item)\n }\n\n return {\n platform: this.meta.id,\n state: 'not_found',\n message: '腾讯号文章列表未找到该文章',\n checkedAt: Date.now(),\n }\n })\n }\n\n protected async uploadImageByUrl(src: string): Promise<TencentImageUploadResult> {\n return this.uploadImageFileByUrl(src, {\n endpoint: 'https://image.om.qq.com/cpom_pimage/ContentImageUploadViaFile',\n opCode: '151',\n })\n }\n\n private async uploadCoverByUrl(src: string): Promise<TencentImageUploadResult> {\n return this.uploadImageFileByUrl(src, {\n endpoint: 'https://image.om.qq.com/cpom_pimage/ListImageUploadViaFile',\n opCode: '157',\n })\n }\n\n private async uploadImageFileByUrl(\n src: string,\n config: { endpoint: string; opCode: string },\n ): Promise<TencentImageUploadResult> {\n const imageResponse = await fetch(src)\n if (!imageResponse.ok) {\n throw new Error('图片下载失败: ' + src)\n }\n const imageBlob = await imageResponse.blob()\n const formData = new FormData()\n formData.append('appid', 'LA6zXi1lWzAioIzdiAD6iM10aHarlHF6')\n formData.append('isUpOrg', '1')\n formData.append('endpoint', '1')\n formData.append('isRetImgAttr', '1')\n formData.append('opCode', config.opCode)\n formData.append('relogin', '1')\n formData.append('file', imageBlob, 'image.jpg')\n\n const response = await this.runtime.fetch(\n config.endpoint,\n {\n method: 'POST',\n credentials: 'include',\n body: formData,\n },\n )\n const res = await response.json() as TencentApiResponse<{\n url?: {\n url?: string\n width?: string | number\n height?: string | number\n size?: Record<string, { imgurl?: string; imageUrl?: string; width?: string | number; height?: string | number }>\n [key: string]: unknown\n }\n }>\n logger.debug('image upload response:', res)\n\n if (!this.isOk(res)) {\n throw new Error(this.errorMessage(res, '腾讯号图片上传失败'))\n }\n\n const raw = res.data?.url\n const sized = raw?.size?.['641'] || raw?.size?.['640'] || raw?.size?.['0']\n const url = this.pickImageUrl(sized) || this.pickImageUrl(raw) || this.pickImageUrl(raw?.['640360']) || this.pickImageUrl(raw?.['1'])\n if (!url) throw new Error('腾讯号图片上传响应缺少 URL')\n\n const variants = raw && !raw.size\n ? this.toStringRecord(raw)\n : undefined\n\n return {\n url,\n variants,\n attrs: {\n width: String(sized?.width || raw?.width || ''),\n height: String(sized?.height || raw?.height || ''),\n 'data-widget': 'image',\n },\n }\n }\n\n private async prepareArticleContent(article: Article, options?: PublishOptions): Promise<{\n content: string\n pureText: string\n }> {\n let html = article.html || markdownToHtml(article.markdown)\n html = await this.processImages(html, async (src) => {\n const uploaded = await this.uploadImageByUrl(src)\n return uploaded\n }, {\n skipPatterns: ['om.qq.com', 'qpic.cn', 'gtimg.cn'],\n onProgress: options?.onImageProgress,\n })\n\n return {\n content: html,\n pureText: this.textFromHtml(html),\n }\n }\n\n private async callPublishService<T>(method: 'save' | 'publish', payload: Record<string, unknown>): Promise<T> {\n const tabId = await this.ensureTencentTab()\n const result = await this.runtime.tabs!.executeScript<\n { success: boolean; data?: T; error?: string },\n ['save' | 'publish', Record<string, unknown>]\n >(tabId, async (serviceMethod, requestPayload) => {\n try {\n let req: ((id: number) => { publishService?: Record<string, (payload: Record<string, unknown>) => Promise<T>> }) | undefined\n const chunk = (window as typeof window & {\n webpackChunkom_mixin_main?: { push: (args: unknown[]) => void }\n }).webpackChunkom_mixin_main\n chunk?.push([[Math.floor(Math.random() * 1000000000)], {}, (runtimeRequire: typeof req) => { req = runtimeRequire }])\n const publishService = req?.(92490)?.publishService\n const fn = publishService?.[serviceMethod]\n if (!fn) throw new Error('腾讯号前端 publishService 不可用')\n return { success: true, data: await fn(requestPayload) }\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) }\n }\n }, [method, payload])\n\n if (!result.success || !result.data) {\n throw new Error(result.error || '腾讯号页面上下文请求失败')\n }\n return result.data\n }\n\n private async ensureTencentTab(): Promise<number> {\n if (!this.runtime.tabs) {\n throw new Error('当前 runtime 不支持页面上下文请求')\n }\n\n const existing = await this.runtime.tabs.query('*://om.qq.com/*')\n if (existing[0]?.id) return existing[0].id\n\n const tab = await this.runtime.tabs.create(this.meta.homepage, false)\n await this.runtime.tabs.waitForLoad(tab.id, 30000)\n return tab.id\n }\n\n private mapArticleStatus(item: TencentListItem): PublishStatusResult {\n const checkedAt = Date.now()\n const rawStatus = String(item.status ?? item.auditStatus ?? item.articleStatus ?? '')\n const message = item.reject_reason_msg || item.reject_reason || item.standard_reject_reason || item.statusDesc || item.status_desc || item.rejectReason || item.reason || item.revisableReason\n const postUrl = item.articleUrl || item.article_url || item.url\n\n if (rawStatus === '1') {\n return {\n platform: this.meta.id,\n state: 'published',\n postUrl,\n message: message || '腾讯号文章状态: 已发布',\n checkedAt,\n }\n }\n if (rawStatus === '3') {\n return {\n platform: this.meta.id,\n state: 'rejected',\n message: message || `腾讯号文章状态: ${rawStatus}`,\n checkedAt,\n }\n }\n if (['2', '4', '5', '6', '7', '10', '12'].includes(rawStatus)) {\n return {\n platform: this.meta.id,\n state: 'reviewing',\n message: message || `腾讯号文章状态: ${rawStatus}`,\n checkedAt,\n }\n }\n\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: message || `腾讯号文章状态未知: ${rawStatus || 'empty'}`,\n checkedAt,\n }\n }\n\n private isOk(res: TencentApiResponse): boolean {\n const code = res.response?.code ?? res.code\n return code === 0\n }\n\n private errorMessage(res: TencentApiResponse, fallback: string): string {\n return res.response?.msg || res.response?.message || res.msg || res.message || fallback\n }\n\n private pickImageUrl(value: unknown): string {\n if (!value) return ''\n if (typeof value === 'string') return value\n if (typeof value !== 'object') return ''\n const row = value as { imgurl?: unknown; imageUrl?: unknown; url?: unknown }\n return this.pickImageUrl(row.imgurl) || this.pickImageUrl(row.imageUrl) || this.pickImageUrl(row.url)\n }\n\n private toStringRecord(value: Record<string, unknown>): Record<string, string> {\n const result: Record<string, string> = {}\n for (const [key, raw] of Object.entries(value)) {\n if (typeof raw === 'string') result[key] = raw\n }\n return result\n }\n\n private stringifyId(value: string | number | undefined): string {\n return value === undefined ? '' : String(value)\n }\n\n private userId(info: TencentUserInfo): string {\n return this.stringifyId(info.mediaId || info.mediaid || info.id)\n }\n\n private textFromHtml(html: string): string {\n return html\n .replace(/<br\\s*\\/?>/gi, '\\n')\n .replace(/<\\/(p|div|li|tr|h[1-6])>/gi, '\\n')\n .replace(/<[^>]+>/g, '')\n .replace(/ /g, ' ')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/&/g, '&')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim()\n }\n}\n","/**\n * 今日头条适配器\n */\nimport { CodeAdapter, type ImageUploadResult } from '../code-adapter'\nimport type {\n Article,\n AuthResult,\n PlatformMeta,\n PublishStatusRef,\n PublishStatusResult,\n SyncResult,\n} from '../../types'\nimport type { PublishOptions } from '../types'\nimport { markdownToHtml } from '../../lib/turndown'\nimport { createLogger } from '../../lib/logger'\n\nconst logger = createLogger('Toutiao')\n\ninterface ToutiaoUser {\n id?: string | number\n screen_name?: string\n name?: string\n https_avatar_url?: string\n avatar_url?: string\n}\n\ninterface ToutiaoApiResponse<T = unknown> {\n code?: number\n err_no?: number\n message?: string\n err_msg?: string\n data?: T\n}\n\ninterface ToutiaoPublishData {\n pgc_id?: string | number\n group_id?: string | number\n item_id?: string | number\n article_url?: string\n url?: string\n}\n\ninterface ToutiaoImageData {\n image_uri?: string\n image_url?: string\n image_width?: number\n image_height?: number\n}\n\ninterface ToutiaoManagedItem {\n id?: string | number\n pgc_id?: string | number\n pgcId?: string | number\n gid?: string | number\n Gid?: string | number\n group_id?: string | number\n item_id?: string | number\n itemId?: string | number\n ItemId?: string | number\n title?: string\n Title?: string\n status?: number | string\n Status?: number | string\n pgcStatus?: number | string\n statusDesc?: string\n status_desc?: string\n StatusDesc?: string\n reason?: string\n VerifyReason?: string\n message?: string\n articleUrl?: string\n article_url?: string\n ArticleUrl?: string\n url?: string\n ActionUrls?: Record<string, {\n Share?: string\n ClickCell?: string\n Edit?: string\n }>\n isPassed?: boolean\n wasRecommended?: number\n article_attr?: {\n gid?: string | number\n Gid?: string | number\n pgcId?: string | number\n pgc_id?: string | number\n ItemId?: string | number\n status?: number | string\n Status?: number | string\n status_desc?: string\n StatusDesc?: string\n title?: string\n Title?: string\n VerifyReason?: string\n ActionUrls?: Record<string, {\n Share?: string\n ClickCell?: string\n Edit?: string\n }>\n }\n articleDTO?: {\n pgcId?: string | number\n gid?: string | number\n status?: number | string\n pgcStatus?: number | string\n statusDesc?: string\n articleUrl?: string\n title?: string\n }\n}\n\ninterface ToutiaoListResponse extends ToutiaoApiResponse {\n data?: {\n list?: ToutiaoManagedItem[]\n article_list?: ToutiaoManagedItem[]\n items?: ToutiaoManagedItem[]\n } | ToutiaoManagedItem[] | ToutiaoFeedRow[]\n list?: ToutiaoManagedItem[]\n errno?: number\n has_more?: boolean\n api_base_info?: {\n app_extra_params?: string\n }\n}\n\ninterface ToutiaoFeedRow {\n content?: string\n assembleCell?: {\n itemCell?: {\n extra?: {\n origin_content?: string\n }\n }\n }\n}\n\nexport class ToutiaoAdapter extends CodeAdapter {\n readonly meta: PlatformMeta = {\n id: 'toutiao',\n name: '今日头条',\n icon: 'https://sf1-cdn-tos.toutiaostatic.com/obj/ttfe/pgcfe/sz/mp_logo.png',\n homepage: 'https://mp.toutiao.com/profile_v4/graphic/publish',\n capabilities: ['article', 'image_upload', 'cover'],\n }\n\n readonly preprocessConfig = {\n outputFormat: 'html' as const,\n removeLinks: true,\n removeIframes: true,\n removeSvgImages: true,\n }\n\n private readonly HEADER_RULES = [\n {\n urlFilter: '*://mp.toutiao.com/*',\n headers: {\n Origin: 'https://mp.toutiao.com',\n Referer: 'https://mp.toutiao.com/profile_v4/graphic/publish',\n },\n resourceTypes: ['xmlhttprequest'],\n },\n ]\n\n async checkAuth(): Promise<AuthResult> {\n try {\n const res = await this.get<ToutiaoApiResponse<{ user?: ToutiaoUser }>>(\n 'https://mp.toutiao.com/mp/agw/media/get_media_info',\n )\n const user = res.data?.user\n if (!user?.id) return { isAuthenticated: false, error: res.message || res.err_msg }\n\n return {\n isAuthenticated: true,\n userId: String(user.id),\n username: user.screen_name || user.name,\n avatar: user.https_avatar_url || user.avatar_url,\n }\n } catch (error) {\n logger.debug('checkAuth: not logged in -', error)\n return { isAuthenticated: false, error: (error as Error).message }\n }\n }\n\n async publish(article: Article, options?: PublishOptions): Promise<SyncResult> {\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n const auth = await this.checkAuth()\n if (!auth.isAuthenticated) {\n throw new Error('请先登录今日头条')\n }\n\n let content = this.prepareContent(article.html || markdownToHtml(article.markdown))\n content = await this.processImages(\n content,\n (src) => this.uploadImageByUrl(src),\n {\n skipPatterns: ['pstatp.com', 'toutiao.com', 'toutiaostatic.com', 'byteimg.com'],\n onProgress: options?.onImageProgress,\n },\n )\n content = this.wrapImages(content)\n\n const cover = article.cover ? await this.uploadImageByUrl(article.cover) : null\n const pgcFeedCovers = cover ? JSON.stringify([this.toCoverPayload(cover)]) : '[]'\n const titleId = `${Date.now()}_${Math.random().toString().slice(2, 18)}`\n const payload = new URLSearchParams({\n pgc_id: '0',\n source: '29',\n extra: JSON.stringify({\n content_source: 100000000402,\n content_word_cnt: this.textLength(content),\n }),\n article_type: '0',\n content,\n title: article.title,\n search_creation_info: JSON.stringify({ searchTopOne: 0, abstract: article.summary || '', clue_id: '' }),\n title_id: titleId,\n mp_editor_stat: '{}',\n is_refute_rumor: '0',\n save: '1',\n entrance: 'main',\n timer_status: '0',\n timer_time: '',\n pgc_feed_covers: pgcFeedCovers,\n article_ad_type: '2',\n })\n\n const res = await this.publishInPage(\n 'https://mp.toutiao.com/mp/agw/article/publish?source=mp&type=article&aid=1231',\n payload.toString(),\n )\n logger.debug('publish response:', res)\n\n if ((res.err_no ?? res.code ?? 0) !== 0 || !res.data?.pgc_id) {\n throw new Error(res.message || res.err_msg || '今日头条发布失败')\n }\n\n const postId = String(res.data.pgc_id)\n return this.createResult(true, {\n postId,\n postUrl: res.data.article_url || res.data.url || `https://www.toutiao.com/item/${postId}/`,\n statusData: {\n title: article.title,\n userId: auth.userId || null,\n },\n })\n }).catch((error) => this.createResult(false, {\n error: (error as Error).message,\n }))\n }\n\n async getStatus(statusRef: PublishStatusRef): Promise<PublishStatusResult> {\n if (!statusRef.id) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: '今日头条 statusRef 缺少文章 ID',\n checkedAt: Date.now(),\n }\n }\n\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n const item = await this.findManagedArticle(statusRef.id!, this.getTitle(statusRef))\n if (!item) {\n return {\n platform: this.meta.id,\n state: 'not_found',\n message: '今日头条内容管理列表未找到该文章',\n checkedAt: Date.now(),\n }\n }\n\n return this.mapManagedStatus(item)\n })\n }\n\n protected async uploadImageByUrl(src: string): Promise<ImageUploadResult> {\n const imageResponse = await fetch(src)\n if (!imageResponse.ok) {\n throw new Error('图片下载失败: ' + src)\n }\n const imageBlob = await imageResponse.blob()\n const csrfToken = await this.getCsrfToken()\n const formData = new FormData()\n formData.append('image', imageBlob, 'image.jpg')\n\n const response = await this.runtime.fetch(\n 'https://mp.toutiao.com/spice/image?upload_source=20020002&aid=1231&device_platform=web',\n {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'x-secsdk-csrf-token': csrfToken,\n },\n body: formData,\n },\n )\n const res = await response.json() as ToutiaoApiResponse<ToutiaoImageData>\n logger.debug('image upload response:', res)\n\n if ((res.code ?? 0) !== 0 || !res.data?.image_url || !res.data.image_uri) {\n throw new Error(res.message || res.err_msg || '今日头条图片上传失败')\n }\n\n return {\n url: res.data.image_url,\n attrs: {\n 'web_uri': res.data.image_uri,\n 'origin_web_uri': res.data.image_uri,\n 'img_width': String(res.data.image_width || 0),\n 'img_height': String(res.data.image_height || 0),\n 'data-width': String(res.data.image_width || 0),\n 'data-height': String(res.data.image_height || 0),\n },\n }\n }\n\n private async getCsrfToken(): Promise<string> {\n const response = await this.runtime.fetch('https://mp.toutiao.com/ttwid/check/', {\n method: 'HEAD',\n credentials: 'include',\n headers: {\n 'x-secsdk-csrf-request': '1',\n 'x-secsdk-csrf-version': '1.2.22',\n },\n })\n const token = response.headers.get('x-ware-csrf-token') || ''\n return token.includes(',') ? token.split(',')[1] || token : token\n }\n\n private async publishInPage(url: string, body: string): Promise<ToutiaoApiResponse<ToutiaoPublishData>> {\n const tabId = await this.ensureToutiaoTab()\n const result = await this.runtime.tabs!.executeScript<\n { success: boolean; data?: ToutiaoApiResponse<ToutiaoPublishData>; error?: string },\n [string, string]\n >(tabId, async (fetchUrl, fetchBody) => {\n try {\n const response = await fetch(fetchUrl, {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: fetchBody,\n })\n return { success: true, data: await response.json() }\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) }\n }\n }, [url, body])\n\n if (!result.success || !result.data) {\n throw new Error(result.error || '今日头条页面上下文发布请求失败')\n }\n return result.data\n }\n\n private async ensureToutiaoTab(): Promise<number> {\n if (!this.runtime.tabs) {\n throw new Error('当前 runtime 不支持页面上下文请求')\n }\n\n const existing = await this.runtime.tabs.query('*://mp.toutiao.com/*')\n if (existing[0]?.id) return existing[0].id\n\n const tab = await this.runtime.tabs.create(this.meta.homepage, false)\n await this.runtime.tabs.waitForLoad(tab.id, 30000)\n return tab.id\n }\n\n private async findManagedArticle(id: string, title: string): Promise<ToutiaoManagedItem | null> {\n const tabId = await this.ensureToutiaoManageTab()\n const userId = await this.getVisitedUserId(tabId)\n const pages = [1, 2, 3]\n\n for (const page of pages) {\n const url = this.buildManagedListUrl(userId, page)\n const response = await this.runtime.fetch(url, {\n method: 'GET',\n credentials: 'include',\n headers: {\n Accept: 'application/json, text/plain, */*',\n 'RPC-PERSIST-BYTETIM_BUSINESS_STREAM_CALLER': 'mp',\n },\n })\n if (!response.ok) continue\n\n const res = await response.json() as ToutiaoListResponse\n const list = this.extractList(res)\n const match = list.find((item) => this.itemMatches(item, id, title))\n if (match) return match\n }\n\n return null\n }\n\n private extractList(res: ToutiaoListResponse): ToutiaoManagedItem[] {\n if (Array.isArray(res.data)) return res.data.map((item) => this.parseManagedRow(item)).filter(Boolean) as ToutiaoManagedItem[]\n return res.data?.list || res.data?.article_list || res.data?.items || res.list || []\n }\n\n private parseManagedRow(row: ToutiaoManagedItem | ToutiaoFeedRow): ToutiaoManagedItem | null {\n const direct = row as ToutiaoManagedItem\n if (direct.title || direct.Title || direct.gid || direct.Gid || direct.article_attr) return direct\n\n const feedRow = row as ToutiaoFeedRow\n const raw = feedRow.content || feedRow.assembleCell?.itemCell?.extra?.origin_content || ''\n if (!raw) return null\n\n try {\n const parsed = JSON.parse(raw) as { ArticleAttr?: ToutiaoManagedItem; article_attr?: ToutiaoManagedItem }\n const articleAttr = parsed.ArticleAttr || parsed.article_attr\n return articleAttr ? { ...articleAttr, article_attr: articleAttr } : null\n } catch {\n return null\n }\n }\n\n private itemMatches(item: ToutiaoManagedItem, id: string, title: string): boolean {\n const ids = [\n item.id,\n item.pgc_id,\n item.pgcId,\n item.gid,\n item.Gid,\n item.group_id,\n item.item_id,\n item.itemId,\n item.ItemId,\n item.article_attr?.gid,\n item.article_attr?.Gid,\n item.article_attr?.pgcId,\n item.article_attr?.pgc_id,\n item.article_attr?.ItemId,\n item.articleDTO?.pgcId,\n item.articleDTO?.gid,\n ].filter(value => value !== undefined && value !== null).map(String)\n if (ids.includes(id)) return true\n const itemTitle = item.title || item.Title || item.article_attr?.title || item.article_attr?.Title || item.articleDTO?.title || ''\n return Boolean(title && itemTitle === title)\n }\n\n private mapManagedStatus(item: ToutiaoManagedItem): PublishStatusResult {\n const checkedAt = Date.now()\n const status = Number(item.status ?? item.Status ?? item.pgcStatus ?? item.article_attr?.status ?? item.article_attr?.Status ?? item.articleDTO?.status ?? item.articleDTO?.pgcStatus)\n const message = item.statusDesc || item.StatusDesc || item.status_desc || item.article_attr?.status_desc || item.article_attr?.StatusDesc || item.articleDTO?.statusDesc || item.reason || item.VerifyReason || item.article_attr?.VerifyReason || item.message\n const postUrl = this.resolvePostUrl(item)\n\n if (status === 2 || item.isPassed || postUrl) {\n if (!postUrl) {\n return {\n platform: this.meta.id,\n state: 'reviewing',\n message: '今日头条管理端已通过,但公开链接尚未出现在官方列表数据中,继续轮询',\n checkedAt,\n }\n }\n return {\n platform: this.meta.id,\n state: 'published',\n postUrl,\n message: message || '今日头条文章状态: 已发布',\n checkedAt,\n }\n }\n\n if (status === 1 || status === 11) {\n return {\n platform: this.meta.id,\n state: 'reviewing',\n message: message || '今日头条文章状态: 审核中',\n checkedAt,\n }\n }\n\n if (status === 3 || status === 4) {\n return {\n platform: this.meta.id,\n state: 'rejected',\n message: message || '今日头条文章状态: 未通过',\n checkedAt,\n }\n }\n\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: message || `今日头条文章状态未知: ${Number.isFinite(status) ? status : 'empty'}`,\n checkedAt,\n }\n }\n\n private async ensureToutiaoManageTab(): Promise<number> {\n if (!this.runtime.tabs) {\n throw new Error('当前 runtime 不支持页面上下文请求')\n }\n\n const existing = await this.runtime.tabs.query('*://mp.toutiao.com/profile_v4/manage/content/all*')\n if (existing[0]?.id) return existing[0].id\n\n const tab = await this.runtime.tabs.create('https://mp.toutiao.com/profile_v4/manage/content/all', false)\n await this.runtime.tabs.waitForLoad(tab.id, 30000)\n return tab.id\n }\n\n private async getVisitedUserId(tabId: number): Promise<string> {\n try {\n const id = await this.runtime.tabs!.executeScript<string, []>(tabId, () => {\n const maybeWindow = window as typeof window & {\n Garr?: {\n pgc_info?: {\n user?: {\n id_str?: string\n id?: string | number\n }\n }\n }\n }\n return String(maybeWindow.Garr?.pgc_info?.user?.id_str || maybeWindow.Garr?.pgc_info?.user?.id || '')\n }, [])\n if (id) return id\n } catch {\n // The content list endpoint still works with the authenticated user id omitted.\n }\n\n const auth = await this.checkAuth()\n return auth.userId || ''\n }\n\n private buildManagedListUrl(userId: string, page: number): string {\n const url = new URL('https://mp.toutiao.com/api/feed/mp_provider/v1/')\n const pageSize = 10\n const params: Record<string, string | number> = {\n provider_type: 'mp_provider',\n aid: '13',\n app_name: 'news_article',\n category: 'mp_all',\n channel: '',\n stream_api_version: 88,\n genre_type_switch: JSON.stringify({\n repost: 1,\n small_video: 1,\n toutiao_graphic: 1,\n weitoutiao: 1,\n xigua_video: 1,\n }),\n device_platform: 'pc',\n platform_id: '0',\n visited_uid: userId,\n offset: (page - 1) * pageSize,\n count: pageSize,\n keyword: '',\n client_extra_params: JSON.stringify({\n category: 'mp_all',\n real_app_id: '1231',\n need_forward: 'true',\n offset_mode: '1',\n page_index: String(page),\n status: '8',\n source: '0',\n }),\n app_id: '1231',\n }\n for (const [key, value] of Object.entries(params)) url.searchParams.set(key, String(value))\n return url.toString()\n }\n\n private resolvePostUrl(item: ToutiaoManagedItem): string | undefined {\n const rawUrl = item.articleUrl || item.ArticleUrl || item.article_url || item.url || item.articleDTO?.articleUrl\n || item.ActionUrls?.['2']?.Share\n || item.ActionUrls?.['2']?.ClickCell\n || item.article_attr?.ActionUrls?.['2']?.Share\n || item.article_attr?.ActionUrls?.['2']?.ClickCell\n if (rawUrl?.startsWith('https://www.toutiao.com/')) return rawUrl\n\n const id = String(item.gid || item.Gid || item.ItemId || item.itemId || item.item_id || item.article_attr?.Gid || item.article_attr?.ItemId || '')\n return id ? `https://www.toutiao.com/item/${id}/` : undefined\n }\n\n private prepareContent(html: string): string {\n return html\n .replace(/<a\\b[^>]*>([\\s\\S]*?)<\\/a>/gi, '$1')\n .replace(/<iframe\\b[\\s\\S]*?<\\/iframe>/gi, '')\n .replace(/<qqmusic\\b[\\s\\S]*?<\\/qqmusic>/gi, '')\n .replace(/<img\\b[^>]*src=([\"'])[^\"']*\\.svg[^\"']*\\1[^>]*>/gi, '')\n .replace(/\\sdata-reader-unique-id=([\"']).*?\\1/gi, '')\n .replace(/<figure[^>]*>\\s*<\\/figure>/gi, '')\n .replace(/\\n{3,}/g, '\\n\\n')\n }\n\n private wrapImages(html: string): string {\n return html.replace(\n /<img\\b([^>]*)>/gi,\n '<div class=\"pgc-img\"><img$1><p class=\"pgc-img-caption\"></p></div>',\n )\n }\n\n private toCoverPayload(cover: ImageUploadResult): Record<string, string | number> {\n const uri = String(cover.attrs?.origin_web_uri || cover.attrs?.web_uri || '')\n return {\n id: 0,\n url: cover.url,\n uri,\n origin_uri: uri,\n ic_uri: '',\n thumb_width: Number(cover.attrs?.img_width || cover.attrs?.['data-width'] || 0),\n thumb_height: Number(cover.attrs?.img_height || cover.attrs?.['data-height'] || 0),\n }\n }\n\n private textLength(html: string): number {\n return html.replace(/<[^>]+>/g, '').length\n }\n\n private getTitle(statusRef: PublishStatusRef): string {\n return typeof statusRef.data?.title === 'string' ? statusRef.data.title : ''\n }\n}\n","/**\n * 微信公众号适配器\n */\nimport { CodeAdapter, type ImageUploadResult } from '../code-adapter'\nimport type { Article, AuthResult, PublishStatusRef, PublishStatusResult, SyncResult, PlatformMeta } from '../../types'\nimport type { PublishOptions } from '../types'\nimport { createLogger } from '../../lib/logger'\n\nconst logger = createLogger('Weixin')\n\ninterface WeixinMeta {\n token: string\n userName: string\n nickName: string\n ticket: string\n svrTime: number\n avatar: string\n serviceType?: string\n}\n\ninterface WeixinImageUploadResult extends ImageUploadResult {\n fileId?: string\n width?: number\n height?: number\n}\n\ninterface WeixinPublishData {\n base_resp?: { ret: number; err_msg?: string }\n operation_seq?: string | number\n scene_replace?: string\n client_time_diff?: string | number\n strategy_info?: string | Record<string, unknown>\n third_status?: string | number\n bind_mail?: string\n}\n\ninterface WeixinPreflightResult {\n directSend?: boolean\n list?: string\n reprintConfirm?: string\n}\n\ninterface WeixinSafeVerifyResult {\n code?: string\n isNeedCode?: string\n}\n\n// 微信公众号的默认 CSS 样式\nconst WEIXIN_CSS = `\np {\n color: rgb(51, 51, 51);\n font-size: 15px;\n line-height: 1.75em;\n margin: 0 0 1em 0;\n}\nh1, h2, h3, h4, h5, h6 {\n font-weight: bold;\n}\nh1 { font-size: 1.25em; line-height: 1.4em; margin: 1em 0 0.5em 0; }\nh2 { font-size: 1.125em; margin: 1em 0 0.5em 0; }\nh3 { font-size: 1.05em; margin: 0.8em 0 0.4em 0; }\nh4, h5, h6 { font-size: 1em; margin: 0.8em 0 0.4em 0; }\nli p { margin: 0; }\nul, ol { margin: 1em 0; padding-left: 2em; }\nli { margin-bottom: 0.4em; }\npre, tt, code, kbd, samp { font-family: monospace; }\npre { white-space: pre; margin: 1em 0; }\nblockquote { border-left: 4px solid #ddd; padding-left: 1em; margin: 1em 0; color: #666; }\nhr { border: none; border-top: 1px solid #ddd; margin: 1.5em 0; }\ni, cite, em, var, address { font-style: italic; }\nb, strong { font-weight: bolder; }\n`\n\nconst WEIXIN_STYLE_RULES = parseWeixinCss(WEIXIN_CSS)\n\nfunction parseWeixinCss(css: string): Array<[string, string]> {\n const rules: Array<[string, string]> = []\n css.replace(/([^{}]+)\\{([^{}]+)\\}/g, (_match, selector: string, body: string) => {\n const style = body.replace(/\\s+/g, ' ').trim()\n if (style) rules.push([selector.trim(), style])\n return ''\n })\n return rules\n}\n\nexport class WeixinAdapter extends CodeAdapter {\n readonly meta: PlatformMeta = {\n id: 'weixin',\n name: '微信公众号',\n icon: 'https://mp.weixin.qq.com/favicon.ico',\n homepage: 'https://mp.weixin.qq.com',\n capabilities: ['article', 'image_upload'],\n }\n\n /** 预处理配置: 微信公众号使用 HTML 格式,移除非微信域名链接,压缩标签间空白避免 ProseMirror 产生空节点 */\n readonly preprocessConfig = {\n outputFormat: 'html' as const,\n removeLinks: true,\n keepLinkDomains: ['mp.weixin.qq.com', 'weixin.qq.com'],\n compactHtml: true,\n }\n\n private weixinMeta: WeixinMeta | null = null\n private authUrl = 'https://mp.weixin.qq.com/'\n\n /** 微信公众号 API 需要的 Header 规则 */\n private readonly HEADER_RULES = [\n {\n urlFilter: '*://mp.weixin.qq.com/*',\n headers: {\n 'Origin': 'https://mp.weixin.qq.com',\n 'Referer': 'https://mp.weixin.qq.com/',\n },\n resourceTypes: ['xmlhttprequest'],\n },\n ]\n\n async checkAuth(): Promise<AuthResult> {\n try {\n return await this.loadAuthFromUrl('https://mp.weixin.qq.com/')\n } catch (error) {\n logger.debug('checkAuth: not logged in -', error)\n return { isAuthenticated: false, error: (error as Error).message }\n }\n }\n\n async getStatus(statusRef: PublishStatusRef): Promise<PublishStatusResult> {\n const auth = await this.checkAuth()\n if (!auth.isAuthenticated || !this.weixinMeta?.token) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: auth.error || '微信公众号未登录,无法查询状态',\n checkedAt: Date.now(),\n }\n }\n\n if (!statusRef.id) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: '微信公众号 statusRef 缺少 appmsg id',\n checkedAt: Date.now(),\n }\n }\n\n const res = await this.get<{\n base_resp?: { ret: number; err_msg?: string }\n publish_page?: string\n publish_page_noencode?: string\n }>(\n `https://mp.weixin.qq.com/cgi-bin/appmsgpublish?sub=list&begin=0&count=10&f=json&token=${this.weixinMeta.token}&lang=zh_CN`,\n )\n\n if (this.getRet(res) !== 0) {\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: res.base_resp?.err_msg || '微信公众号状态列表接口返回异常',\n checkedAt: Date.now(),\n }\n }\n\n const publishPage = this.parseJson<{ publish_list?: Array<{ publish_info?: string }> }>(\n res.publish_page_noencode || res.publish_page || '',\n )\n for (const item of publishPage?.publish_list || []) {\n const info = this.parseJson<{\n copy_appmsg_id?: string | number\n sent_result?: { msg_status?: string | number }\n publish_info?: { publish_status?: string | number }\n appmsg_info?: Array<{ content_url?: string }>\n }>(item.publish_info || '')\n if (!info || String(info.copy_appmsg_id) !== String(statusRef.id)) continue\n\n const msgStatus = Number(info.sent_result?.msg_status)\n const publishStatus = Number(info.publish_info?.publish_status)\n if (publishStatus === 200 || [12, 13, 5, 6, 15].includes(msgStatus)) {\n return {\n platform: this.meta.id,\n state: 'published',\n postUrl: info.appmsg_info?.[0]?.content_url || statusRef.url,\n checkedAt: Date.now(),\n }\n }\n\n return {\n platform: this.meta.id,\n state: 'reviewing',\n message: `publish_status=${info.publish_info?.publish_status ?? 'unknown'}`,\n checkedAt: Date.now(),\n }\n }\n\n return {\n platform: this.meta.id,\n state: 'unknown',\n message: '微信公众号发表列表未找到该 appmsg id',\n checkedAt: Date.now(),\n }\n }\n\n async publish(article: Article, options?: PublishOptions): Promise<SyncResult> {\n return this.withHeaderRules(this.HEADER_RULES, async () => {\n logger.info('Starting publish...')\n\n this.authUrl = article.source?.url || 'https://mp.weixin.qq.com/'\n\n if (!this.weixinMeta) {\n this.loadTokenFromSourceUrl(article.source?.url)\n }\n\n if (!this.weixinMeta) {\n try {\n const auth = await this.checkAuth()\n if (!auth.isAuthenticated && article.source?.url) {\n await this.loadAuthFromUrl(article.source.url)\n }\n } catch (error) {\n throw this.wrapStageError('认证', error)\n }\n if (!this.weixinMeta) {\n throw new Error('请先登录微信公众号')\n }\n }\n\n // 微信到微信:使用原始 HTML,跳过所有处理\n let content = (article.source?.platform === 'weixin' && (article as any).rawHtml)\n ? (article as any).rawHtml\n : (article.html || '')\n const firstContentImage = this.extractFirstImageInfo(content)\n\n if (article.source?.platform === 'weixin') {\n logger.info('Source is WeChat, using raw HTML, skipping content processing')\n } else {\n content = this.processLatex(content)\n content = this.stripExternalLinks(content)\n let firstUploadedImage: WeixinImageUploadResult | null = null\n content = await this.processImages(\n content,\n async (src) => {\n const result = await this.uploadImageByUrl(src)\n firstUploadedImage ??= result\n return result\n },\n {\n skipPatterns: ['mmbiz.qpic.cn', 'mmbiz.qlogo.cn'],\n onProgress: options?.onImageProgress,\n }\n )\n content = this.processContent(content)\n const cover = await this.resolveCoverImage(article, firstUploadedImage, firstContentImage)\n\n return await this.createAndPublish(article, content, cover, options)\n }\n\n const cover = await this.resolveCoverImage(article, null, firstContentImage)\n return await this.createAndPublish(article, content, cover, options)\n }).catch((error) => this.createResult(false, {\n error: this.formatUnexpectedError(error),\n }))\n }\n\n private async createAndPublish(\n article: Article,\n content: string,\n cover: WeixinImageUploadResult,\n options?: PublishOptions,\n ): Promise<SyncResult> {\n const coverCropList = this.buildCoverCropList(cover)\n\n const formData = new URLSearchParams({\n token: this.weixinMeta!.token,\n lang: 'zh_CN',\n f: 'json',\n ajax: '1',\n random: String(Math.random()),\n AppMsgId: '',\n count: '1',\n data_seq: '0',\n operate_from: 'Chrome',\n isnew: '0',\n ad_video_transition0: '',\n can_reward0: '0',\n related_video0: '',\n is_video_recommend0: '-1',\n title0: article.title,\n author0: '',\n writerid0: '0',\n fileid0: cover.fileId || '',\n digest0: article.summary || '',\n auto_gen_digest0: article.summary ? '0' : '1',\n content0: content,\n sourceurl0: '',\n need_open_comment0: '1',\n only_fans_can_comment0: '0',\n cdn_url0: cover.url,\n cdn_235_1_url0: cover.url,\n cdn_16_9_url0: cover.url,\n cdn_1_1_url0: cover.url,\n cdn_3_4_url0: cover.url,\n cdn_url_back0: cover.url,\n crop_list0: coverCropList,\n music_id0: '',\n video_id0: '',\n voteid0: '',\n voteismlt0: '',\n supervoteid0: '',\n cardid0: '',\n cardquantity0: '',\n cardlimit0: '',\n vid_type0: '',\n show_cover_pic0: '0',\n shortvideofileid0: '',\n copyright_type0: '0',\n releasefirst0: '',\n platform0: '',\n reprint_permit_type0: '',\n allow_reprint0: '',\n allow_reprint_modify0: '',\n original_article_type0: '',\n ori_white_list0: '',\n free_content0: '',\n fee0: '0',\n ad_id0: '',\n guide_words0: '',\n is_share_copyright0: '0',\n share_copyright_url0: '',\n source_article_type0: '',\n reprint_recommend_title0: '',\n reprint_recommend_content0: '',\n share_page_type0: '0',\n share_imageinfo0: '{\"list\":[]}',\n share_video_id0: '',\n dot0: '{}',\n share_voice_id0: '',\n insert_ad_mode0: '',\n categories_list0: '[]',\n new_pic_process0: '1',\n })\n\n let res: {\n appMsgId?: string\n ret?: number\n base_resp?: { ret: number; err_msg?: string }\n }\n try {\n const response = await this.runtime.fetch(\n `https://mp.weixin.qq.com/cgi-bin/operate_appmsg?t=ajax-response&sub=create&type=77&token=${this.weixinMeta!.token}&lang=zh_CN`,\n {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: formData,\n }\n )\n res = await response.json() as typeof res\n } catch (error) {\n throw this.wrapStageError('保存图文', error)\n }\n\n logger.debug(' Save response:', res)\n\n if (!res.appMsgId) {\n throw new Error(this.formatStageError('保存图文', res))\n }\n\n const draftUrl = `https://mp.weixin.qq.com/cgi-bin/appmsg?t=media/appmsg_edit&action=edit&type=77&appmsgid=${res.appMsgId}&token=${this.weixinMeta!.token}&lang=zh_CN`\n await this.publishDraft(res.appMsgId, options)\n\n return this.createResult(true, {\n postId: res.appMsgId,\n postUrl: draftUrl,\n })\n }\n\n private async resolveCoverImage(\n article: Article,\n firstUploadedImage: WeixinImageUploadResult | null,\n firstContentImage: WeixinImageUploadResult | null,\n ): Promise<WeixinImageUploadResult> {\n if (article.cover) {\n return this.uploadImageByUrl(article.cover)\n }\n\n if (firstUploadedImage) {\n return firstUploadedImage\n }\n\n if (firstContentImage) {\n if (firstContentImage.fileId) {\n return firstContentImage\n }\n return this.uploadImageByUrl(firstContentImage.url)\n }\n\n throw new Error('微信公众号发布需要封面:请提供 article.cover 或在正文插入图片')\n }\n\n private extractFirstImageInfo(content: string): WeixinImageUploadResult | null {\n const match = content.match(/<img\\b[^>]*>/i)\n if (!match) return null\n\n const tag = match[0]\n const src = this.getAttr(tag, 'src') || this.getAttr(tag, 'data-src')\n if (!src) return null\n\n const width = Number(this.getAttr(tag, 'data-w') || this.getAttr(tag, 'width')) || undefined\n const ratio = Number(this.getAttr(tag, 'data-ratio')) || undefined\n\n return {\n url: this.decodeHtmlAttr(src),\n fileId: this.getAttr(tag, 'data-imgfileid') || undefined,\n width,\n height: width && ratio ? Math.round(width / ratio) : undefined,\n }\n }\n\n private getAttr(tag: string, name: string): string {\n const match = tag.match(new RegExp(`\\\\s${name}=[\"']([^\"']+)[\"']`, 'i'))\n return match?.[1] || ''\n }\n\n private decodeHtmlAttr(value: string): string {\n return value\n .replace(/&/g, '&')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/</g, '<')\n .replace(/>/g, '>')\n }\n\n private async publishDraft(appMsgId: string, options?: PublishOptions): Promise<void> {\n const token = this.weixinMeta!.token\n try {\n const check = await this.postForm<{\n base_resp?: { ret: number; err_msg?: string }\n }>(\n `https://mp.weixin.qq.com/cgi-bin/masssend?t=ajax-response&for_check=1&is_release_publish_page=1&token=${token}&lang=zh_CN`,\n { appmsgid: appMsgId },\n )\n\n if (check.base_resp?.ret !== 0) {\n throw new Error(this.formatStageError('群发检查', check))\n }\n } catch (error) {\n throw this.wrapStageError('群发检查', error)\n }\n\n const publishData = await this.loadPublishData(appMsgId)\n const preflight = await this.runPublishPreflight(appMsgId)\n await this.ensureNotInPublishQueue(appMsgId)\n const safeVerify = await this.loadSafePublishCode(publishData, options)\n\n try {\n const payload: Record<string, string> = {\n ack: '',\n code: safeVerify.code || '',\n reprint_info: '',\n reprint_confirm: preflight.reprintConfirm || '0',\n list: preflight.list || '',\n groupid: '',\n sex: '0',\n country: '',\n province: '',\n city: '',\n send_time: '0',\n type: '10',\n share_page: '1',\n synctxweibo: '0',\n operation_seq: String(publishData.operation_seq),\n scene_replace: publishData.scene_replace || '',\n req_id: this.randomId(32),\n req_time: String(this.getPublishReqTime(publishData)),\n sync_version: '1',\n isFreePublish: '1',\n appmsgid: appMsgId,\n isMulti: '1',\n }\n if (preflight.directSend) payload.direct_send = '1'\n if (safeVerify.isNeedCode) payload.isNeedCode = safeVerify.isNeedCode\n\n const res = await this.postForm<{\n base_resp?: { ret: number; err_msg?: string }\n }>(\n `https://mp.weixin.qq.com/cgi-bin/masssend?t=ajax-response&is_release_publish_page=1&token=${token}&lang=zh_CN`,\n payload,\n )\n\n const ret = res.base_resp?.ret\n if (ret !== 0 && ret !== 230000 && ret !== 230001) {\n throw new Error(this.formatStageError('发布', res))\n }\n } catch (error) {\n throw this.wrapStageError('发布', error)\n }\n }\n\n private async runPublishPreflight(appMsgId: string): Promise<WeixinPreflightResult> {\n await this.checkSameMaterial(appMsgId)\n const copyright = await this.checkCopyright(appMsgId)\n await this.checkSponsorAd(appMsgId)\n await this.checkMusic(appMsgId)\n return copyright\n }\n\n private async checkSameMaterial(appMsgId: string): Promise<void> {\n try {\n const res = await this.postForm<{\n base_resp?: { ret: number; err_msg?: string }\n }>(\n this.masssendActionUrl('check_same_material'),\n { msgid: appMsgId },\n )\n const ret = this.getRet(res)\n if (ret === 0 || ret === 67017 || ret === undefined) return\n throw new Error(this.formatStageError('相同内容检查', res))\n } catch (error) {\n throw this.wrapStageError('相同内容检查', error)\n }\n }\n\n private async checkCopyright(appMsgId: string): Promise<WeixinPreflightResult> {\n let checkTimes = 0\n const timeoutAt = Date.now() + 60_000\n\n while (Date.now() < timeoutAt) {\n checkTimes++\n let res: {\n base_resp?: { ret: number; err_msg?: string }\n list?: string\n }\n try {\n res = await this.postForm<typeof res>(\n this.masssendActionUrl('get_appmsg_copyright_stat'),\n {\n first_check: checkTimes === 1 ? '1' : '0',\n check_times: String(checkTimes),\n type: '10',\n appmsgid: appMsgId,\n },\n )\n } catch (error) {\n throw this.wrapStageError('原创校验', error)\n }\n\n const ret = this.getRet(res)\n if (ret === 154009) return { directSend: true }\n if (ret === 154008) {\n throw new Error(this.formatStageError('原创校验', res))\n }\n if (ret === 154011) {\n await this.delay(checkTimes === 1 ? 10 : 500)\n continue\n }\n if (ret === 200013) {\n throw new Error('微信公众号原创校验失败: 操作太频繁,请稍后再试')\n }\n if (ret === 64715) {\n throw new Error('微信公众号原创校验失败: 需要在页面处理原创声明后再发布')\n }\n throw new Error(this.formatStageError('原创校验', res))\n }\n\n throw new Error('微信公众号原创校验失败: 等待超时')\n }\n\n private async checkSponsorAd(appMsgId: string): Promise<void> {\n try {\n const res = await this.postForm<{\n base_resp?: { ret: number; err_msg?: string }\n check_ad_resp?: { detail_err_url?: string }\n }>(\n this.masssendActionUrl('check_ad'),\n {\n appmsg_id: appMsgId,\n is_release_publish_page: '1',\n send_time: '0',\n },\n )\n const ret = this.getRet(res)\n if (ret === 0) return\n if (ret === 67038) {\n const detail = res.check_ad_resp?.detail_err_url ? ` ${res.check_ad_resp.detail_err_url}` : ''\n throw new Error(`微信公众号广告检查失败: ${res.base_resp?.err_msg || '存在赞助广告风险'}${detail}`)\n }\n throw new Error(this.formatStageError('广告检查', res))\n } catch (error) {\n throw this.wrapStageError('广告检查', error)\n }\n }\n\n private async checkMusic(appMsgId: string): Promise<void> {\n try {\n const res = await this.postForm<{\n base_resp?: { ret: number; err_msg?: string }\n list?: unknown[]\n }>(\n this.masssendActionUrl('check_music'),\n {\n appmsgid: appMsgId,\n masssend_check: '1',\n },\n )\n const ret = this.getRet(res)\n if (ret === 0 && (!res.list || res.list.length === 0)) return\n if (ret === 0 && res.list?.length) {\n throw new Error('微信公众号音乐检查失败: 正文含有需人工处理的音乐素材')\n }\n if ([67032, 67033, 67034, 67035, 67036, 67037].includes(ret ?? 0)) {\n throw new Error(this.formatStageError('音乐检查', res))\n }\n // 微信前端对未知音乐检查错误走放行,避免系统偶发 -1 阻断纯图文发布。\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n if (message.startsWith('微信公众号音乐检查失败')) throw error\n logger.warn('Music check failed, continuing like Weixin frontend:', error)\n }\n }\n\n private async ensureNotInPublishQueue(appMsgId: string): Promise<void> {\n try {\n const res = await this.get<{\n base_resp?: { ret: number; err_msg?: string }\n publish_page?: string\n publish_page_noencode?: string\n }>(\n `https://mp.weixin.qq.com/cgi-bin/appmsgpublish?sub=list&begin=0&count=10&f=json&token=${this.weixinMeta!.token}&lang=zh_CN`,\n )\n if (this.getRet(res) !== 0) return\n\n const publishPage = this.parseJson<{ publish_list?: Array<{ publish_info?: string }> }>(\n res.publish_page_noencode || res.publish_page || '',\n )\n const activeDoneStatuses = [12, 13, 5, 6, 15]\n const ignoredPublishStatuses = [102, 103, 104, 105, 400]\n const inQueue = (publishPage?.publish_list || []).some((item) => {\n const info = this.parseJson<{\n copy_appmsg_id?: string | number\n sent_result?: { msg_status?: string | number }\n publish_info?: { publish_status?: string | number }\n }>(item.publish_info || '')\n if (!info || String(info.copy_appmsg_id) !== String(appMsgId)) return false\n const msgStatus = Number(info.sent_result?.msg_status)\n if (activeDoneStatuses.includes(msgStatus)) return false\n const publishStatus = Number(info.publish_info?.publish_status)\n if (ignoredPublishStatuses.includes(publishStatus)) return false\n return true\n })\n\n if (inQueue) {\n throw new Error('该草稿正在发表,请勿重复操作')\n }\n } catch (error) {\n throw this.wrapStageError('发布队列检查', error)\n }\n }\n\n private async loadSafePublishCode(\n data: WeixinPublishData,\n options?: PublishOptions,\n ): Promise<WeixinSafeVerifyResult> {\n const strategyInfo = this.parseStrategyInfo(data.strategy_info)\n if (!this.needsSafeScan(strategyInfo)) return {}\n if (!this.runtime.tabs?.create) {\n throw new Error('微信公众号发布需要微信安全扫码验证,但当前运行时不能打开验证二维码')\n }\n\n const token = this.weixinMeta!.token\n const ticketRes = await this.postForm<{\n base_resp?: { ret: number; err_msg?: string }\n ticket?: string\n operation_seq?: string\n }>(\n `https://mp.weixin.qq.com/misc/safeassistant?token=${token}&lang=zh_CN`,\n { action: 'get_ticket' },\n )\n if (this.getRet(ticketRes) !== 0 || !ticketRes.ticket) {\n throw new Error(this.formatStageError('安全验证', ticketRes))\n }\n\n const qrRes = await this.postForm<{\n base_resp?: { ret: number; err_msg?: string }\n uuid?: string\n }>(\n `https://mp.weixin.qq.com/safe/safeqrconnect?token=${token}&lang=zh_CN`,\n {\n state: '0',\n login_type: 'safe_center',\n f: 'json',\n type: 'json',\n ticket: ticketRes.ticket,\n },\n )\n if (!qrRes.uuid) {\n throw new Error(this.formatStageError('安全验证', qrRes))\n }\n\n const msgId = String(data.operation_seq || ticketRes.operation_seq || '')\n const qrUrl = new URL('https://mp.weixin.qq.com/safe/safeqrcode')\n qrUrl.searchParams.set('ticket', ticketRes.ticket)\n qrUrl.searchParams.set('uuid', qrRes.uuid)\n qrUrl.searchParams.set('action', 'check')\n qrUrl.searchParams.set('service_type', this.weixinMeta!.serviceType || '1')\n qrUrl.searchParams.set('type', 'msgs')\n qrUrl.searchParams.set('msgid', msgId)\n qrUrl.searchParams.set('publish_type', '1')\n\n const expiresAt = Date.now() + 180_000\n await this.emitPublishEvent(options, {\n type: 'security_check',\n platform: this.meta.id,\n message: '微信公众号需要扫码确认发布',\n url: qrUrl.toString(),\n method: 'qrcode',\n expiresAt,\n })\n await this.runtime.tabs.create(qrUrl.toString(), true)\n return { code: await this.pollSafeUuid(qrRes.uuid, expiresAt), isNeedCode: '1' }\n }\n\n private async pollSafeUuid(uuid: string, timeoutAt = Date.now() + 180_000): Promise<string> {\n const token = this.weixinMeta!.token\n while (Date.now() < timeoutAt) {\n await this.delay(1200)\n const res = await this.postForm<{\n errcode?: number | string\n check_status?: number | string\n code?: string\n }>(\n `https://mp.weixin.qq.com/safe/safeuuid?timespam=${Date.now()}&token=${token}&lang=zh_CN`,\n {\n uuid,\n action: 'json',\n type: 'json',\n },\n )\n\n const errcode = Number(res.errcode ?? 0)\n const checkStatus = Number(res.check_status ?? 0)\n if ((errcode === 405 || (errcode === 404 && checkStatus === 602)) && res.code) {\n return res.code\n }\n if (errcode === 407 || errcode === 408) {\n throw new Error('微信公众号安全验证失败: 已发起管理员申请,需要管理员通过后重新发布')\n }\n if (errcode === 402) {\n throw new Error('微信公众号安全验证失败: 二维码已过期,请重新发布生成二维码')\n }\n if (errcode === 403) {\n throw new Error('微信公众号安全验证失败: 扫码已取消')\n }\n }\n throw new Error('微信公众号安全验证失败: 等待扫码确认超时')\n }\n\n private async emitPublishEvent(options: PublishOptions | undefined, event: Parameters<NonNullable<PublishOptions['onEvent']>>[0]): Promise<void> {\n try {\n await options?.onEvent?.(event)\n } catch (error) {\n logger.warn('Publish event handler failed:', error)\n }\n }\n\n private needsSafeScan(strategyInfo: Record<string, unknown> | null): boolean {\n return (Number(strategyInfo?.protect_status || 0) & 2) === 2\n }\n\n private parseStrategyInfo(value: WeixinPublishData['strategy_info']): Record<string, unknown> | null {\n if (!value) return null\n if (typeof value === 'object') return value\n return this.parseJson<Record<string, unknown>>(value)\n }\n\n private parseJson<T>(value: string): T | null {\n if (!value) return null\n try {\n return JSON.parse(value) as T\n } catch {\n return null\n }\n }\n\n private masssendActionUrl(action: string): string {\n return `https://mp.weixin.qq.com/cgi-bin/masssend?action=${action}&token=${this.weixinMeta!.token}&lang=zh_CN`\n }\n\n private getRet(res: { ret?: number | string; base_resp?: { ret?: number | string } }): number | undefined {\n const ret = res.ret ?? res.base_resp?.ret\n if (ret === undefined || ret === null || ret === '') return undefined\n const value = Number(ret)\n return Number.isFinite(value) ? value : undefined\n }\n\n private async loadPublishData(appMsgId: string): Promise<WeixinPublishData> {\n const token = this.weixinMeta!.token\n let data: WeixinPublishData\n\n try {\n data = await this.get<WeixinPublishData>(\n `https://mp.weixin.qq.com/cgi-bin/masssendpage?f=json&preview_appmsgid=${encodeURIComponent(appMsgId)}&token=${token}&lang=zh_CN`,\n )\n } catch (error) {\n throw this.wrapStageError('发布准备', error)\n }\n\n if (data.base_resp?.ret !== 0) {\n throw new Error(this.formatStageError('发布准备', data))\n }\n\n if (data.operation_seq === undefined || data.operation_seq === '') {\n throw new Error(this.formatStageError('发布准备', data))\n }\n\n return data\n }\n\n private getPublishReqTime(data: WeixinPublishData): number {\n const diff = Number(data.client_time_diff ?? 0)\n if (!Number.isFinite(diff)) return Date.now()\n return Date.now() + diff * 1000\n }\n\n private async loadAuthFromUrl(url: string): Promise<AuthResult> {\n const response = await this.runtime.fetch(url, {\n method: 'GET',\n credentials: 'include',\n })\n const html = await response.text()\n\n const commonData = this.extractWxCommonData(html)\n const token = this.extractCommonDataField(commonData, 't') || this.extractTokenFromUrl(url)\n if (!token) {\n logger.debug(' No token found')\n return { isAuthenticated: false }\n }\n\n const ticket = this.extractCommonDataField(commonData, 'ticket')\n const userName = this.extractCommonDataField(commonData, 'user_name')\n const nickName = this.extractCommonDataField(commonData, 'nick_name')\n const svrTime = Number(this.extractCommonDataField(commonData, 'time')) || Date.now() / 1000\n const headImg = this.extractCommonDataField(commonData, 'head_img')\n const serviceType = this.extractCommonDataField(commonData, 'service_type')\n\n if (!userName || !ticket) {\n logger.debug(' Incomplete Weixin auth info:', { hasToken: !!token, hasUserName: !!userName, hasTicket: !!ticket })\n return {\n isAuthenticated: false,\n error: '微信公众号登录信息不完整,请打开或刷新微信公众号后台首页后重试',\n }\n }\n\n const avatarMatch = html.match(/class=\"weui-desktop-account__thumb\"[^>]*src=\"([^\"]+)\"/)\n let avatar = avatarMatch ? avatarMatch[1] : headImg\n if (avatar.startsWith('http://')) {\n avatar = avatar.replace('http://', 'https://')\n }\n\n this.weixinMeta = {\n token,\n userName,\n nickName,\n ticket,\n svrTime,\n avatar,\n serviceType,\n }\n\n logger.debug(' Auth info:', {\n userName: this.weixinMeta.userName,\n nickName: this.weixinMeta.nickName,\n hasToken: !!this.weixinMeta.token,\n })\n\n return {\n isAuthenticated: true,\n userId: this.weixinMeta.userName,\n username: this.weixinMeta.nickName,\n avatar: this.weixinMeta.avatar,\n }\n }\n\n private extractWxCommonData(html: string): string {\n return html.match(/window\\.wx\\.commonData\\s*=\\s*\\{[\\s\\S]*?\\n\\s*\\};/)?.[0] || ''\n }\n\n private extractCommonDataField(commonData: string, key: string): string {\n if (!commonData) return ''\n const match = commonData.match(new RegExp(`\\\\b${key}:\\\\s*(?:[\"']([^\"']*)[\"']|(\\\\d+))`))\n return match?.[1] || match?.[2] || ''\n }\n\n private extractTokenFromUrl(url: string): string {\n try {\n return new URL(url).searchParams.get('token') || ''\n } catch {\n return ''\n }\n }\n\n private loadTokenFromSourceUrl(url?: string): void {\n if (!url) return\n const token = new URL(url).searchParams.get('token')\n if (!token) return\n\n this.weixinMeta = {\n token,\n userName: '',\n nickName: '',\n ticket: '',\n svrTime: Date.now() / 1000,\n avatar: '',\n serviceType: undefined,\n }\n }\n\n protected async uploadImageByUrl(src: string): Promise<WeixinImageUploadResult> {\n if (!this.weixinMeta) {\n throw new Error('未登录')\n }\n if (!this.weixinMeta.userName || !this.weixinMeta.ticket) {\n await this.loadAuthFromUrl(this.authUrl)\n }\n if (!this.weixinMeta.userName || !this.weixinMeta.ticket) {\n throw new Error('微信公众号图片上传认证信息不完整,请刷新后台后重试')\n }\n\n const imageResponse = await this.runtime.fetch(src, { credentials: 'include' })\n if (!imageResponse.ok) {\n throw new Error('图片下载失败: ' + src)\n }\n const imageBlob = await imageResponse.blob()\n const imageSize = await this.getImageSize(imageBlob)\n\n const formData = new FormData()\n const timestamp = Date.now()\n const fileName = `${timestamp}.jpg`\n\n formData.append('type', imageBlob.type || 'image/jpeg')\n formData.append('id', String(timestamp))\n formData.append('name', fileName)\n formData.append('lastModifiedDate', new Date().toString())\n formData.append('size', String(imageBlob.size))\n formData.append('file', imageBlob, fileName)\n\n const { token, userName, ticket, svrTime } = this.weixinMeta\n const seq = Date.now()\n\n const response = await this.runtime.fetch(\n `https://mp.weixin.qq.com/cgi-bin/filetransfer?action=upload_material&f=json&scene=8&writetype=doublewrite&groupid=1&ticket_id=${userName}&ticket=${ticket}&svr_time=${svrTime}&token=${token}&lang=zh_CN&seq=${seq}&t=${Math.random()}`,\n {\n method: 'POST',\n credentials: 'include',\n body: formData,\n }\n )\n\n const res = await response.json() as {\n cdn_url?: string\n content?: string\n base_resp?: { err_msg: string; ret: number }\n }\n\n logger.debug(' Image upload response:', res)\n\n if (res.base_resp?.err_msg !== 'ok' || !res.cdn_url) {\n throw new Error(`图片上传失败: ${res.base_resp?.err_msg || JSON.stringify(res).slice(0, 300)} ${src}`)\n }\n\n return {\n url: res.cdn_url,\n fileId: res.content,\n width: imageSize?.width,\n height: imageSize?.height,\n }\n }\n\n private buildCoverCropList(cover: WeixinImageUploadResult): string {\n const fileId = Number(cover.fileId)\n if (!fileId || !cover.width || !cover.height) return ''\n\n const ratios = [\n ['16_9', 16 / 9],\n ['2.35_1', 2.35],\n ['1_1', 1],\n ['3_4', 3 / 4],\n ] as const\n\n const crops = ratios.map(([ratio, value]) => {\n const crop = this.centerCrop(cover.width!, cover.height!, value)\n return {\n ratio,\n x1: crop.x1,\n y1: crop.y1,\n x2: crop.x2,\n y2: crop.y2,\n file_id: fileId,\n }\n })\n\n return JSON.stringify({\n crop_list: crops,\n crop_list_percent: crops.map((crop) => ({\n ratio: crop.ratio,\n x1: crop.x1 / cover.width!,\n y1: crop.y1 / cover.height!,\n x2: crop.x2 / cover.width!,\n y2: crop.y2 / cover.height!,\n file_id: fileId,\n })),\n })\n }\n\n private centerCrop(width: number, height: number, ratio: number) {\n const currentRatio = width / height\n let cropWidth = width\n let cropHeight = height\n\n if (currentRatio > ratio) {\n cropWidth = height * ratio\n } else if (currentRatio < ratio) {\n cropHeight = width / ratio\n }\n\n const x1 = Math.max(0, Math.floor((width - cropWidth) / 2))\n const y1 = Math.max(0, Math.floor((height - cropHeight) / 2))\n const x2 = Math.min(width, Math.floor(x1 + cropWidth))\n const y2 = Math.min(height, Math.floor(y1 + cropHeight))\n\n return { x1, y1, x2, y2 }\n }\n\n private async getImageSize(blob: Blob): Promise<{ width: number; height: number } | undefined> {\n const bytes = new Uint8Array(await blob.arrayBuffer())\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)\n\n if (\n bytes.length >= 24 &&\n bytes[0] === 0x89 &&\n bytes[1] === 0x50 &&\n bytes[2] === 0x4e &&\n bytes[3] === 0x47\n ) {\n return {\n width: view.getUint32(16),\n height: view.getUint32(20),\n }\n }\n\n if (bytes.length >= 10 && bytes[0] === 0x47 && bytes[1] === 0x49 && bytes[2] === 0x46) {\n return {\n width: view.getUint16(6, true),\n height: view.getUint16(8, true),\n }\n }\n\n if (bytes.length >= 4 && bytes[0] === 0xff && bytes[1] === 0xd8) {\n let offset = 2\n while (offset + 9 < bytes.length) {\n if (bytes[offset] !== 0xff) break\n const marker = bytes[offset + 1]\n const length = view.getUint16(offset + 2)\n if (marker >= 0xc0 && marker <= 0xc3) {\n return {\n height: view.getUint16(offset + 5),\n width: view.getUint16(offset + 7),\n }\n }\n offset += 2 + length\n }\n }\n\n return undefined\n }\n\n private isLatexFormula(text: string): boolean {\n if (/[\\\\^_{}]/.test(text)) return true\n if (/[α-ωΑ-Ω]/.test(text)) return true\n if (/[∑∏∫∂∇∞≠≤≥±×÷√]/.test(text)) return true\n return false\n }\n\n private processLatex(content: string): string {\n const LATEX_API = 'https://latex.codecogs.com/png.latex'\n\n content = content.replace(/\\$\\$([^$]+)\\$\\$/g, (match, latex) => {\n if (!this.isLatexFormula(latex)) return match\n const encoded = encodeURIComponent(latex.trim())\n return `<p style=\"text-align: center;\"><img src=\"${LATEX_API}?\\\\dpi{150}${encoded}\" alt=\"formula\" style=\"vertical-align: middle; max-width: 100%;\"></p>`\n })\n\n content = content.replace(/\\$([^$]+)\\$/g, (match, latex) => {\n if (!this.isLatexFormula(latex)) return match\n const encoded = encodeURIComponent(latex.trim())\n return `<img src=\"${LATEX_API}?\\\\dpi{120}${encoded}\" alt=\"formula\" style=\"vertical-align: middle;\">`\n })\n\n return content\n }\n\n private processContent(content: string): string {\n let html = `<section style=\"margin-left: 6px; margin-right: 6px; line-height: 1.75em;\">${content}</section>`\n for (const [selector, style] of WEIXIN_STYLE_RULES) {\n html = this.inlineSelectorStyle(html, selector, style)\n }\n return html\n }\n\n private inlineSelectorStyle(html: string, selector: string, style: string): string {\n if (selector === 'li p') {\n return html.replace(/<li\\b[^>]*>[\\s\\S]*?<\\/li>/gi, liHtml => this.inlineTagStyle(liHtml, 'p', style))\n }\n return selector\n .split(',')\n .map(tag => tag.trim())\n .reduce((nextHtml, tag) => this.inlineTagStyle(nextHtml, tag, style), html)\n }\n\n private inlineTagStyle(html: string, tag: string, style: string): string {\n const pattern = new RegExp(`<${tag}\\\\b([^>]*)>`, 'gi')\n return html.replace(pattern, (_match, attrs: string) => {\n const styleMatch = attrs.match(/\\sstyle=([\"'])([\\s\\S]*?)\\1/i)\n if (!styleMatch) {\n return `<${tag}${attrs} style=\"${style}\">`\n }\n\n const [fullMatch, quote, existingStyle] = styleMatch\n const nextStyle = this.escapeStyleAttribute(this.mergeInlineStyle(existingStyle, style), quote)\n return `<${tag}${attrs.replace(fullMatch, ` style=${quote}${nextStyle}${quote}`)}>`\n })\n }\n\n private mergeInlineStyle(existingStyle: string, nextStyle: string): string {\n const declarations: Array<[string, string]> = []\n const indexByProperty = new Map<string, number>()\n\n for (const style of [existingStyle, nextStyle]) {\n for (const declaration of style.split(';')) {\n const [property, ...valueParts] = declaration.split(':')\n const value = valueParts.join(':').trim()\n const normalizedProperty = property?.trim().toLowerCase()\n if (!normalizedProperty || !value) continue\n\n const rendered: [string, string] = [property.trim(), value]\n const index = indexByProperty.get(normalizedProperty)\n if (index === undefined) {\n indexByProperty.set(normalizedProperty, declarations.length)\n declarations.push(rendered)\n } else {\n declarations[index] = rendered\n }\n }\n }\n\n return declarations.map(([property, value]) => `${property}: ${value};`).join(' ')\n }\n\n private escapeStyleAttribute(value: string, quote: string): string {\n return quote === '\"'\n ? value.replace(/\"/g, '"')\n : value.replace(/'/g, ''')\n }\n\n /**\n * 移除外部链接(微信不允许非 mp.weixin.qq.com 域名的链接)\n * 将 <a href=\"外部链接\">文字</a> 转换为 文字\n */\n private stripExternalLinks(content: string): string {\n // 匹配 <a> 标签,保留微信域名的链接\n return content.replace(\n /<a\\s+[^>]*href=[\"']([^\"']*)[\"'][^>]*>([\\s\\S]*?)<\\/a>/gi,\n (match, href, text) => {\n // 保留微信域名的链接\n if (href && (\n href.includes('mp.weixin.qq.com') ||\n href.includes('weixin.qq.com') ||\n href.startsWith('#') || // 锚点链接\n href.startsWith('javascript:') // JS 链接\n )) {\n return match\n }\n // 外部链接只保留文字\n return text\n }\n )\n }\n\n private formatError(res: { ret?: number; base_resp?: { ret: number } }): string {\n const ret = res.ret ?? res.base_resp?.ret\n\n const errorMap: Record<number, string> = {\n [-6]: '请输入验证码',\n [-8]: '请输入验证码',\n [-1]: '系统错误,请注意备份内容后重试',\n [-2]: '参数错误,请注意备份内容后重试',\n [-5]: '服务错误,请注意备份内容后重试',\n [-99]: '内容超出字数,请调整',\n [-206]: '服务负荷过大,请稍后重试',\n [200002]: '参数错误,请注意备份内容后重试',\n [200003]: '登录态超时,请重新登录',\n [412]: '图文中含非法外链',\n [62752]: '可能含有具备安全风险的链接,请检查',\n [64502]: '你输入的微信号不存在',\n [64505]: '发送预览失败,请稍后再试',\n [64506]: '保存失败,链接不合法',\n [64507]: '内容不能包含外部链接',\n [64562]: '请勿插入非微信域名的链接',\n [64509]: '正文中不能包含超过3个视频',\n [64515]: '当前素材非最新内容,请重新打开并编辑',\n [64702]: '标题超出64字长度限制',\n [64703]: '摘要超出120字长度限制',\n [64705]: '内容超出字数,请调整',\n [10806]: '正文不能有违规内容,请重新编辑',\n [10807]: '内容不能违反公众平台协议',\n [220001]: '素材管理中的存储数量已达上限',\n [220002]: '图片库已达到存储上限',\n }\n\n return errorMap[ret as number] || `同步失败 (错误码: ${ret})`\n }\n\n private formatStageError(stage: string, res: { ret?: number; base_resp?: { ret: number; err_msg?: string } }): string {\n const message = res.base_resp?.err_msg || this.formatError(res)\n let detail = ''\n try {\n detail = ` ${JSON.stringify(res).slice(0, 500)}`\n } catch {\n // ignore non-serializable response\n }\n return `微信公众号${stage}失败: ${message}${detail}`\n }\n\n private wrapStageError(stage: string, error: unknown): Error {\n const message = error instanceof Error ? error.message : String(error)\n if (message.startsWith('微信公众号')) {\n return error instanceof Error ? error : new Error(message)\n }\n return new Error(`微信公众号${stage}失败: ${message || '未知错误'}`)\n }\n\n private formatUnexpectedError(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error)\n if (message.startsWith('微信公众号') || message.startsWith('[weixin]')) {\n return message\n }\n return `微信公众号发布流程失败: ${message || '未知错误'}`\n }\n\n private randomId(length: number): string {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'\n let value = ''\n for (let i = 0; i < length; i++) {\n value += chars[Math.floor(Math.random() * chars.length)]\n }\n return value\n }\n}\n"],"mappings":"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","names":["logger","tab","logger","logger","logger","tab","logger","tab","logger","IMAGEX_SERVICE_ID","logger","logger","logger","logger","logger","cover"]}
|