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:
@@ -35,6 +35,7 @@ async function main() {
|
||||
'以及 google / x / universities / global_markets。',
|
||||
'全页去重:同一 URL 或同一核心事件只允许出现一次;主栏目优先,扩展栏目必须换角度或跳过。',
|
||||
'禁止 id=hot 热搜栏目;禁止 .stats 或「X条资讯 · Y个栏目」统计行。',
|
||||
'SEO:title/description/mindspace-geo/faq 必做;section-title 内用 h2;card 左侧色条 + highlight 渐变。',
|
||||
'英文栏目标题可英文,每条必须有中文摘要与来源 URL;禁止整段纯英文正文。',
|
||||
].join('\n'),
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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">`:80~160 字,含日期 + 当日 3~5 条核心标题关键词(国内/国际/财经/科技至少各 1 个)。',
|
||||
'3. `<meta name="mindspace-geo">` JSON:summary(120~180 字)、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),标题 15~28 字、前 10 字有钩子。',
|
||||
' - id=weather:「今日天气 · {月日}」;`.weather-today` + `.weather-grid` 8~12 张 `.weather-card`;热门城市(北京、上海、广州、深圳、成都、杭州、西安、重庆、武汉、南京、厦门、三亚等),禁止用区域预报顶替城市卡。',
|
||||
@@ -66,7 +77,7 @@ export const NEWS_MORNING_TEMPLATE_0915_SPEC = [
|
||||
' - id=knowledge:「📚 知识小卡片」;1~2 条短知识 card。',
|
||||
' - id=history:「📅 近7天新闻早报」;列出近 7 天 daily-news-MMDD.html 链接。',
|
||||
'5. 每条 card:span.tag + h3 + p(2~4 句)+ 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 },
|
||||
|
||||
Reference in New Issue
Block a user