chore(frontend): introduce prettier + eslint and prune unused code
Backend CI / Backend (push) Has been cancelled
Frontend CI / Frontend (push) Failing after 1m39s

- Add Prettier 3 with prettier-plugin-organize-imports (sorts/removes unused imports)
- Add ESLint 10 flat config with typescript-eslint + eslint-plugin-vue + eslint-config-prettier
- Add root scripts: format, format:check, lint, lint:fix
- Reformat 257 files across admin-web, ops-web, desktop-client, packages
- Remove unused locals/exports flagged by --noUnusedLocals/--noUnusedParameters
- Fix duplicate localTabLabel key, surrogate-pair regex u-flag, NBSP literal in regex
- Skip server/ (Go) and apps/browser-extension/ (deprecated per ADR)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-01 20:39:09 +08:00
parent 21c7892ee4
commit 162abdc97c
258 changed files with 42261 additions and 37556 deletions
+302 -265
View File
@@ -1,154 +1,168 @@
import { Buffer } from "node:buffer";
import { Buffer } from 'node:buffer'
import type { JsonValue } from "@geo/shared-types";
import type { JsonValue } from '@geo/shared-types'
import { nativeImage } from 'electron'
import {
prepareBaijiahaoArticleHtml,
prepareBaijiahaoMarkdown,
} from "../../../../../packages/publisher-platforms/src/baijiahao";
import { nativeImage } from "electron";
} from '../../../../../packages/publisher-platforms/src/baijiahao'
import { resolveDesktopApiURL } from '../transport/api-client'
import type { PublishAdapter, PublishAdapterContext } from './base'
import {
normalizeArticleHtml,
sessionFetchJson,
sessionFetchText,
uploadHtmlImages,
} from "./common";
import type { PublishAdapter, PublishAdapterContext } from "./base";
import { resolveDesktopApiURL } from "../transport/api-client";
} from './common'
type BaijiahaoAppInfoResponse = {
data?: {
user?: {
userid?: string | number;
name?: string;
uname?: string;
username?: string;
avatar?: string;
app_id?: string | number;
};
};
};
userid?: string | number
name?: string
uname?: string
username?: string
avatar?: string
app_id?: string | number
}
}
}
type BaijiahaoPublishResponse = {
errno?: number;
errmsg?: string;
errno?: number
errmsg?: string
ret?: {
id?: string | number;
};
};
id?: string | number
}
}
type BaijiahaoUploadResponse = {
errno?: number;
errmsg?: string;
err_msg?: string;
errno?: number
errmsg?: string
err_msg?: string
ret?: {
https_url?: string;
url?: string;
};
};
https_url?: string
url?: string
}
}
type BaijiahaoCutResponse = {
data?: {
new_url?: string;
};
};
new_url?: string
}
}
type BaijiahaoUser = NonNullable<NonNullable<BaijiahaoAppInfoResponse["data"]>["user"]>;
type BaijiahaoUser = NonNullable<NonNullable<BaijiahaoAppInfoResponse['data']>['user']>
type BaijiahaoImageBlob = {
blob: Blob;
fileName: string;
};
blob: Blob
fileName: string
}
const BAIJIAHAO_SUPPORTED_IMAGE_TYPES = new Set(["image/png", "image/jpeg", "image/jpg", "image/gif"]);
const BAIJIAHAO_ORIGIN = "https://baijiahao.baidu.com";
const BAIJIAHAO_EDIT_URL = `${BAIJIAHAO_ORIGIN}/builder/rc/edit?type=news`;
const BAIJIAHAO_STEP_DELAY_MS = 1400;
const BAIJIAHAO_RISK_CONTROL_PROMPT = "您触发平台风控,请手动发稿一篇并完成验证,方可继续使用";
const BAIJIAHAO_SUPPORTED_IMAGE_TYPES = new Set([
'image/png',
'image/jpeg',
'image/jpg',
'image/gif',
])
const BAIJIAHAO_ORIGIN = 'https://baijiahao.baidu.com'
const BAIJIAHAO_EDIT_URL = `${BAIJIAHAO_ORIGIN}/builder/rc/edit?type=news`
const BAIJIAHAO_STEP_DELAY_MS = 1400
const BAIJIAHAO_RISK_CONTROL_PROMPT = '您触发平台风控,请手动发稿一篇并完成验证,方可继续使用'
function normalizeUserId(value: unknown): string {
if (value === null || value === undefined) {
return "";
return ''
}
return String(value).trim();
return String(value).trim()
}
function displayNameFromUser(user: BaijiahaoUser): string {
return user.name?.trim() || user.uname?.trim() || user.username?.trim() || "";
return user.name?.trim() || user.uname?.trim() || user.username?.trim() || ''
}
function baijiahaoHeaders(headers?: HeadersInit): Headers {
const next = new Headers(headers);
if (!next.has("origin")) {
next.set("origin", BAIJIAHAO_ORIGIN);
const next = new Headers(headers)
if (!next.has('origin')) {
next.set('origin', BAIJIAHAO_ORIGIN)
}
if (!next.has("referer")) {
next.set("referer", BAIJIAHAO_EDIT_URL);
if (!next.has('referer')) {
next.set('referer', BAIJIAHAO_EDIT_URL)
}
return next;
return next
}
function waitForHumanPace(signal?: AbortSignal): Promise<void> {
if (signal?.aborted) {
return Promise.reject(new Error("adapter_aborted"));
return Promise.reject(new Error('adapter_aborted'))
}
return new Promise((resolve, reject) => {
const cleanup = () => {
signal?.removeEventListener("abort", onAbort);
};
signal?.removeEventListener('abort', onAbort)
}
const timeout = setTimeout(() => {
cleanup();
resolve();
}, BAIJIAHAO_STEP_DELAY_MS);
cleanup()
resolve()
}, BAIJIAHAO_STEP_DELAY_MS)
const onAbort = () => {
clearTimeout(timeout);
cleanup();
reject(new Error("adapter_aborted"));
};
signal?.addEventListener("abort", onAbort, { once: true });
});
clearTimeout(timeout)
cleanup()
reject(new Error('adapter_aborted'))
}
signal?.addEventListener('abort', onAbort, { once: true })
})
}
function baijiahaoResponseMessage(response: {
errno?: number;
errmsg?: string;
err_msg?: string;
message?: string;
} | null | undefined): string {
return response?.errmsg || response?.err_msg || response?.message || `errno_${response?.errno ?? "unknown"}`;
function baijiahaoResponseMessage(
response:
| {
errno?: number
errmsg?: string
err_msg?: string
message?: string
}
| null
| undefined,
): string {
return (
response?.errmsg ||
response?.err_msg ||
response?.message ||
`errno_${response?.errno ?? 'unknown'}`
)
}
function isBaijiahaoChallengeMessage(message: string): boolean {
return /(验证码|滑块|人机验证|安全验证|请完成验证|短信验证|扫码验证|captcha|challenge|verification required)/i.test(message);
return /(验证码|滑块|人机验证|安全验证|请完成验证|短信验证|扫码验证|captcha|challenge|verification required)/i.test(
message,
)
}
async function fetchAppInfo(context: PublishAdapterContext): Promise<BaijiahaoUser | null> {
const response = await sessionFetchJson<BaijiahaoAppInfoResponse>(
context.session,
"https://baijiahao.baidu.com/builder/app/appinfo",
'https://baijiahao.baidu.com/builder/app/appinfo',
{
credentials: "include",
credentials: 'include',
headers: baijiahaoHeaders({
accept: "application/json, text/plain, */*",
accept: 'application/json, text/plain, */*',
}),
},
).catch(() => null);
).catch(() => null)
return response?.data?.user ?? null;
return response?.data?.user ?? null
}
async function getPublishToken(context: PublishAdapterContext): Promise<string> {
const html = await sessionFetchText(
context.session,
BAIJIAHAO_EDIT_URL,
{
credentials: "include",
headers: baijiahaoHeaders({
accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
}),
},
);
const html = await sessionFetchText(context.session, BAIJIAHAO_EDIT_URL, {
credentials: 'include',
headers: baijiahaoHeaders({
accept:
'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
}),
})
return /window\.__BJH__INIT__AUTH__\s*=\s*(["'])(.*?)\1/.exec(html)?.[2] ?? "";
return /window\.__BJH__INIT__AUTH__\s*=\s*(["'])(.*?)\1/.exec(html)?.[2] ?? ''
}
async function uploadImage(
@@ -157,143 +171,156 @@ async function uploadImage(
appId: string,
cropCover: boolean,
): Promise<string | null> {
const image = await fetchBaijiahaoImageBlob(sourceUrl);
const image = await fetchBaijiahaoImageBlob(sourceUrl)
if (!image) {
throw new Error(cropCover ? "baijiahao_cover_fetch_failed" : "baijiahao_image_fetch_failed");
throw new Error(cropCover ? 'baijiahao_cover_fetch_failed' : 'baijiahao_image_fetch_failed')
}
const form = new FormData();
form.append("media", image.blob, "cover.png");
form.append("org_file_name", "cover.png");
form.append("type", "image");
form.append("app_id", appId);
form.append("is_waterlog", "0");
form.append("save_material", "1");
form.append("no_compress", "0");
form.append("article_type", "news");
const form = new FormData()
form.append('media', image.blob, 'cover.png')
form.append('org_file_name', 'cover.png')
form.append('type', 'image')
form.append('app_id', appId)
form.append('is_waterlog', '0')
form.append('save_material', '1')
form.append('no_compress', '0')
form.append('article_type', 'news')
const uploaded = await sessionFetchJson<BaijiahaoUploadResponse>(
context.session,
`${BAIJIAHAO_ORIGIN}/materialui/picture/uploadProxy`,
{
method: "POST",
credentials: "include",
method: 'POST',
credentials: 'include',
headers: baijiahaoHeaders(),
body: form,
},
).catch((error) => {
throw new Error(error instanceof Error ? `baijiahao_upload_proxy_request_failed:${error.message}` : "baijiahao_upload_proxy_request_failed");
});
throw new Error(
error instanceof Error
? `baijiahao_upload_proxy_request_failed:${error.message}`
: 'baijiahao_upload_proxy_request_failed',
)
})
const uploadedUrl = uploaded?.ret?.https_url ?? uploaded?.ret?.url ?? null;
const uploadedUrl = uploaded?.ret?.https_url ?? uploaded?.ret?.url ?? null
if (!uploadedUrl) {
const message = baijiahaoResponseMessage(uploaded);
const message = baijiahaoResponseMessage(uploaded)
if (isBaijiahaoChallengeMessage(message)) {
throw new Error(`baijiahao_challenge_required:${message}`);
throw new Error(`baijiahao_challenge_required:${message}`)
}
throw new Error(`baijiahao_upload_proxy_failed:${message}`);
throw new Error(`baijiahao_upload_proxy_failed:${message}`)
}
if (!cropCover) {
return uploadedUrl;
return uploadedUrl
}
const cut = await sessionFetchJson<BaijiahaoCutResponse>(
context.session,
`${BAIJIAHAO_ORIGIN}/materialui/picture/auto_cutting`,
{
method: "POST",
credentials: "include",
method: 'POST',
credentials: 'include',
headers: baijiahaoHeaders({
"content-type": "application/x-www-form-urlencoded",
'content-type': 'application/x-www-form-urlencoded',
}),
body: new URLSearchParams({
org_url: uploadedUrl,
type: "news",
cutting_type: "cover_image",
type: 'news',
cutting_type: 'cover_image',
}),
},
).catch((error) => {
throw new Error(error instanceof Error ? `baijiahao_cover_cut_failed:${error.message}` : "baijiahao_cover_cut_failed");
});
throw new Error(
error instanceof Error
? `baijiahao_cover_cut_failed:${error.message}`
: 'baijiahao_cover_cut_failed',
)
})
return cut?.data?.new_url ?? uploadedUrl;
return cut?.data?.new_url ?? uploadedUrl
}
function buildImageURLCandidates(sourceUrl: string): string[] {
const trimmed = sourceUrl.trim();
const trimmed = sourceUrl.trim()
if (!trimmed) {
return [];
return []
}
if (/^(data|blob):/i.test(trimmed)) {
return [trimmed];
return [trimmed]
}
const candidates: string[] = [];
const candidates: string[] = []
const pushCandidate = (value: string) => {
if (!candidates.includes(value)) {
candidates.push(value);
candidates.push(value)
}
};
try {
const parsed = new URL(trimmed, resolveDesktopApiURL("/"));
if (parsed.pathname.startsWith("/api/")) {
const apiAssetUrl = new URL(resolveDesktopApiURL(`${parsed.pathname}${parsed.search}`));
if (apiAssetUrl.pathname.startsWith("/api/public/assets/")) {
apiAssetUrl.searchParams.set("format", "png");
}
pushCandidate(apiAssetUrl.toString());
}
pushCandidate(parsed.toString());
} catch {
pushCandidate(trimmed);
}
return candidates;
try {
const parsed = new URL(trimmed, resolveDesktopApiURL('/'))
if (parsed.pathname.startsWith('/api/')) {
const apiAssetUrl = new URL(resolveDesktopApiURL(`${parsed.pathname}${parsed.search}`))
if (apiAssetUrl.pathname.startsWith('/api/public/assets/')) {
apiAssetUrl.searchParams.set('format', 'png')
}
pushCandidate(apiAssetUrl.toString())
}
pushCandidate(parsed.toString())
} catch {
pushCandidate(trimmed)
}
return candidates
}
async function fetchBaijiahaoImageBlob(sourceUrl: string): Promise<BaijiahaoImageBlob | null> {
for (const candidate of buildImageURLCandidates(sourceUrl)) {
const response = await fetch(candidate).catch(() => null);
const response = await fetch(candidate).catch(() => null)
if (!response?.ok) {
continue;
continue
}
const sourceBlob = await response.blob().catch(() => null);
if (!sourceBlob || !sourceBlob.type.startsWith("image/")) {
continue;
const sourceBlob = await response.blob().catch(() => null)
if (!sourceBlob || !sourceBlob.type.startsWith('image/')) {
continue
}
return normalizeBaijiahaoImageBlob(sourceBlob);
return normalizeBaijiahaoImageBlob(sourceBlob)
}
return null;
return null
}
async function normalizeBaijiahaoImageBlob(sourceBlob: Blob): Promise<BaijiahaoImageBlob | null> {
const sourceType = sourceBlob.type.toLowerCase();
const sourceType = sourceBlob.type.toLowerCase()
if (BAIJIAHAO_SUPPORTED_IMAGE_TYPES.has(sourceType)) {
return {
blob: sourceBlob,
fileName: sourceType === "image/gif" ? "image.gif" : sourceType === "image/jpeg" || sourceType === "image/jpg" ? "image.jpg" : "image.png",
};
fileName:
sourceType === 'image/gif'
? 'image.gif'
: sourceType === 'image/jpeg' || sourceType === 'image/jpg'
? 'image.jpg'
: 'image.png',
}
}
const buffer = Buffer.from(await sourceBlob.arrayBuffer());
const image = nativeImage.createFromBuffer(buffer);
const buffer = Buffer.from(await sourceBlob.arrayBuffer())
const image = nativeImage.createFromBuffer(buffer)
if (image.isEmpty()) {
return null;
return null
}
const png = image.toPNG();
const png = image.toPNG()
return {
blob: new Blob([new Uint8Array(png)], { type: "image/png" }),
fileName: "image.png",
};
blob: new Blob([new Uint8Array(png)], { type: 'image/png' }),
fileName: 'image.png',
}
}
async function processContentImages(
@@ -302,20 +329,20 @@ async function processContentImages(
appId: string,
): Promise<string> {
const processed = await uploadHtmlImages(html, async (sourceUrl) => {
await waitForHumanPace(context.signal);
return await uploadImage(context, sourceUrl, appId, false);
});
await waitForHumanPace(context.signal)
return await uploadImage(context, sourceUrl, appId, false)
})
return processed.html;
return processed.html
}
function buildActivityList(): string {
return JSON.stringify([
{ id: "ttv", is_checked: 0 },
{ id: "ai_tts", is_checked: 0 },
{ id: "aigc_bjh_status", is_checked: 0 },
{ id: "reward", is_checked: 0 },
]);
{ id: 'ttv', is_checked: 0 },
{ id: 'ai_tts', is_checked: 0 },
{ id: 'aigc_bjh_status', is_checked: 0 },
{ id: 'reward', is_checked: 0 },
])
}
function buildCoverImages(coverUrl: string): string {
@@ -325,17 +352,17 @@ function buildCoverImages(coverUrl: string): string {
cropData: {},
machine_chooseimg: 0,
isLegal: 0,
cover_source_tag: "local",
cover_source_tag: 'local',
},
]);
])
}
function baijiahaoManageUrl(articleId: string): string {
return `${BAIJIAHAO_EDIT_URL}&article_id=${encodeURIComponent(articleId)}`;
return `${BAIJIAHAO_EDIT_URL}&article_id=${encodeURIComponent(articleId)}`
}
function baijiahaoPublicUrl(articleId: string): string {
return `${BAIJIAHAO_ORIGIN}/s?id=${encodeURIComponent(articleId)}`;
return `${BAIJIAHAO_ORIGIN}/s?id=${encodeURIComponent(articleId)}`
}
function buildResultPayload(
@@ -345,218 +372,228 @@ function buildResultPayload(
externalArticleUrl: string,
): Record<string, JsonValue> {
return {
platform: "baijiahao",
platform: 'baijiahao',
media_name: mediaName,
external_article_id: articleId,
external_manage_url: externalManageUrl,
external_article_url: externalArticleUrl,
publish_type: "publish",
};
publish_type: 'publish',
}
}
function failureResult(error: unknown): ReturnType<PublishAdapter["publish"]> extends Promise<infer T> ? T : never {
const message = error instanceof Error ? error.message : String(error);
function failureResult(
error: unknown,
): ReturnType<PublishAdapter['publish']> extends Promise<infer T> ? T : never {
const message = error instanceof Error ? error.message : String(error)
if (message === "baijiahao_not_logged_in") {
if (message === 'baijiahao_not_logged_in') {
return {
status: "failed",
summary: "百家号登录态失效,无法执行发布。",
status: 'failed',
summary: '百家号登录态失效,无法执行发布。',
error: {
code: "baijiahao_not_logged_in",
code: 'baijiahao_not_logged_in',
message,
},
};
}
}
if (message === "baijiahao_token_missing") {
if (message === 'baijiahao_token_missing') {
return {
status: "failed",
summary: "百家号发布 Token 获取失败,请重新打开百家号后台确认登录态。",
status: 'failed',
summary: '百家号发布 Token 获取失败,请重新打开百家号后台确认登录态。',
error: {
code: "baijiahao_token_missing",
code: 'baijiahao_token_missing',
message,
},
};
}
}
if (message === "publish_cover_required") {
if (message === 'publish_cover_required') {
return {
status: "failed",
summary: "百家号发布必须上传封面图。",
status: 'failed',
summary: '百家号发布必须上传封面图。',
error: {
code: "publish_cover_required",
code: 'publish_cover_required',
message,
},
};
}
}
if (message === "baijiahao_cover_upload_failed") {
if (message === 'baijiahao_cover_upload_failed') {
return {
status: "failed",
summary: "百家号封面上传失败,请更换封面图后重试。",
status: 'failed',
summary: '百家号封面上传失败,请更换封面图后重试。',
error: {
code: "baijiahao_cover_upload_failed",
code: 'baijiahao_cover_upload_failed',
message,
},
};
}
}
if (message === "baijiahao_cover_fetch_failed" || message.startsWith("baijiahao_cover_fetch_failed:")) {
if (
message === 'baijiahao_cover_fetch_failed' ||
message.startsWith('baijiahao_cover_fetch_failed:')
) {
return {
status: "failed",
summary: "百家号封面文件读取失败,请重新上传封面图后重试。",
status: 'failed',
summary: '百家号封面文件读取失败,请重新上传封面图后重试。',
error: {
code: "baijiahao_cover_fetch_failed",
code: 'baijiahao_cover_fetch_failed',
message,
},
};
}
}
if (message.startsWith("baijiahao_upload_proxy_failed") || message.startsWith("baijiahao_upload_proxy_request_failed")) {
if (
message.startsWith('baijiahao_upload_proxy_failed') ||
message.startsWith('baijiahao_upload_proxy_request_failed')
) {
return {
status: "failed",
summary: "百家号素材上传接口拒绝了封面图。",
status: 'failed',
summary: '百家号素材上传接口拒绝了封面图。',
error: {
code: "baijiahao_upload_proxy_failed",
code: 'baijiahao_upload_proxy_failed',
message,
},
};
}
}
if (message.startsWith("baijiahao_cover_cut_failed")) {
if (message.startsWith('baijiahao_cover_cut_failed')) {
return {
status: "failed",
summary: "百家号封面裁剪接口处理失败。",
status: 'failed',
summary: '百家号封面裁剪接口处理失败。',
error: {
code: "baijiahao_cover_cut_failed",
code: 'baijiahao_cover_cut_failed',
message,
},
};
}
}
if (message.startsWith("baijiahao_challenge_required")) {
if (message.startsWith('baijiahao_challenge_required')) {
return {
status: "failed",
status: 'failed',
summary: BAIJIAHAO_RISK_CONTROL_PROMPT,
error: {
code: "baijiahao_challenge_required",
code: 'baijiahao_challenge_required',
message,
},
};
}
}
if (message === "article_content_empty") {
if (message === 'article_content_empty') {
return {
status: "failed",
summary: "文章内容为空,无法推送到百家号。",
status: 'failed',
summary: '文章内容为空,无法推送到百家号。',
error: {
code: "article_content_empty",
code: 'article_content_empty',
message,
},
};
}
}
return {
status: "failed",
summary: "百家号发布失败。",
status: 'failed',
summary: '百家号发布失败。',
error: {
code: "baijiahao_publish_failed",
code: 'baijiahao_publish_failed',
message,
},
};
}
}
export const baijiahaoAdapter: PublishAdapter = {
platform: "baijiahao",
executionMode: "session",
platform: 'baijiahao',
executionMode: 'session',
async publish(context) {
try {
context.reportProgress("baijiahao.detect_login");
const user = await fetchAppInfo(context);
const platformUid = normalizeUserId(user?.userid);
const mediaName = user ? displayNameFromUser(user) : "";
const appId = normalizeUserId(user?.app_id);
context.reportProgress('baijiahao.detect_login')
const user = await fetchAppInfo(context)
const platformUid = normalizeUserId(user?.userid)
const mediaName = user ? displayNameFromUser(user) : ''
const appId = normalizeUserId(user?.app_id)
if (!platformUid || !mediaName || !appId) {
throw new Error("baijiahao_not_logged_in");
throw new Error('baijiahao_not_logged_in')
}
context.reportProgress("baijiahao.get_token");
await waitForHumanPace(context.signal);
const token = await getPublishToken(context);
context.reportProgress('baijiahao.get_token')
await waitForHumanPace(context.signal)
const token = await getPublishToken(context)
if (!token) {
throw new Error("baijiahao_token_missing");
throw new Error('baijiahao_token_missing')
}
const coverAssetUrl = context.article.cover_asset_url?.trim() || "";
const coverAssetUrl = context.article.cover_asset_url?.trim() || ''
if (!coverAssetUrl) {
throw new Error("publish_cover_required");
throw new Error('publish_cover_required')
}
const html = prepareBaijiahaoArticleHtml(
normalizeArticleHtml(context.article, {
prepareMarkdown: prepareBaijiahaoMarkdown,
}),
);
)
if (!html) {
throw new Error("article_content_empty");
throw new Error('article_content_empty')
}
context.reportProgress("baijiahao.upload_content_images");
await waitForHumanPace(context.signal);
const content = await processContentImages(context, html, appId);
context.reportProgress('baijiahao.upload_content_images')
await waitForHumanPace(context.signal)
const content = await processContentImages(context, html, appId)
context.reportProgress("baijiahao.upload_cover");
await waitForHumanPace(context.signal);
const coverUrl = await uploadImage(context, coverAssetUrl, appId, true);
context.reportProgress('baijiahao.upload_cover')
await waitForHumanPace(context.signal)
const coverUrl = await uploadImage(context, coverAssetUrl, appId, true)
if (!coverUrl) {
throw new Error("baijiahao_cover_upload_failed");
throw new Error('baijiahao_cover_upload_failed')
}
context.reportProgress("baijiahao.submit");
await waitForHumanPace(context.signal);
context.reportProgress('baijiahao.submit')
await waitForHumanPace(context.signal)
const response: BaijiahaoPublishResponse = await sessionFetchJson<BaijiahaoPublishResponse>(
context.session,
`${BAIJIAHAO_ORIGIN}/pcui/article/publish`,
{
method: "POST",
credentials: "include",
method: 'POST',
credentials: 'include',
headers: baijiahaoHeaders({
"content-type": "application/x-www-form-urlencoded",
'content-type': 'application/x-www-form-urlencoded',
Token: token,
}),
body: new URLSearchParams({
type: "news",
title: context.article.title?.trim() || "未命名文章",
type: 'news',
title: context.article.title?.trim() || '未命名文章',
content,
abstract_from: "1",
cover_layout: "one",
abstract_from: '1',
cover_layout: 'one',
cover_images: buildCoverImages(coverUrl),
activity_list: buildActivityList(),
}),
},
).catch((requestError): BaijiahaoPublishResponse => ({
errno: -1,
errmsg: requestError instanceof Error ? requestError.message : "baijiahao_publish_failed",
}));
).catch(
(requestError): BaijiahaoPublishResponse => ({
errno: -1,
errmsg: requestError instanceof Error ? requestError.message : 'baijiahao_publish_failed',
}),
)
const articleId = response.ret?.id != null ? String(response.ret.id) : "";
const articleId = response.ret?.id != null ? String(response.ret.id) : ''
if (response.errno !== 0 || !articleId) {
const message = baijiahaoResponseMessage(response);
const message = baijiahaoResponseMessage(response)
if (isBaijiahaoChallengeMessage(message)) {
throw new Error(`baijiahao_challenge_required:${message}`);
throw new Error(`baijiahao_challenge_required:${message}`)
}
throw new Error(message || "baijiahao_publish_failed");
throw new Error(message || 'baijiahao_publish_failed')
}
const manageUrl = baijiahaoManageUrl(articleId);
const articleUrl = baijiahaoPublicUrl(articleId);
const manageUrl = baijiahaoManageUrl(articleId)
const articleUrl = baijiahaoPublicUrl(articleId)
return {
status: "succeeded",
status: 'succeeded',
payload: buildResultPayload(articleId, mediaName, manageUrl, articleUrl),
summary: "百家号发布成功。",
};
summary: '百家号发布成功。',
}
} catch (error) {
return failureResult(error);
return failureResult(error)
}
},
};
}