mcpField
W
wechat-article-formatter

wechat-article-formatter

github.com/iamzifei营销与增长76230 次安装11 周前更新
代码仓库

关于 wechat-article-formatter

wechat-article-formatter 将 Markdown 文章排版为带样式的 HTML,并发布到微信公众号草稿。它会把图片上传至微信,并使用官方草稿 API 保留行内样式。

主要功能

  1. 01使用 bm.md 样式渲染 Markdown
  2. 02将文章图片上传至微信 CDN
  3. 03用 CDN 地址替换图片路径
  4. 04通过官方 API 发布草稿
  5. 05提取摘要并确定作者信息

适用场景

  1. 01将 Markdown 文章排版为公众号内容
  2. 02准备文章图片和封面素材
  3. 03将排版后的文章发布为公众号草稿

安装

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

$npx skills add https://github.com/iamzifei/wechat-article-formatter-skill --skill wechat-article-formatter

安装后在 Claude Code 中输入/wechat-article-formatter确认已加载。

包含的文件

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

README.md
README.zh-CN.md
.gitignore
styles/
custom.css

详细介绍

微信公众号文章排版与发布

使用 bm.md 样式排版 Markdown 文章,并通过官方 API 直接发布到微信公众号草稿箱。

概述

  1. 读取 Markdown 文件(通常是文章目录中的 wechat.md)
  2. 通过 media/uploadimg API 将本地图片上传到微信 CDN
  3. 将 Markdown 中的本地图片路径替换为微信 CDN URL
  4. 通过 bm.md API 和自定义 CSS 将 Markdown 渲染为带样式的 HTML
  5. 通过官方 draft/add API 发布到微信草稿箱

重要:不要使用第三方发布 API(例如微绿 wechat-publish)。它们会移除内联 CSS 样式。始终直接使用微信官方 draft/add API。

凭据

从 ~/.env 读取:

变量用途
WECHAT_APP_ID微信公众号 AppID
WECHAT_APP_SECRET微信公众号 AppSecret

如果未找到,请提示用户提供凭据并保存到 ~/.env。

工作流

步骤 1:确定输入文件

用户会提供 Markdown 文件路径(例如文章目录中的 wechat.md)。

查找文章目录以确定:

  • promotion.md → 提取摘要
  • _attachments/ → 本地图片
  • 对话上下文中的品牌配置 → 作者姓名
步骤 2:获取微信 Access Token
params = urlencode({
    'grant_type': 'client_credential',
    'appid': WECHAT_APP_ID,
    'secret': WECHAT_APP_SECRET
})
# GET https://api.weixin.qq.com/cgi-bin/token?{params}

如果出现错误 40164(IP 不在白名单中),请指引用户前往:mp.weixin.qq.com → 设置与开发 → 基本配置 → IP白名单 添加该 IP。

步骤 3:将图片上传到微信 CDN

重要:在同一会话中上传所有图片。之前会话中的微信 CDN URL 可能会过期。

使用 media/uploadimg API 上传正文内的图片:

# POST https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token={token}
# Content-Type: multipart/form-data
# Body: media=@image_file
# Response: {"url": "http://mmbiz.qpic.cn/..."}

使用 material/add_material API 上传封面/缩略图:

# POST https://api.weixin.qq.com/cgi-bin/material/add_material?access_token={token}&type=image
# Content-Type: multipart/form-data
# Body: media=@cover_image
# Response: {"media_id": "...", "url": "..."}

对于远程图片(例如 https://i.ibb.co/...),请先下载,再上传到微信 CDN。

上传后,在渲染前将 Markdown 中所有本地/远程图片路径替换为微信 CDN URL。

步骤 4:使用 bm.md 渲染

从 {{SKILL_DIR}}/styles/custom.css 读取自定义 CSS。

重要:将 JSON 负载写入临时文件,并使用 curl -d @file,以避免 Shell 转义问题。

payload = json.dumps({
    "markdown": md_content,
    "markdownStyle": "green-simple",
    "codeTheme": "kimbie-light",
    "customCss": css_content,
    "enableFootnoteLinks": True,
    "openLinksInNewWindow": True,
    "platform": "wechat"
}, ensure_ascii=False)

# Write to /tmp/bm-payload.json, then:
# curl -s -X POST https://bm.md/api/markdown/render \
#   -H "Content-Type: application/json" \
#   -d @/tmp/bm-payload.json

ensure_ascii=False 至关重要——否则中文字符会变成 \uXXXX 转义序列。

步骤 5:发布到微信草稿箱
draft_payload = json.dumps({
    "articles": [{
        "title": title,
        "author": author,                    # e.g. "在悉尼和稀泥"
        "thumb_media_id": thumb_media_id,     # from Step 3 material upload
        "content": html,                      # from Step 4 bm.md render
        "digest": digest,                     # from promotion.md, max ~60 Chinese chars
        "need_open_comment": 1,               # enable comments
        "only_fans_can_comment": 0,           # allow all users to comment
        "original_article_type": 1,           # declare as original content
        "reward_wording": "喜欢这篇文章,请我喝杯咖啡",  # enable tipping
        "creation_source_type": 1             # 个人观点,仅供参考
    }]
}, ensure_ascii=False).encode('utf-8')

# POST https://api.weixin.qq.com/cgi-bin/draft/add?access_token={token}

默认发布设置:

字段值说明
need_open_comment1开启评论
only_fans_can_comment0所有用户均可评论
original_article_type1声明为原创
reward_wording"喜欢这篇文章,请我喝杯咖啡"开启赞赏
creation_source_type1个人观点,仅供参考

从 promotion.md 提取摘要:

查找 ## 文章摘要 章节,提取文本并截断至约 60 个中文字符(微信限制为 120 字节)。

作者确定顺序(采用首个匹配项):

  1. 用户明确指定
  2. 品牌配置中的 author 字段
  3. 品牌配置中的 品牌名称 字段
步骤 6:报告结果
WeChat Publishing Complete!

Title: {title}
Author: {author}
Digest: {digest}
Original: ✓ declared
Tipping: ✓ enabled
Comments: ✓ open to all
Images: {N} uploaded to WeChat CDN
media_id: {media_id}

→ Preview at: https://mp.weixin.qq.com (内容管理 → 草稿箱)

微信 Markdown 内容顺序

编写微信 Markdown 时,内容元素应按以下顺序排列:

1. 关注引导文字 (e.g. 👆 「关注」加「星标」...)
2. 封面图 (cover image)
3. --- 分隔线
4. 正文内容 (article body with inline images)
5. --- 分隔线
6. 作者介绍 (about author section)
7. --- 分隔线
8. 推广区块 (promo blockquote with image)
9. --- 分隔线
10. 互动引导 (engagement CTA)

应从 Markdown 中移除 H1 标题——微信会使用 title 字段显示标题。

常见问题

问题解决方案
中文显示为 \uXXXX在所有 json.dumps() 调用中使用 ensure_ascii=False
图片无法显示在同一会话中上传;不要重复使用旧的 CDN URL
样式被移除(显示为纯文本)使用微信官方 draft/add API,而非第三方 API
40164 IP 白名单错误前往 mp.weixin.qq.com → 基本配置 → IP白名单 添加当前 IP
45004 摘要过长摘要保持在 60 个中文字符以内
40007 media_id 无效先通过 material/add_material 上传封面,以获取 thumb_media_id
> [!NOTE] 渲染异常将 GitHub 提示转换为普通的 > 引用块,以便在微信中显示

bm.md API 参考

渲染:POST https://bm.md/api/markdown/render

参数类型默认值描述
markdownstring必填Markdown 内容
markdownStylestringayu-light样式 ID(使用 green-simple)
codeThemestringkimbie-light代码高亮主题
customCssstring""作用域限定为 #bm-md 的自定义 CSS
enableFootnoteLinksbooleantrue将链接转换为脚注
openLinksInNewWindowbooleantrue在新窗口中打开链接
platformstringhtml目标平台:html、wechat、zhihu、juejin

可用样式:ayu-light、bauhaus、blueprint、botanical、green-simple、maximalism、neo-brutalism、newsprint、organic、playful-geometric、professional、retro、sketch、terminal

样式功能

自定义 CSS(styles/custom.css)提供:

  • Optima/Microsoft YaHei 字体
  • 绿色强调色(rgb(53, 179, 120))
  • H2 标题:黑色背景上的白色文字
  • 粗体文字:绿色
  • 引用块:绿色左边框
  • 带交替行颜色的响应式表格
  • 深色背景的代码块

依赖项

  • 微信公众号 API 凭据(~/.env)
  • bm.md 渲染服务(无需身份验证)
  • 位于 {{SKILL_DIR}}/styles/custom.css 的自定义 CSS

新手上路(用户不知道该输入什么时,走这里)

触发:/公众号排版 新手、「这个怎么用」「第一次用」「能干嘛」「带我走一遍」, 以及用户输入了技能名却没有给任何任务的时候。

这个模式的铁律:不假设、不索取。用户可能什么都没准备, 不要一上来就问他要文件、要 API key、要具体需求。按下面四步走:

一、先说清楚这是什么(三句话以内)

一句话:把 Markdown 排成公众号能直接用的样式。 公众号编辑器不认 Markdown,手动调格式很费时间, 这个技能把排版做完,还能换主题。

二、给编号选项,让他按回车就能继续

不要问开放式问题(「你想做什么?」对新手是负担)。给 3 个选项加一个默认:

想先看哪个?(直接回车 = 1)
  1. 先看看排出来长什么样(示例)
  2. 排我的这篇 Markdown
  3. 有哪些主题可以选

三、直接演示一遍,边做边解释

选完立刻做给他看,用示例数据,不需要他提供任何东西。 每做完一步,加一行「💡 刚才发生了什么」,一句话说明这步的意义。

四、毕业

演示完只问一个是非题:「要不要用你自己的文章真跑一遍?」 答是就进正常流程;答否就告诉他随时回来输 /公众号排版 新手。

评论

支持 Markdown