diff --git a/skills/baoyu-post-to-wechat/scripts/wechat-api.ts b/skills/baoyu-post-to-wechat/scripts/wechat-api.ts
index 5b7674e..5656da9 100644
--- a/skills/baoyu-post-to-wechat/scripts/wechat-api.ts
+++ b/skills/baoyu-post-to-wechat/scripts/wechat-api.ts
@@ -99,6 +99,60 @@ function toHttpsUrl(url: string | undefined): string {
return url.startsWith("http://") ? url.replace(/^http:\/\//i, "https://") : url;
}
+function htmlToPlainText(html: string): string {
+ if (!html) return "";
+
+ let text = html;
+
+ // 1. 将
,
,
替换为换行符
+ text = text.replace(/
/gi, "\n");
+
+ // 2. 将
, , , , , , , , 替换为换行符
+ text = text.replace(/<\/(?:p|div|h[1-6]|li|tr|td|th)>/gi, "\n");
+
+ // 3. 去掉所有剩余的 HTML 标签
+ text = text.replace(/<[^>]+>/g, "");
+
+ // 4. 解码 HTML 实体
+ const entityMap: Record = {
+ " ": " ",
+ "<": "<",
+ ">": ">",
+ "&": "&",
+ """: '"',
+ "'": "'",
+ "'": "'",
+ "—": "—",
+ "–": "–",
+ "…": "…",
+ "“": """,
+ "”": """,
+ "‘": "'",
+ "’": "'",
+ };
+ text = text.replace(/&(?:[a-zA-Z]+|#\d+);/g, (entity) => {
+ if (entityMap[entity]) return entityMap[entity];
+ // 处理数字实体,如 {
+ const numMatch = entity.match(/(\d+);/);
+ if (numMatch) {
+ return String.fromCharCode(Number.parseInt(numMatch[1]!, 10));
+ }
+ return entity;
+ });
+
+ // 5. 合并多个连续空白字符(空格、制表符、换行)为一个空格
+ text = text.replace(/[ \t]+/g, " ");
+
+ // 6. 合并多个连续换行为一个换行
+ text = text.replace(/\n{3,}/g, "\n\n");
+
+ // 7. 去掉行首行尾空白
+ text = text.split("\n").map(line => line.trim()).join("\n");
+
+ // 8. 最终 trim
+ return text.trim();
+}
+
async function uploadImage(
imagePath: string,
accessToken: string,
@@ -295,10 +349,15 @@ async function publishToDraft(
if (!options.imageMediaIds || options.imageMediaIds.length === 0) {
throw new Error("newspic requires at least one image");
}
+ // newspic 的 content 应该是纯文本,需要:
+ // 1. 去掉 HTML 标签
+ // 2. 解码 HTML 实体( 、< 等)
+ // 3. 合并多余空白字符
+ const plainContent = htmlToPlainText(options.content);
article = {
article_type: "newspic",
title: options.title,
- content: options.content,
+ content: plainContent,
need_open_comment: noc,
only_fans_can_comment: ofcc,
image_info: {