关于 publish-md-to-wechat
用于将 Markdown 文章发布到微信公众号草稿、渲染微信视频号视频,以及翻译文章后转载的技能。它通过不同流程处理文章样式、图片与封面,以及视频规划和验证。
主要功能
- 01将 Markdown 文章排版后发布为草稿
- 02处理文章图片并生成封面
- 03渲染带旁白和字幕的竖屏 MP4
- 04全文翻译后发布为草稿
- 05创建和管理自定义文章样式
适用场景
- 01将 Markdown 文章发布到微信
- 02把文章制作为带旁白的竖屏视频
- 03翻译外文文章后转载
- 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 外,安装时一起下载的参考资料和脚本。
.gitignoreAGENTS.mdenv.exampleSECURITY.mdREADME.mdLICENSETODO.mdCNAMEpackage-lock.jsonpackage.jsonpyproject.tomlindex.htmlinstall.shrequirements.txtevals/evals.jsonevals/files/test.mdtest_features.mdreferences/styles.mdwechat_logic.mdscripts/air7_publisher.pyclear_drafts.pyrender_formulas.jsvideo_publisher.pyvideo_pipeline.pygenerate_cover.pystyles.pywechat_publisher.pytemplates/video/gen_scenes.pytests/test_styles.pytest_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 — 翻译与转载
不要总结或改写——忠实翻译全文。
- 完整阅读源 Markdown 文件。
- 将全文翻译成中文,并保留:
- 所有 Markdown 结构(标题、列表、代码块、引用块、图片)
- 原始章节顺序和层级
- 标准情况下使用英语的技术术语(例如 agent、token、context window、bash)
- 代码块原文照录——不要翻译代码
- frontmatter 中的作者署名:
> 本文译自:[原文标题](url),作者:[Author]([Publication])
- 使用中文编写包含
title、author、description的 YAML frontmatter。 - 保存到
/tmp/translated_article.md。 - 将翻译后的文件作为
--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 配音的视频,除非用户明确要求不要配音。 **重要:**生成视频前,如果用户尚未在请求中明确提供以下偏好,你必须先询问:
- 目标时长(例如 30s、60s、90s)
- 旁白语气(例如 专业克制、轻松幽默、热情洋溢)
- 目标受众(例如 AI 开发者、产品经理、大众)
- 视觉风格(例如 swiss、ink、minimal)
- 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 个短句;避免长篇独白。
- 避免在不同场景中重复相同的句式。
- 尽量使用具体措辞,避免抽象的流行语。
写入文件前进行旁白自检:
- 从头到尾阅读所有场景的旁白。
- 如果某个短语词干在 3 个或更多场景中重复出现(例如“面向…”“关键在…”),请改写。
- 确保每个场景都能用一句话概括独特的要点。
- 删除所有没有信息量的填充内容。
关键:竖屏视频(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"> 标签,并清除残留的 ↩ 字符。 |