
md2wechat
by VO-VOO
WeChat Official Account CLI: upload images, create drafts
SKILL.md
name: md2wechat description: Convert Markdown articles to WeChat Official Account formatted HTML with beautiful themed layouts. Use when user wants to convert markdown to WeChat article, publish to WeChat, or format articles for WeChat Official Account.
MD to WeChat
将 Markdown 文章转换为微信公众号格式的精美 HTML。
重要:你(AI)负责生成 HTML,不要调用 CLI 的 convert 命令。CLI 只用于上传图片和草稿。
默认输出目录:读取文章后,默认在桌面创建一个与文章同名的文件夹,并在该目录生成中间与最终文件(HTML/JSON)。只有当用户明确表示“可以放在当前目录”,才使用当前目录。
工作流程
[ ] Step 1: 分析 Markdown 结构和图片
[ ] Step 2: 确认主题选择
[ ] Step 3: 你自己生成 HTML(读取主题 prompt)
[ ] Step 4: 上传图片并替换占位符(调用 CLI)
[ ] Step 5: 上传草稿到微信(调用 CLI)
Step 1: 分析 Markdown
读取用户提供的 Markdown 文件,提取以下信息:
长度判断与分段:如果正文超过约 3000 字,必须按约 3000 字分段处理,但始终生成单个 HTML 文件。做法:分段生成 HTML 片段,最后合并为一个完整 HTML。
| 元素 | 提取方式 |
|---|---|
| 标题 | 文章文件名(优先作为标题) |
| 作者 | frontmatter 中的 Author: 或 作者: |
| 摘要 | 首段内容(最多 120 字符) |
| 图片列表 | 收集所有  引用,记录顺序 |
| 结构 | 标题层级、列表、代码块、引用、表格 |
图片类型:
| 类型 | 语法示例 |
|---|---|
| 本地图片 |  |
| 在线图片 |  |
Step 2: 确认主题
询问用户选择主题:「你想使用哪个主题样式?」
可用主题:
| 主题 | 风格 | 适用场景 |
|---|---|---|
latte | Catppuccin Latte,柔和亮色调 | 日常随笔、知识分享 |
autumn-warm | 秋日暖光,温暖橙色调 | 情感故事、生活随笔 |
spring-fresh | 春日清新,自然绿色调 | 旅行日记、自然主题 |
violet | 鸢尾花优雅,理性紫色调 | 技术文章、商业分析 |
apple-minimal | Apple 极简,黑白灰调 | 产品介绍、技术文档 |
默认:用户未指定时使用 latte。
theme 的使用方法在 references/themes.md 中查看
Step 3: 你自己生成 HTML
重要:这一步由你(AI)直接完成,不调用任何 CLI 命令。
3.1 读取主题文件
根据用户选择的主题,读取对应的 YAML 文件:
themes/latte.yaml
themes/autumn-warm.yaml
themes/spring-fresh.yaml
themes/violet.yaml
themes/apple-minimal.yaml
主题文件位于本 skill 的 themes/ 目录。
3.2 提取 prompt
从 YAML 文件中提取 prompt 字段,这是完整的样式指令。
3.3 拼接内容
将用户的 Markdown 内容追加到 prompt 末尾。
3.4 生成 HTML
根据 prompt 指令生成微信兼容的 HTML,必须遵守以下规则:
长度控制:若正文超过 3000 字,按约 3000 字分段生成 HTML 片段,最终合并为一个完整 HTML,用于后续 JSON 生成。
必须遵守:
- 所有 CSS 必须内联(使用
style属性,不能用<style>标签) - 不能使用外部样式表或脚本
- 只使用微信安全的 HTML 标签
- 图片使用占位符格式:
<!-- IMG:0 -->、<!-- IMG:1 -->等
安全 HTML 标签:
p, br, strong, em, u, a
h1, h2, h3, h4, h5, h6
ul, ol, li
blockquote, pre, code
table, thead, tbody, tr, th, td
section, span, div, img
禁止使用:
script, iframe, form, style(标签)
外部 CSS/JS 引用
position: fixed/absolute
微信关键要求:
- 在
<body>后立即创建主容器<div>承载全局样式 - 每个
<p>标签必须显式指定color(微信会重置为黑色) - 使用内联
style而非类名 - 列表优先不用
<ul>/<li>:微信会二次渲染列表,容易出现重复 bullet- 推荐方案:改为多个
<p>,在每行前用<span>手动放 bullet(全内联样式) - 若必须用
<ul>/<li>:ul设list-style: none; padding-left: 0;,并在每个<li>内加入自定义 bullet<span>(全内联样式)
- 推荐方案:改为多个
- HTML 不要再输出
<h1>标题;标题已由文件名提供,不在正文重复
Step 3.5: CLI 首次安装与配置
在调用任何 CLI 之前,先确保 CLI 已安装并完成配置。
运行本 skill 目录下的 scripts/first-run.py:
uv run python <本skill目录>/scripts/first-run.py
注意:如果未安装
uv,先安装它,然后再执行以上命令。
脚本会自动识别系统类型,下载 CLI 到本地目录,并初始化配置文件。
Step 4: 上传图片并替换占位符
如果用户希望上传到微信,需要调用 CLI 将图片上传到微信素材库。
4.1 上传图片(调用 CLI)
本地图片:
md2wechat upload_image ./path/to/image.jpg
在线图片(自动下载后上传):
md2wechat download_and_upload https://example.com/image.jpg
返回结果:
{"success": true, "data": {"wechat_url": "https://mmbiz.qpic.cn/...", "media_id": "xxx"}}
用途:
data.wechat_url用于正文<img src="...">data.media_id可作为thumb_media_id(封面图)
4.2 替换占位符
将 HTML 中的占位符替换为微信 URL:
<!-- 替换前 -->
<!-- IMG:0 -->
<!-- 替换后 -->
<img src="https://mmbiz.qpic.cn/..." style="max-width: 100%;" />
占位符规则:
- 从 0 开始编号,按图片在 Markdown 中出现的顺序
- 必须使用微信图床 URL(
mmbiz.qpic.cn),外部 URL 无法显示
Step 5: 上传草稿到微信
询问用户:「你希望预览 HTML 还是直接上传到微信草稿箱?」
选项 1: 预览模式
在代码块中展示 HTML,用户可复制到微信编辑器。
选项 2: 上传到微信草稿箱
流程:生成 HTML 和 meta.json 两个文件,然后调用 Python 脚本合并生成 draft.json。
5.1 你(AI)生成两个文件
文件 1:article.html - 完整的 HTML 内容
文件 2:meta.json - 元数据(不含正文内容)
{
"title": "文章标题",
"author": "作者名",
"digest": "文章摘要(最多120字符)",
"thumb_media_id": "封面图的 media_id(来自 upload_image 返回)"
}
字段生成规则:
title:使用文章文件名author:取 frontmatter 中的Author:或作者:;没有则留空或让用户指定digest:取首段正文,超过 120 字符则截断thumb_media_id:优先使用用户指定封面;否则用第一张上传图片的media_id;若无图片则提醒用户必须提供封面
5.2 调用脚本合并生成 draft.json
运行本 skill 目录下的 scripts/build_draft.py 脚本:
uv run python <本skill目录>/scripts/build_draft.py <meta.json绝对路径> <html文件绝对路径>
注意:你(AI)需要根据读取本 SKILL.md 时的实际路径,确定
scripts/build_draft.py的完整路径。
脚本会读取两个文件,合并生成 draft.json(默认输出到 HTML 文件所在目录)。
5.3 上传草稿
md2wechat create_draft draft.json
返回结果:
{"success": true, "data": {"media_id": "draft_xxx"}}
完成条件:
- 当终端返回
success: true,立刻结束任务 - 告知用户"草稿已上传成功",并提醒去微信公众号后台草稿箱查看
CLI 命令参考
| 命令 | 用途 | 示例 |
|---|---|---|
upload_image | 上传本地图片 | md2wechat upload_image ./photo.jpg |
download_and_upload | 下载并上传在线图片 | md2wechat download_and_upload https://... |
create_draft | 从 JSON 创建草稿 | md2wechat create_draft draft.json |
完整示例
用户输入
文件:article.md
# 秋日漫步
周末的午后,阳光正好...

> 生活不止眼前的代码,还有诗和远方。
## 第二章
继续写作内容...
你的处理流程
- 分析:标题"秋日漫步",1 张本地图片
./photos/park.jpg - 确认主题:用户选择
autumn-warm - 读取主题:读取
themes/autumn-warm.yaml的 prompt - 你生成 HTML:按 prompt 指令生成带内联样式的 HTML,图片位置用
<!-- IMG:0 --> - 上传图片:调用
md2wechat upload_image ./photos/park.jpg - 替换占位符:用返回的
wechat_url替换<!-- IMG:0 --> - 上传草稿:调用
md2wechat create_draft draft.json
输出示例(Step 4 之前)
<div style="background-color: #faf9f5; padding: 40px 10px;">
<section style="max-width: 800px; margin: 0 auto; background: #fff; border-radius: 18px; padding: 25px;">
<p style="color: #4a413d; line-height: 1.8;">周末的午后,阳光正好...</p>
<!-- IMG:0 -->
<blockquote style="background: #fef4e7; border-left: 4px solid #d97758; padding: 15px; color: #4a413d;">
生活不止眼前的代码,还有诗和远方。
</blockquote>
<h2 style="color: #c06b4d; font-size: 20px;">▶ 第二章</h2>
<p style="color: #4a413d; line-height: 1.8;">继续写作内容...</p>
</section>
</div>
参考文档
项目仓库
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon