feat(news-morning): enable comments, compact WeChat layout and SEO spec

Default open WeChat draft comments, add SEO/visual template rules with h2 sections and mindspace-geo, and compress inline styles to pack more cards within the 20k HTML budget.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
John
2026-09-18 09:29:30 +08:00
parent 9ae35f38e1
commit e962d86ba5
3 changed files with 118 additions and 59 deletions
@@ -35,6 +35,7 @@ async function main() {
'以及 google / x / universities / global_markets。',
'全页去重:同一 URL 或同一核心事件只允许出现一次;主栏目优先,扩展栏目必须换角度或跳过。',
'禁止 id=hot 热搜栏目;禁止 .stats 或「X条资讯 · Y个栏目」统计行。',
'SEOtitle/description/mindspace-geo/faq 必做;section-title 内用 h2card 左侧色条 + highlight 渐变。',
'英文栏目标题可英文,每条必须有中文摘要与来源 URL;禁止整段纯英文正文。',
].join('\n'),
};
+93 -53
View File
@@ -27,6 +27,28 @@ const BRAND = Object.freeze({
onDarkSoft: '#e8c2c8',
});
/** 紧凑 inline 样式,降低 HTML 开销以便在 2 万字内塞入更多资讯条。 */
const WX = Object.freeze({
hero: `background:linear-gradient(135deg,${BRAND.red},${BRAND.navy});border-radius:14px;padding:22px 16px 20px;text-align:center;color:#fff`,
heroTitle: 'margin:0;font-size:24px;font-weight:700;line-height:1.35',
heroMeta: `margin:8px 0 0;font-size:12px;color:${BRAND.onDark}`,
heroSub: `margin:12px 0 0;font-size:12px;line-height:1.8;color:${BRAND.onDark};text-align:left`,
digest: `margin:12px 0 0;background:${BRAND.tintRed};border-radius:10px;padding:12px 14px`,
digestLabel: `margin:0 0 6px;font-size:11px;font-weight:700;color:${BRAND.red}`,
digestBody: `margin:0;font-size:12px;color:${BRAND.body};line-height:1.85`,
section: `margin:20px 0 10px;padding-bottom:6px;border-bottom:1px solid ${BRAND.line};font-size:16px;font-weight:700;color:${BRAND.ink}`,
feature: 'margin:0 0 12px;border-radius:12px;padding:14px 14px 12px;color:#fff',
featureTag: `margin:0 0 6px;font-size:10px;color:${BRAND.onDarkSoft}`,
featureTitle: 'margin:0;font-size:15px;font-weight:700;line-height:1.5',
featureBody: `margin:8px 0 0;font-size:13px;line-height:1.75;color:${BRAND.onDark}`,
listWrap: 'margin:0 0 12px',
listTitle: `margin:0;font-size:14px;font-weight:700;color:${BRAND.ink};line-height:1.5`,
listBody: `margin:5px 0 0;font-size:13px;color:${BRAND.body};line-height:1.75`,
rankWrap: `margin:0 0 12px;background:${BRAND.tintRed};border-radius:10px;padding:12px 12px 8px`,
rankTitle: `margin:0 0 8px;font-size:14px;font-weight:700;color:${BRAND.ink};line-height:1.5`,
rankBody: `margin:0;font-size:13px;color:${BRAND.body};line-height:1.85`,
});
const SECTION_LABELS = {
headlines: 'TOP NEWS',
weather: 'WEATHER',
@@ -204,25 +226,25 @@ function renderRankListBody(bodyHtml, { maxRows = 14 } = {}) {
return `<span style="color:${BRAND.red};font-weight:700">${String(index + 1).padStart(2, '0')}</span> ${text}`;
})
.join('<br>');
return `<p style="margin:0;font-size:14px;color:${BRAND.body};line-height:1.95">${lines}</p>`;
return `<p style="${WX.rankBody}">${lines}</p>`;
}
function renderFeatureCard(cardHtml, { theme, title, body }) {
const tag = extractTagLabel(cardHtml);
return [
`<section style="margin:0 0 14px;background:${theme};border-radius:14px;padding:17px 16px;color:#fff">`,
tag ? `<p style="margin:0 0 9px;font-size:11px;color:${BRAND.onDarkSoft}">${tag}</p>` : '',
`<p style="margin:0;font-size:17px;font-weight:700;line-height:1.55"><strong>${title}</strong></p>`,
body ? `<p style="margin:9px 0 0;font-size:14px;line-height:1.85;color:${BRAND.onDark}">${body}</p>` : '',
`<section style="${WX.feature};background:${theme}">`,
tag ? `<p style="${WX.featureTag}">${tag}</p>` : '',
`<p style="${WX.featureTitle}"><strong>${title}</strong></p>`,
body ? `<p style="${WX.featureBody}">${body}</p>` : '',
'</section>',
].filter(Boolean).join('');
}
function renderListCard({ title, body, index }) {
return [
'<section style="margin:0 0 16px">',
`<p style="margin:0;font-size:16px;font-weight:700;color:${BRAND.ink};line-height:1.6"><span style="color:${BRAND.red}">${formatCardIndex(index)}</span> <strong>${title}</strong></p>`,
body ? `<p style="margin:7px 0 0;font-size:14px;color:${BRAND.body};line-height:1.85">${body}</p>` : '',
`<section style="${WX.listWrap}">`,
`<p style="${WX.listTitle}"><span style="color:${BRAND.red}">${formatCardIndex(index)}</span> <strong>${title}</strong></p>`,
body ? `<p style="${WX.listBody}">${body}</p>` : '',
'</section>',
].filter(Boolean).join('');
}
@@ -239,8 +261,8 @@ function renderCard(cardHtml, {
const rankBody = theme ? '' : renderRankListBody(rawBody);
if (rankBody) {
return [
`<section style="margin:0 0 15px;background:${BRAND.tintRed};border-radius:12px;padding:15px 15px 9px">`,
`<p style="margin:0 0 12px;font-size:16px;font-weight:700;color:${BRAND.ink};line-height:1.55"><strong>${stripInlineText(title)}</strong></p>`,
`<section style="${WX.rankWrap}">`,
`<p style="${WX.rankTitle}"><strong>${stripInlineText(title)}</strong></p>`,
rankBody,
'</section>',
].join('');
@@ -263,7 +285,7 @@ function renderSectionTitle(titleHtml, sectionId = '') {
const suffix = label
? `<span style="font-size:11px;color:${BRAND.faint};font-weight:400"> ${label}</span>`
: '';
return `<p style="margin:26px 0 14px;padding-bottom:8px;border-bottom:1px solid ${BRAND.line};font-size:18px;font-weight:700;color:${BRAND.ink}"><span style="color:${BRAND.red}">▎</span>${text}${suffix}</p>`;
return `<p style="${WX.section}"><span style="color:${BRAND.red}">▎</span>${text}${suffix}</p>`;
}
function resolveMappedImageUrl(src, imageUrlMap = new Map()) {
@@ -292,9 +314,9 @@ function renderTodayDigest(html, { maxItems = 6, maxItemChars = 30 } = {}) {
if (items.length < 2) return '';
const lines = items.map((item) => `<span style="color:${BRAND.red}">·</span> ${item}`).join('<br>');
return [
`<section style="margin:15px 0 2px;background:${BRAND.tintRed};border-radius:12px;padding:14px 15px">`,
`<p style="margin:0 0 9px;font-size:12px;font-weight:700;color:${BRAND.red};letter-spacing:1px">今日导读</p>`,
`<p style="margin:0;font-size:13px;color:${BRAND.body};line-height:1.95">${lines}</p>`,
`<section style="${WX.digest}">`,
`<p style="${WX.digestLabel}">今日导读</p>`,
`<p style="${WX.digestBody}">${lines}</p>`,
'</section>',
].join('');
}
@@ -305,10 +327,10 @@ function renderHero(html, _imageUrlMap = new Map(), { includeSubtitle = true } =
const dateBadge = stripInlineText(String(html).match(/<div class="date-badge"[^>]*>([\s\S]*?)<\/div>/i)?.[1] ?? '');
const subtitle = includeSubtitle ? truncatePlainText(extractHeroSubtitle(html), 150) : '';
return [
`<section style="background:linear-gradient(135deg,${BRAND.red},${BRAND.redDeep} 55%,${BRAND.navy});border-radius:16px;padding:30px 20px 26px;text-align:center;color:#fff">`,
`<p style="margin:0;font-size:27px;font-weight:700;line-height:1.3"><strong>${title.replace(/^[📰\s]+/u, '')}</strong></p>`,
dateBadge ? `<p style="margin:11px 0 0;font-size:13px;color:${BRAND.onDark}">${dateBadge}</p>` : '',
subtitle ? `<p style="margin:16px 0 0;font-size:13px;line-height:1.85;color:${BRAND.onDark};text-align:left">${subtitle}</p>` : '',
`<section style="${WX.hero}">`,
`<p style="${WX.heroTitle}"><strong>${title.replace(/^[📰\s]+/u, '')}</strong></p>`,
dateBadge ? `<p style="${WX.heroMeta}">${dateBadge}</p>` : '',
subtitle ? `<p style="${WX.heroSub}">${subtitle}</p>` : '',
'</section>',
].filter(Boolean).join('');
}
@@ -562,34 +584,34 @@ function renderGenericSection(
}
const DEFAULT_SECTION_CARD_LIMITS = {
headlines: 6,
world: 4,
domestic: 4,
google: 2,
x: 2,
asia_pacific: 2,
commodities: 2,
ai_chips: 2,
policy: 2,
universities: 2,
global_markets: 2,
community: 2,
science: 2,
culture: 2,
startup: 2,
headlines: 7,
world: 5,
domestic: 5,
google: 3,
x: 3,
asia_pacific: 3,
commodities: 3,
ai_chips: 3,
policy: 3,
universities: 3,
global_markets: 3,
community: 3,
science: 3,
culture: 3,
startup: 3,
crypto: 2,
geopolitics: 2,
local_life: 2,
official_feeds: 2,
finance: 4,
tech: 4,
sports: 2,
geopolitics: 3,
local_life: 3,
official_feeds: 3,
finance: 5,
tech: 5,
sports: 3,
technews: 2,
knowledge: 3,
};
const DEFAULT_CARD_BODY_CHARS = 150;
const MIN_CARDS_TO_KEEP = 12;
const DEFAULT_CARD_BODY_CHARS = 132;
const MIN_CARDS_TO_KEEP = 16;
const BASE_TRIM_FLAGS = Object.freeze({
skipHistory: true,
@@ -599,9 +621,18 @@ const BASE_TRIM_FLAGS = Object.freeze({
skipPageFooter: true,
});
/** 每档栏目容量,从「全量」到「精简」。 */
function mergeSectionCardLimits(fullCounts = {}, caps = DEFAULT_SECTION_CARD_LIMITS) {
const merged = { ...caps };
for (const [id, count] of Object.entries(fullCounts)) {
const cap = caps[id];
merged[id] = cap == null ? count : Math.min(count, cap);
}
return merged;
}
/** 每档栏目容量,从「较全量」到「精简」。 */
const CARD_LIMIT_TIERS = [
null,
DEFAULT_SECTION_CARD_LIMITS,
DEFAULT_SECTION_CARD_LIMITS,
{ ...DEFAULT_SECTION_CARD_LIMITS, headlines: 6, world: 4, domestic: 4, finance: 4, tech: 4, knowledge: 3 },
{ headlines: 5, world: 3, domestic: 3, google: 2, finance: 3, tech: 3, sports: 2, technews: 1, knowledge: 3 },
@@ -609,7 +640,7 @@ const CARD_LIMIT_TIERS = [
];
/** 每档卡片摘要字数,标题信息已足够时优先压缩摘要来换取更多条目。 */
const BODY_CHAR_TIERS = [DEFAULT_CARD_BODY_CHARS, 132, 118, 104];
const BODY_CHAR_TIERS = [DEFAULT_CARD_BODY_CHARS, 120, 108, 96];
const TRIM_PROFILES = CARD_LIMIT_TIERS.map((sectionCardLimits, index) => ({
...BASE_TRIM_FLAGS,
@@ -745,12 +776,11 @@ function renderFollowMpSection(qrcodeImageUrl = '') {
}
/**
* 内容卡(头条卡 / 列表卡 / 榜单卡 / 知识卡)统一以 `margin:0 0 {10|14|15|16}px` 开头
* 其余区块(Hero 12px、配图 18px、天气 11px/6px、速览、栏目标题、底部)刻意用别的起始值,
* 便于按整卡统计与裁剪。调整任何一处 margin 都必须同步这里。
* 内容卡统一以 `margin:0 0 12px` 开头(见 WX.listWrap / WX.feature / WX.rankWrap
* 便于按整卡统计与裁剪。调整 margin 时必须同步这里。
*/
const INLINE_CARD_SECTION_RE = /<section style="margin:0 0 1[0456]px[^"]*">[\s\S]*?<strong>[\s\S]*?<\/section>/g;
const INLINE_SECTION_TITLE_PREFIX = '<p style="margin:26px 0 14px;padding-bottom:8px;border-bottom:1px solid';
const INLINE_CARD_SECTION_RE = /<section style="margin:0 0 12px[^"]*">[\s\S]*?<strong>[\s\S]*?<\/section>/g;
const INLINE_SECTION_TITLE_PREFIX = '<p style="margin:20px 0 10px;padding-bottom:6px;border-bottom:1px solid';
function countInlineCards(body) {
return (String(body ?? '').match(INLINE_CARD_SECTION_RE) ?? []).length;
@@ -879,6 +909,7 @@ function fitInlineContentToBudget(html, bodyBudget, {
imageUrlMap = new Map(),
} = {}) {
const fullCounts = countSectionCards(splitSections(html));
const cappedCounts = mergeSectionCardLimits(fullCounts, DEFAULT_SECTION_CARD_LIMITS);
const render = (trimProfile) => buildWechatInlineContent(html, {
publicUrl,
qrcodeImageUrl,
@@ -890,7 +921,8 @@ function fitInlineContentToBudget(html, bodyBudget, {
let best = null;
for (const [tier, maxBodyChars] of BODY_CHAR_TIERS.entries()) {
const sectionCardLimits = { ...fullCounts };
const tierCaps = CARD_LIMIT_TIERS[tier] ?? DEFAULT_SECTION_CARD_LIMITS;
const sectionCardLimits = mergeSectionCardLimits(fullCounts, tierCaps ?? cappedCounts);
let built = render({ ...BASE_TRIM_FLAGS, sectionCardLimits, maxBodyChars });
let guard = 0;
while (built.content.length > bodyBudget && guard < 80) {
@@ -975,7 +1007,10 @@ export function convertDailyNewsHtmlToWechatInlineArticle(html, {
const fixedLayoutLengthResolved = Number.isFinite(fixedLayoutLength)
? fixedLayoutLength
: estimateFixedLayoutLength({ publicUrl, qrcodeImageUrl, portalUrl });
const bodyBudget = Math.max(12000, MAX_WECHAT_CONTENT_TARGET_CHARS - fixedLayoutLengthResolved);
const bodyBudget = Math.max(
8000,
MAX_WECHAT_CONTENT_CHARS - fixedLayoutLengthResolved - 120,
);
const fitted = fitInlineContentToBudget(html, bodyBudget, {
publicUrl,
@@ -987,8 +1022,13 @@ export function convertDailyNewsHtmlToWechatInlineArticle(html, {
const built = fitted.built;
let usedFallback = fitted.usedFallback;
let content = built?.content ?? '';
if (content.length > bodyBudget) {
content = trimWechatInlineBodyByRemovingCards(content, bodyBudget);
const maxBodyChars = includeFixedLayout
? Math.max(6000, MAX_WECHAT_CONTENT_CHARS - fixedLayoutLengthResolved)
: bodyBudget;
if (content.length > maxBodyChars) {
content = trimWechatInlineBodyByRemovingCards(content, maxBodyChars, {
minCards: MIN_CARDS_TO_KEEP,
});
usedFallback = true;
}
+24 -6
View File
@@ -33,7 +33,17 @@ const MAX_THUMB_BYTES = 64 * 1024;
export const NEWS_MORNING_TEMPLATE_REFERENCE_URL =
'https://m.tkmind.cn/MindSpace/a70ff537-8908-486e-9b6c-042e07cc25db/public/daily-news-0915.html';
export const NEWS_MORNING_TEMPLATE_VERSION = '2026-09-18-no-hot';
export const NEWS_MORNING_TEMPLATE_VERSION = '2026-09-18-refined';
export const NEWS_MORNING_SEO_SPEC = [
'【SEO / GEO 必做】',
'1. `<title>``每日新闻早报 · {YYYY年M月D日} · TKMind`。',
'2. `<meta name="description">`80160 字,含日期 + 当日 3~5 条核心标题关键词(国内/国际/财经/科技至少各 1 个)。',
'3. `<meta name="mindspace-geo">` JSONsummary120180 字)、keywords 数组(8~12 个:新闻/日期/国内/国际/财经/科技/体育/城市名/英文主题词)、faq 至少 3 组 q/a(分别覆盖国内、国际财经、科技体育)。',
'4. 每个 `.section-title` 内标题文字必须用 `<h2>` 包裹(保留 icon span),便于搜索引擎理解栏目层级。',
'5. 每条 card 的 `<h3>` 标题须含具体事件关键词,禁止「暂无」「未能获取」等空词。',
'6. footer 注明整理时间与主要来源域名,便于 GEO 引用。',
].join('\n');
/** 生产 daily-news-0915 版式:div.section + 扩展全球栏目。 */
export const NEWS_MORNING_TEMPLATE_0915_SPEC = [
@@ -42,7 +52,8 @@ export const NEWS_MORNING_TEMPLATE_0915_SPEC = [
'写页前可先 read_file 打开同目录最近 daily-news-*.html 或上述 URL 对应文件,对照 CSS 与 DOM 骨架;正文条目必须全部来自当日检索。',
'1. 外层:`.wrap` > `.hero``.hero-content` 内 h1「📰 每日新闻早报」、`.date-badge`、`.subtitle` 一句主编导语)> `.container`;禁止 `.stats` 或「X条资讯 · Y个栏目」统计行。',
'2. quick-links 固定顺序:📰 要闻|🌤️ 天气|🌍 国际|🇨🇳 国内|💰 财经|🤖 科技|🏆 体育|🔎 Google|𝕏 X|🌏 亚太|⛽ 能源|🧠 AI芯片|⚖️ 政策|🎓 高校|📈 全球股市|💬 社区|🔬 科学|🎬 文娱|🚀 创投|₿ 加密|🛡️ 地缘|🏙️ 城市|📡 权威快讯|📚 小知识|📅 历史(href 对应下方 id);禁止 id=hot / 🔥 热搜。',
'3. 区块容器必须用 `<div class="section" id="...">`(禁止 `<section id>`);`.section-title` 含 `<span class="icon">` emoji。',
'3. 区块容器必须用 `<div class="section" id="...">`(禁止 `<section id>`);`.section-title` 含 `<span class="icon">` emoji,标题文字用 `<h2>` 包裹。',
'3b. 视觉精细化:`.card` 左侧 3px 色条(tag 色系);`.card.highlight-box` 渐变底+白字;`.quick-links` 横向滚动+浅灰底圆角;hero 保留渐变与 date-badge;整体留白充足、字号层级清晰(h1 28px / h2 18px / h3 16px / p 14px)。',
'4. 区块 id 与内容:',
' - id=headlines:「今日要闻 · {完整日期}」;至少 3 条 `.card.highlight-box`tag + h3 + p + source),标题 1528 字、前 10 字有钩子。',
' - id=weather:「今日天气 · {月日}」;`.weather-today` + `.weather-grid` 812 张 `.weather-card`;热门城市(北京、上海、广州、深圳、成都、杭州、西安、重庆、武汉、南京、厦门、三亚等),禁止用区域预报顶替城市卡。',
@@ -66,7 +77,7 @@ export const NEWS_MORNING_TEMPLATE_0915_SPEC = [
' - id=knowledge:「📚 知识小卡片」;12 条短知识 card。',
' - id=history:「📅 近7天新闻早报」;列出近 7 天 daily-news-MMDD.html 链接。',
'5. 每条 cardspan.tag + h3 + p24 句)+ div.source。',
'6. footer:新闻来源列表 + 整理时间 + TKMind 品牌;meta mindspace-cover、title、description;生成 daily-news-MMDD.thumbnail.png。',
'6. footer:新闻来源列表 + 整理时间 + TKMind 品牌;必须含 title、description、mindspace-cover、mindspace-geo;生成 daily-news-MMDD.thumbnail.png。',
'7. 推送微信草稿时转为内联 style 版式(微信不支持 <style> 标签),禁止整页长图;底部追加统一「阅读原文 + 二维码」layout;公众号侧 history/knowledge 可略短。',
'8. 英文栏目允许英文标题或中英并列,但每条必须有中文可读摘要,禁止整段纯英文正文。',
'9. 全页去重(必须):同一 URL、同一核心事件只允许出现一次;若已在 headlines/world/domestic/finance/tech 出现,扩展栏目不得重复同角度,可换角度或跳过;写页前合并预取+tkmind_search+web_search 后再去重。',
@@ -217,6 +228,7 @@ export function buildNewsMorningAutoGenerationTask(config, { now = Date.now(), s
title: '每日新闻早报页面(自动)',
taskSpec: [
NEWS_MORNING_FRESH_CONTENT_SPEC,
NEWS_MORNING_SEO_SPEC,
NEWS_MORNING_TEMPLATE_0910_SPEC,
`版式参照(只读结构):${NEWS_MORNING_TEMPLATE_REFERENCE_URL}`,
`今日日期:${dateLabel.iso}${dateLabel.year}${dateLabel.month}${dateLabel.day}日)。正文必须是这一天的新闻,不能是其它日期的旧稿。`,
@@ -857,6 +869,7 @@ function defaultsFromEnv(env = process.env) {
sourceUserId: String(env.H5_WECHAT_NEWS_MORNING_DRAFT_USER_ID ?? '').trim() || null,
pageSlugPattern: String(env.H5_WECHAT_NEWS_MORNING_DRAFT_SLUG ?? 'daily-news-*').trim() || 'daily-news-*',
author: String(env.H5_WECHAT_NEWS_MORNING_DRAFT_AUTHOR ?? 'TKMind').trim() || 'TKMind',
openComment: normalizeBoolean(env.H5_WECHAT_NEWS_MORNING_DRAFT_OPEN_COMMENT, true),
forceGenerateOnce: false,
templateVersion: NEWS_MORNING_TEMPLATE_VERSION,
};
@@ -914,6 +927,7 @@ export function createWechatNewsMorningDraftService(
sourceUserId: String(stored.sourceUserId ?? defaults.sourceUserId ?? '').trim() || null,
pageSlugPattern: String(stored.pageSlugPattern ?? defaults.pageSlugPattern).trim() || defaults.pageSlugPattern,
author: String(stored.author ?? defaults.author).trim().slice(0, 8) || defaults.author,
openComment: normalizeBoolean(stored.openComment, defaults.openComment),
forceGenerateOnce: normalizeBoolean(stored.forceGenerateOnce, false),
taskSpecAppend: String(stored.taskSpecAppend ?? '').trim(),
templateVersion: NEWS_MORNING_TEMPLATE_VERSION,
@@ -1000,7 +1014,7 @@ export function createWechatNewsMorningDraftService(
article,
template: {
version: NEWS_MORNING_TEMPLATE_VERSION,
spec: [NEWS_MORNING_FRESH_CONTENT_SPEC, NEWS_MORNING_TEMPLATE_0910_SPEC].join('\n'),
spec: [NEWS_MORNING_FRESH_CONTENT_SPEC, NEWS_MORNING_SEO_SPEC, NEWS_MORNING_TEMPLATE_0910_SPEC].join('\n'),
},
};
}
@@ -1057,7 +1071,7 @@ export function createWechatNewsMorningDraftService(
getTemplate() {
return {
version: NEWS_MORNING_TEMPLATE_VERSION,
spec: [NEWS_MORNING_FRESH_CONTENT_SPEC, NEWS_MORNING_TEMPLATE_0910_SPEC].join('\n'),
spec: [NEWS_MORNING_FRESH_CONTENT_SPEC, NEWS_MORNING_SEO_SPEC, NEWS_MORNING_TEMPLATE_0910_SPEC].join('\n'),
};
},
@@ -1102,6 +1116,10 @@ export function createWechatNewsMorningDraftService(
payload.author === undefined
? current.author
: String(payload.author ?? current.author).trim().slice(0, 8) || current.author,
openComment:
payload.openComment === undefined
? current.openComment
: normalizeBoolean(payload.openComment, current.openComment),
forceGenerateOnce:
payload.forceGenerateOnce === undefined
? current.forceGenerateOnce
@@ -1249,7 +1267,7 @@ export function createWechatNewsMorningDraftService(
content: article.content,
content_source_url: article.contentSourceUrl,
thumb_media_id: thumbMediaId,
need_open_comment: 0,
need_open_comment: config.openComment !== false ? 1 : 0,
only_fans_can_comment: 0,
},
{ wechatFetch },