mcpField
P
publish-md-to-wechat

publish-md-to-wechat

github.com/walk4rever营销与增长350 次安装12 周前更新
代码仓库

关于 publish-md-to-wechat

用于将 Markdown 文章发布到微信公众号草稿、渲染微信视频号视频,以及翻译文章后转载的技能。它通过不同流程处理文章样式、图片与封面,以及视频规划和验证。

主要功能

  1. 01将 Markdown 文章排版后发布为草稿
  2. 02处理文章图片并生成封面
  3. 03渲染带旁白和字幕的竖屏 MP4
  4. 04全文翻译后发布为草稿
  5. 05创建和管理自定义文章样式

适用场景

  1. 01将 Markdown 文章发布到微信
  2. 02把文章制作为带旁白的竖屏视频
  3. 03翻译外文文章后转载
  4. 04调整 Vault 文章的发布用 frontmatter

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/walk4rever/publish-md-to-wechat --skill publish-md-to-wechat

安装后在 Claude Code 中输入/publish-md-to-wechat确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

.gitignore
AGENTS.md
env.example
SECURITY.md
README.md
LICENSE
TODO.md
CNAME
package-lock.json
package.json
pyproject.toml
index.html
install.sh
requirements.txt
evals/
evals.json
evals/files/
test.md
test_features.md
references/
styles.md
wechat_logic.md
scripts/
air7_publisher.py
clear_drafts.py
render_formulas.js
video_publisher.py
video_pipeline.py
generate_cover.py
styles.py
wechat_publisher.py
templates/video/
gen_scenes.py
tests/
test_styles.py
test_video_pipeline.py

详细介绍

publish-md-to-wechat

将 Markdown 文章发布到微信公众号草稿,提供专业的视觉样式、自动图片处理和封面生成。

运行模式(严格边界)

模式 A — 文章发布(公众号图文)

用户希望将 Markdown 发布为微信草稿时使用。

  • 输入:--md、样式、可选的缩略图/标题
  • 输出:微信草稿媒体 ID
  • 命令系列:scripts/wechat_publisher.py
模式 B — 视频渲染(视频号)

用户希望生成竖屏 MP4 时使用。

  • 输入:源文章,以及时长、语气、受众、视觉风格和可选的 Edge TTS 语音
  • 输出:本地 .mp4
  • 命令系列:scripts/video_publisher.py
  • 重要: Agent 负责规划视频并创建项目文件;脚本负责渲染、旁白、字幕、合成和采集验证帧。
模式 C — 翻译与转载(全文翻译/转载)

用户希望翻译外语文章并发布到微信时使用。

  • 触发条件:"全文翻译"、"转载"、"translate"、"repost",或源文章使用英语/其他语言。
  • 输入:源 Markdown 文件(英语或其他语言)
  • 输出:微信草稿媒体 ID(与模式 A 相同)
  • 工作流:Agent 原生翻译(不使用 Python 脚本)→ 保存到 /tmp/translated_article.md → 按模式 A 继续。
  • 重要: 翻译由 Agent 自行完成,不使用任何脚本通过 Python 调用大模型进行翻译。

除非用户明确要求同时交付两项内容,否则不要在同一流程中混用模式 A 和模式 B 的步骤。 模式 C 始终以模式 A 发布结束——它是预处理步骤,而不是单独的流程。

阶段 1:环境与凭据

检查依赖项:

ls .venv/bin/python 2>/dev/null || echo "MISSING"

如果缺少 .venv,运行 ./install.sh。

凭据: 自动从当前目录中的 .env 加载;若不存在,则使用全局备用文件 ~/.config/publish-md-to-wechat/.env。只有脚本明确因身份验证错误而失败时,才向用户索取凭据。


阶段 1B:模式 C — 翻译与转载

不要总结或改写——忠实翻译全文。

  1. 完整阅读源 Markdown 文件。
  2. 将全文翻译成中文,并保留:
    • 所有 Markdown 结构(标题、列表、代码块、引用块、图片)
    • 原始章节顺序和层级
    • 标准情况下使用英语的技术术语(例如 agent、token、context window、bash)
    • 代码块原文照录——不要翻译代码
    • frontmatter 中的作者署名:> 本文译自:[原文标题](url),作者:[Author]([Publication])
  3. 使用中文编写包含 title、author、description 的 YAML frontmatter。
  4. 保存到 /tmp/translated_article.md。
  5. 将翻译后的文件作为 --md 参数,继续执行阶段 2。

翻译前不要征求确认——如果用户说了“全文翻译/转载”,就直接翻译。

阶段 1C:Frontmatter 适配(Vault 文章)

发布任何 Vault 文章前,请确认 frontmatter 包含 WeChat 发布器正确渲染文章标题区域所需的字段。

发布器会使用以下特定键,在每篇文章顶部渲染元数据块:

WeChat 键渲染为常见 Vault 别名操作
author作者相同✅ 通常已存在
published发布日期date⚠️ 如果仅存在 date:,则添加 published:
tags标签列表—⚠️ 缺失时添加
description摘要excerpt⚠️ 如果仅存在 excerpt:,则添加 description:
source来源—⚠️ 为 Vault 文章添加 source: AI-DIVE · ai.air7.fun

脚本回退(内置): 发布器脚本会自动回退:

  • 如果缺少 published,则使用 date
  • 如果缺少 description,则使用 excerpt

因此,发布前无需手动修补这两组别名。其余三个键(author、tags、source)没有自动别名——若缺失,请将其添加到 frontmatter。

Vault → WeChat 文章的最简完整 frontmatter:

---
title: 文章标题
slug: type-YYYY-MM-DD-topic          # ai-dive API
date: YYYY-MM-DD                     # ai-dive API
published: YYYY-MM-DD                # WeChat header display
type: analysis                       # ai-dive API
author: Rafa
tags: [标签1,标签2, 标签3]           # WeChat header display
excerpt: 摘要文字                     # ai-dive API
description: 摘要文字                 # WeChat header display (same content as excerpt)
source: AI-DIVE · ai.air7.fun       # WeChat header display
og_image: https://...               # ai-dive cover (fill after upload)
cover: assets/topic-cover.png       # local preview
---

注意: date 和 published 的值相同;excerpt 和 description 的内容相同——两个系统对同一概念使用了不同的键。


阶段 2:阅读文章并选择样式

阅读 Markdown 文件,了解内容的语气,然后选择样式。

列出所有样式:

.venv/bin/python3 scripts/styles.py --list

样式选择指南:

类别样式适用场景
⭐ 核心swiss、editorial、ink默认选择。适用于 90% 的内容类型。
📦 扩展notebook、geometry、botanical、terminal、bold、cyber、voltage仅适用于特定场景。
🎨 自定义custom-xxx根据 WeChat 文章分析创建的用户自定义样式。

三种核心样式速览:

  • swiss — 技术文章、教程、报告、官方公告
  • editorial — 评论文章、分析、博客文章、个人品牌
  • ink — 人文、文化、深度内容、文学内容

用一句话说明理由并推荐样式。若用户已指定,则跳过。


阶段 3:先验证(复杂文章建议执行)

.venv/bin/python3 scripts/wechat_publisher.py \
  --md [PATH] --style [STYLE] --dry-run --out-html /tmp/preview.html
open /tmp/preview.html

阶段 4:发布

.venv/bin/python3 scripts/wechat_publisher.py \
  --md [PATH] --style [STYLE]

重要标志:

  • --thumb [PATH] — 自定义封面(省略时自动生成)
  • --title "[TITLE]" — 覆盖标题(自动从 frontmatter/H1 检测)
  • --no-verify-ssl — 适用于 SSL 证书问题
  • -v — 详细日志

YAML Frontmatter: 自动提取标题、作者和描述:

---
title: Article Title
author: Author Name
description: Short summary for WeChat article list.
---

第 4B 阶段:生成微信视频(视频号)

默认情况下,始终生成带 TTS 配音的视频,除非用户明确要求不要配音。 **重要:**生成视频前,如果用户尚未在请求中明确提供以下偏好,你必须先询问:

  1. 目标时长(例如 30s、60s、90s)
  2. 旁白语气(例如 专业克制、轻松幽默、热情洋溢)
  3. 目标受众(例如 AI 开发者、产品经理、大众)
  4. 视觉风格(例如 swiss、ink、minimal)
  5. TTS 音色(可选;默认使用 zh-CN-YunxiNeural)

**不要猜测或假定这 5 项参数。**如果用户只说“转换成视频”,你必须停下来,先询问时长、语气、受众和风格。

第 1 步:Agent 规划场景(不要使用 Python 脚本调用大模型) 阅读 Markdown 文件。以专业演示文稿编辑的身份,原生创建视频项目目录,其中包含 scenes.txt 和 gen_scenes.py,并根据用户要求的时长、语气、受众和视觉风格进行编写。

先创建项目;不要从空白 Python 文件开始:

.venv/bin/python3 scripts/video_publisher.py --init-project /tmp/video-project

然后编辑 /tmp/video-project/scenes.txt 和 /tmp/video-project/gen_scenes.py。随附的生成器是视觉基准:保留其 1080×1920 画布、品牌行、页码、底栏、对比度和通用 CSS;根据故事调整文案和布局。

关键:旁白质量规则(避免填充内容和重复)

  • 受众和语气是全局约束,不是每个场景的口号。不要在每个场景里反复说“面向 AI 开发者”或“关键在于”之类的话。
  • 每个场景的旁白都必须补充新信息(事实、示例、对比、行动步骤),不能用模板化内容凑字数。
  • 禁止使用空洞的引入语:“我们来看看”“关键在于”“总的来说”,除非后面紧接具体内容。
  • 旁白要简洁、口语化:每个场景通常用 1-3 个短句;避免长篇独白。
  • 避免在不同场景中重复相同的句式。
  • 尽量使用具体措辞,避免抽象的流行语。

写入文件前进行旁白自检:

  1. 从头到尾阅读所有场景的旁白。
  2. 如果某个短语词干在 3 个或更多场景中重复出现(例如“面向…”“关键在…”),请改写。
  3. 确保每个场景都能用一句话概括独特的要点。
  4. 删除所有没有信息量的填充内容。

关键:竖屏视频(9:16)的 HTML 场景格式

  • scenes.txt 每行包含一个按顺序排列的场景:S1|口播旁白|可选的书面字幕。
  • gen_scenes.py 必须在 1080×1920 分辨率下生成 scenes/S1.html、scenes/S2.html,依此类推。
  • 在生成器中使用共享 CSS 系统:稳定的品牌行、页码、底部信息栏、高对比度文字和克制的强调色。
  • 口播和字幕内容可以因 URL 和英文术语而有所不同。例如,口播念 air7 点 fun,字幕写 air7.fun。
  • 每个场景只讲一个要点。脚本会根据生成的音频推算时长,加入短暂的换气间隔,并将字幕烧录到视频中。

第 2 步:渲染与合成(仅执行) 使用脚本生成 HTML、截取 PNG 场景、合成旁白、创建字幕、合成 MP4,并截取开头、中间和结尾的 QA 帧。

# 导出 MP4
.venv/bin/python3 scripts/video_publisher.py \
  --project-dir /tmp/video-project \
  --duration [SECONDS] \
  --voice zh-CN-YunxiNeural \
  --rate +6% \
  --out [OUTPUT.mp4]

依赖项:ffmpeg、Python Playwright Chromium 和 edge-tts。

第 3 步:强制视觉 QA 打开 build/check_start.jpg、build/check_middle.jpg 和 build/check_end.jpg。检查字幕换行、对比度是否清晰、文案是否溢出、拼写是否正确,以及旁白与场景是否匹配。如果有任何一帧未通过检查,只修改 scenes.txt / gen_scenes.py 中受影响的场景,然后重新运行渲染器。未通过此检查时,不得报告视频已完成。


第 5 阶段:成功输出

## 🚀 发布成功!

| 字段 | 值 |
|------|-----|
| **标题** | [Title] |
| **风格** | `[style]` — [one-line description] |
| **Media ID** | `[MEDIA_ID]` |

**下一步:** mp.weixin.qq.com → 草稿箱 → 预览 → 发布

自定义样式

样式复刻使用 Playwright 的 getComputedStyle()(而非解析内联 CSS)来准确获取颜色, 并自动检测结构模式:

  • 标题样式:bg-block(彩色区块背景)/ left-border / underline / plain
  • 引用块样式:left-border / full-box / plain

使用自定义样式发布时,渲染器会应用这些结构提示。

# Create from WeChat article (give it a meaningful name)
.venv/bin/python3 scripts/styles.py --url https://mp.weixin.qq.com/s/xxx --name custom-myname --no-verify-ssl

# List all styles (core / extend / custom)
.venv/bin/python3 scripts/styles.py --list

# Rename
.venv/bin/python3 scripts/styles.py --rename custom-old custom-new

# Use
.venv/bin/python3 scripts/wechat_publisher.py --md article.md --style custom-xxx

故障排除

错误解决方法
40164 IP 白名单前往 mp.weixin.qq.com → 设置与开发 → IP白名单,添加 IP
40125 / 40013 凭据无效检查 .env
45009 请求频率限制自动重试;如果问题仍然存在,请稍候
45166 内容无效(锚点链接)文章包含 href="#anchor" 链接(例如目录)。自 v0.7.0 起,后处理器会自动移除这些链接。如果旧版本遇到此问题,请升级。
SSL 错误添加 --no-verify-ssl
找不到图片检查文件名(区分大小写),确保图片位于文章目录中
封面失败回退使用 assets/default_thumb.png;或使用 --thumb
缺少依赖项运行 ./install.sh

微信渲染的已知限制

以下是微信 HTML 渲染器的平台级限制,自 v0.7.0 起由后处理器自动处理:

限制表现自动修复
图片必须包含 data-src微信使用 data-src 延迟加载图片。仅包含 src 的图片会显示为空白。后处理器会在 URL 上传后为每个 <img> 添加 data-src。
<ol>/<li> 空白节点<li> 标签之间的空白文本节点会被渲染成额外的空白编号项。后处理器会将整个 .footnotes 区域重建为扁平的 <section> 元素,并使用内联编号。
锚点链接(href="#")被屏蔽只要存在 <a href="#...">,草稿 API 就会返回 45166。后处理器会将所有以 # 开头的 <a> 标签展开为纯文本。
脚注反向链接mistune 会在每条脚注末尾插入一个 ↩ 返回链接,在微信中没有意义。后处理器会移除所有 <a class="footnote"> 标签,并清除残留的 ↩ 字符。

评论

支持 Markdown