diff --git a/skills/baoyu-post-to-wechat/scripts/wechat-api.ts b/skills/baoyu-post-to-wechat/scripts/wechat-api.ts
index 4802736..7266460 100644
--- a/skills/baoyu-post-to-wechat/scripts/wechat-api.ts
+++ b/skills/baoyu-post-to-wechat/scripts/wechat-api.ts
@@ -175,17 +175,19 @@ async function uploadImagesInHtml(
accessToken: string,
baseDir: string,
contentImages: ImageInfo[] = [],
-): Promise<{ html: string; firstImageUrl: string; allMediaIds: string[] }> {
+ articleType: ArticleType = "news",
+): Promise<{ html: string; firstImageUrl: string; firstImageSource: string; imageMediaIds: string[] }> {
const imgRegex = /
]*\ssrc=["']([^"']+)["'][^>]*>/gi;
const matches = [...html.matchAll(imgRegex)];
if (matches.length === 0 && contentImages.length === 0) {
- return { html, firstImageUrl: "", allMediaIds: [] };
+ return { html, firstImageUrl: "", firstImageSource: "", imageMediaIds: [] };
}
let firstImageUrl = "";
+ let firstImageSource = "";
let updatedHtml = html;
- const allMediaIds: string[] = [];
+ const imageMediaIds: string[] = [];
const uploadedBySource = new Map();
for (const match of matches) {
@@ -206,7 +208,7 @@ async function uploadImagesInHtml(
try {
let resp = uploadedBySource.get(imagePath);
if (!resp) {
- // 正文图片使用 media/uploadimg 接口
+ // 正文图片使用 media/uploadimg 接口获取 URL
resp = await uploadImage(imagePath, accessToken, baseDir, "body");
uploadedBySource.set(imagePath, resp);
}
@@ -217,6 +219,21 @@ async function uploadImagesInHtml(
if (!firstImageUrl) {
firstImageUrl = resp.url;
}
+
+ // 如果是 newspic 类型,额外调用 material 接口收集 media_id
+ if (articleType === "newspic") {
+ let materialResp = uploadedBySource.get(`${imagePath}:material`);
+ if (!materialResp) {
+ materialResp = await uploadImage(imagePath, accessToken, baseDir, "material");
+ uploadedBySource.set(`${imagePath}:material`, materialResp);
+ }
+ if (materialResp.media_id) {
+ imageMediaIds.push(materialResp.media_id);
+ if (!firstImageSource) {
+ firstImageSource = materialResp.media_id;
+ }
+ }
+ }
} catch (err) {
console.error(`[wechat-api] Failed to upload ${imagePath}:`, err);
}
@@ -231,7 +248,7 @@ async function uploadImagesInHtml(
try {
let resp = uploadedBySource.get(imagePath);
if (!resp) {
- // 正文图片使用 media/uploadimg 接口
+ // 正文图片使用 media/uploadimg 接口获取 URL
resp = await uploadImage(imagePath, accessToken, baseDir, "body");
uploadedBySource.set(imagePath, resp);
}
@@ -241,12 +258,27 @@ async function uploadImagesInHtml(
if (!firstImageUrl) {
firstImageUrl = resp.url;
}
+
+ // 如果是 newspic 类型,额外调用 material 接口收集 media_id
+ if (articleType === "newspic") {
+ let materialResp = uploadedBySource.get(`${imagePath}:material`);
+ if (!materialResp) {
+ materialResp = await uploadImage(imagePath, accessToken, baseDir, "material");
+ uploadedBySource.set(`${imagePath}:material`, materialResp);
+ }
+ if (materialResp.media_id) {
+ imageMediaIds.push(materialResp.media_id);
+ if (!firstImageSource) {
+ firstImageSource = materialResp.media_id;
+ }
+ }
+ }
} catch (err) {
console.error(`[wechat-api] Failed to upload placeholder ${image.placeholder}:`, err);
}
}
- return { html: updatedHtml, firstImageUrl, allMediaIds };
+ return { html: updatedHtml, firstImageUrl, firstImageSource, imageMediaIds };
}
async function publishToDraft(
@@ -609,11 +641,12 @@ async function main(): Promise {
const accessToken = await fetchAccessToken(creds.appId, creds.appSecret);
console.error("[wechat-api] Uploading body images...");
- const { html: processedHtml, firstImageUrl, allMediaIds } = await uploadImagesInHtml(
+ const { html: processedHtml, firstImageUrl, firstImageSource, imageMediaIds } = await uploadImagesInHtml(
htmlContent,
accessToken,
baseDir,
contentImages,
+ args.articleType,
);
htmlContent = processedHtml;
@@ -633,13 +666,10 @@ async function main(): Promise {
const coverResp = await uploadImage(coverPath, accessToken, baseDir, "material");
thumbMediaId = coverResp.media_id;
console.error(`[wechat-api] Cover uploaded successfully, media_id: ${thumbMediaId}`);
- } else if (firstImageUrl && args.articleType === "news") {
- // news 类型需要 thumb_media_id,正文图片的 URL 无法使用
- console.error(`[wechat-api] Warning: No cover image provided for news article.`);
- console.error(`[wechat-api] The first body image URL is: ${firstImageUrl}`);
- console.error(`[wechat-api] However, news articles require thumb_media_id (not URL).`);
- console.error(`[wechat-api] Please provide --cover parameter or set coverImage in frontmatter.`);
- process.exit(1);
+ } else if (firstImageSource && args.articleType === "news") {
+ // news 类型没有封面时,使用第一张正文图的 media_id 作为封面(兜底逻辑)
+ thumbMediaId = firstImageSource;
+ console.error(`[wechat-api] Using first body image as cover (fallback), media_id: ${thumbMediaId}`);
}
if (args.articleType === "news" && !thumbMediaId) {
@@ -647,7 +677,7 @@ async function main(): Promise {
process.exit(1);
}
- if (args.articleType === "newspic" && allMediaIds.length === 0) {
+ if (args.articleType === "newspic" && imageMediaIds.length === 0) {
console.error("Error: newspic requires at least one image in content.");
process.exit(1);
}
@@ -660,7 +690,7 @@ async function main(): Promise {
content: htmlContent,
thumbMediaId,
articleType: args.articleType,
- imageMediaIds: args.articleType === "newspic" ? allMediaIds : undefined,
+ imageMediaIds: args.articleType === "newspic" ? imageMediaIds : undefined,
needOpenComment: resolved.need_open_comment,
onlyFansCanComment: resolved.only_fans_can_comment,
}, accessToken);