mirror of
https://github.com/JimLiu/baoyu-skills.git
synced 2026-07-09 20:51:22 +00:00
fix(baoyu-post-to-wechat): improve newspic plain text conversion for WeChat API
The previous fix used a simple regex to strip HTML tags for newspic content, but it had several issues: 1. HTML entities ( , <, >, &, etc.) were not decoded 2. Block-level tags (</p>, </div>, </h1> etc.) did not produce line breaks 3. Multiple consecutive whitespace characters were not collapsed This commit introduces a dedicated htmlToPlainText() function that: - Converts <br> and block-level closing tags to line breaks - Strips all remaining HTML tags - Decodes common HTML entities (including numeric entities) - Collapses consecutive whitespace into single spaces - Trims whitespace from each line This ensures the content field for newspic articles is properly formatted plain text that complies with WeChat API requirements, preventing error 45166 (invalid content) especially when publishing with multiple images. Closes #163 Merges #164
This commit is contained in:
@@ -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. 将 <br>, <br/>, <br /> 替换为换行符
|
||||
text = text.replace(/<br\s*\/?>/gi, "\n");
|
||||
|
||||
// 2. 将 </p>, </div>, </h1>, </h2>, </h3>, </h4>, </h5>, </h6>, </li> 替换为换行符
|
||||
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<string, string> = {
|
||||
" ": " ",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
"&": "&",
|
||||
""": '"',
|
||||
"'": "'",
|
||||
"'": "'",
|
||||
"—": "—",
|
||||
"–": "–",
|
||||
"…": "…",
|
||||
"“": """,
|
||||
"”": """,
|
||||
"‘": "'",
|
||||
"’": "'",
|
||||
};
|
||||
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: {
|
||||
|
||||
Reference in New Issue
Block a user