微信公众号内容自动化发布流水线
一句话:素材 → 选题 → 写文章 → 配图处理 → 转微信 HTML → 存草稿箱 → 归档。
本 skill 管从素材到草稿箱的全流程,写作环节可插拔。所有账号配置(AppID/AppSecret)参数化,不绑定任何特定公众号。
什么时候用我 / 什么时候别用我
对号入座,不用猜:
| 你说的话 | 用不用 |
|---|---|
| 「把这篇文章发到公众号草稿箱」 | ✅ 用 |
| 「帮我写篇公众号文章」 | ✅ 用(4 套模板任选) |
| 「这几个选题哪个值得写」 | ✅ 用(四维评分) |
| 「这篇文章有没有 AI 味 / 帮我检查下」 | ✅ 用(质检脚本) |
| 「今天这行有什么新动态」 | ⚠️ 先按 references/collection-guide.md 采集,再进来 |
| 「帮我做张海报 / 封面图」 | ❌ 别用 —— 本 skill 不生成图片,只压缩与上传 |
| 「帮我做多源深度调研」 | ❌ 别用 —— 先走深度调研类技能 |
| 「帮我群发」 | ❌ 别用 —— 只建草稿,群发请到公众号后台人工确认 |
触发关键词(提到这些会被自动识别):公众号、草稿箱、发文章、写推文、公众号排版、选题、标题优化、去 AI 味、文章质检、一键发布。
照着说就行:8 句开场白
不用记参数、不用记流程 —— 复制下面任意一句发给 AI 就能开始(方括号换成你的内容):
| 想干什么 | 直接说这句 |
|---|---|
| 从零写一篇 | 帮我写一篇公众号文章,主题是[XX],给[谁]看的,1200 字左右,用「工具实测」模板 |
| 有素材要整理 | 把这段素材整理成公众号文章:[粘贴内容],标题多给几个备选 |
| 不知道写什么 | 最近[某个方向]有什么值得写的?给我 5 个选题并按优先级排序 |
| 改标题 | 这篇的标题帮我改改,给 3 个备选:[标题] |
| 查 AI 味 | 帮我看看这篇有没有 AI 味,逐条列出来:[文章] |
| 从链接开始 | 把这个链接的内容改成一篇公众号文章:[链接] |
| 发草稿箱 | 把这篇发到公众号草稿箱,封面用[图片]:[文章] |
| 一键全流程 | 用「资讯速递」模板写篇[主题]日报,发到草稿箱 |
三个不用管
| 你本来担心的 | 现在不用管 |
|---|---|
参数该用哪种写法(--app-id 还是 --app_id) |
三种写法都认(--app-id / --app_id / --WECHAT_APP_ID),怎么写都对 |
| 文件路径写错了怎么办 | 会提前检查并一次列全,不会跑到一半才失败 |
| 配置填错了怎么办 | 报错直接说人话 —— 例如 40164 会把「需要加入白名单的 IP」列给你 |
> macOS 用户:若遇「权限不够」,统一用 python3 scripts/xxx.py 方式调用即可,
> 不需要给脚本额外授权执行。想直接用 ./xxx.py 再执行 chmod +x scripts/*.py。
> Windows 用户:同样能跑,注意两点 ——
> ① 命令里的 python3 换成 python(Windows 通常没有 python3 这个别名);
> ② 脚本已内置控制台编码兜底,中文版 cmd 下输出中文与符号不会乱码或报错。
配置(三种方式,任选)
方式 A:.env 文件(推荐,避免泄露密钥到命令历史)
在 skill 目录放 .env:
WECHAT_APP_ID=wx你的appid
WECHAT_APP_SECRET=你的appsecret
MARKDOWN_CONVERTER=doocs
MARKDOWN_THEME= # 留空=由 Agent 按内容选;或填 default/green/purple/orange/cyan
脚本会自动读取(scripts/config.py)。也可用环境变量 WECHAT_ENV_FILE 指向外部凭证文件(默认 ~/.workbuddy/wechat-publisher.env)。
方式 B:命令行传参
每个脚本都接受 --app_id / --app_secret,优先级高于 .env。
方式 C:让脚本引导你配(第一次用推荐)
不知道 AppID / AppSecret 在哪、或者填完报错看不懂?跑这个:
python3 scripts/setup_credentials.py
流程:检测现有配置 → 引导填入(AppSecret 输入时不回显)→ 联网验证 → 写回配置并备份。
报错会翻译成人话 —— 例如 40164 会直接告诉你「需要加入白名单的 IP 是多少」。
只检查、不改动配置:
python3 scripts/setup_credentials.py --check
> 参数写法:三种都认,不用记区别
> 命令行里写 --app-id、--app_id、--WECHAT_APP_ID 效果一样,用哪个都对。
> (.env 文件里固定写 WECHAT_APP_ID / WECHAT_APP_SECRET)
>
> ⚠️ AppSecret 是高危凭证,不要写进可被分享的 prompt / 文章 / 日志。建议用 .env 或环境变量。
依赖
pip install -r requirements.txt
# 也可装到指定 venv:
# macOS / Linux:<venv>/bin/pip install -r requirements.txt
# Windows: <venv>\Scripts\pip install -r requirements.txt
需要 requests(微信 API)、markdown(MD→HTML)、Pillow(图片压缩)。
完整流水线(9 步)
Step 1 素材采集
按信源清单抓当日素材:官方一手 → 行业媒体 → 垂类 KOL,去重并判断时效。
方法见 references/collection-guide.md。已有素材时可直接跳到 Step 2。
Step 2 选题决策(四维打分)
候选选题按 时效 / 实用 / 争议 / 新奇 四维打分,加权排序取首选。
标准见 references/topic-scoring.md;批量打分可直接跑:
$PYTHON $SCRIPTS/score_topic.py --input topics.json
默认权重 0.3 / 0.3 / 0.2 / 0.2,可用 --weights 覆盖。
Step 3 撰写文章(按模板)
从 templates/ 选一套结构骨架,按选定选题成稿:
| 模板 | 适合 |
|---|---|
01-news-digest.md |
资讯速递(结论前置 + 分条快讯) |
02-deep-dive.md |
深度解读(现象→原因→影响→怎么办) |
03-tool-review.md |
工具实测(结论→过程→数据→适用性) |
04-opinion-column.md |
观点专栏(立论→反方→论据→立场) |
也可调用你已安装的写作 skill:通用号用 wechat-article-writer,人设号用对应人设 skill;都不装则按模板 + references/writing-quality.md 自行撰写。
产出 article.md(Markdown)。
Step 4 去 AI 味 + 标题定稿 + 自动质检
4.1 按 references/writing-quality.md 改写
- 反翻译腔 L4 终检(5 类标记扫描,默认激进模式;技术/合规类内容用保守模式)
- 标题规范:产出 3 个备选(主旨型 / 态度型 / 爆款钩子型),14 型公式库按需选用
4.2 跑自动质检(发出前必做)
$PYTHON $SCRIPTS/check_quality.py article.md
# 公众号标题区间可自定义:--title-chars 18,32
# 账号专属禁用词表:--banned-file banned.txt(每行一个词)
# 机器可读输出:--json
脚本检查 4 类共 9 项:
- 红线与规范:禁用词 / 绝对化用词 / 模糊数量词
- 反翻译腔:物理动作隐喻 / 「形容词+冒号」起手式 / 未翻译英文词 / 段落节奏
- 排版:段落过长;标题:字数区间与情绪词数量
退出码 0=通过 · 1=有警告 · 2=有错误,可直接接进流水线判断。
硬性:exit 2 时不许发出,改完重跑。
Step 5 配图处理
封面图 必须(公众号草稿强制要求)。配图每 500 字 1 张为佳。
PYTHON=python3
SCRIPTS=<本skill目录>/scripts
# 跨平台压缩(PIL,封面建议 ≤800KB,配图 ≤600KB)
$PYTHON $SCRIPTS/compress_image.py --input cover.png --output cover.jpg --max-size 800
# macOS 用户也可: sips -s format jpeg -s formatOptions 80 cover.png --out cover.jpg
# 上传到微信素材库,拿到 thumb_media_id + url
$PYTHON $SCRIPTS/upload_material.py \
--app_id "$APPID" --app_secret "$APPSECRET" \
--image_path cover.jpg
# 输出 JSON:{"thumb_media_id":"...","url":"..."}
记录 thumb_media_id(封面)和正文中每张图的 url(微信草稿要求正文图必须用微信素材库的 url,不能直接外链)。
> 本 skill 负责压缩与上传,不生成图片。封面可自备或用其他图像工具产出。
Step 6 Markdown → 微信 HTML
$PYTHON $SCRIPTS/markdown_to_wechat_doocs.py \
--input article.md --output article.html --theme cyan
主题按内容选(cyan 科技/商务、orange 温暖、green 清新、purple 高端、default 通用)。也可留空由 Agent 用 config.select_theme_by_content() 自动选(仅返回上述 5 种)。
后处理(必须):
- 把正文配图的本地标记替换为 Step 5 拿到的微信 url(<img src="微信url">)
- 在 HTML 末尾插入签名块(可选):放一张签名图,或用 --footer-file footer.md 让 create_draft.py 追加
- 若需自定义排版习惯(如字号 17px、左对齐):将 font-size:20px 替换为 17px、text-align:justify→left
Step 7 创建草稿
$PYTHON $SCRIPTS/create_draft.py \
--app_id "$APPID" --app_secret "$APPSECRET" \
--title "文章标题" \
--content "$(cat article.html)" \
--thumb_media_id "封面thumb_media_id" \
--author "作者名" \
--digest "摘要(≤50字)"
# 成功输出 {"media_id":"..."}
> 默认只建草稿,不自动群发(安全)。
Step 8 归档
- 文章 →
articles/published/YYYYMMDD_标题.md - 元数据 →
articles/published/YYYYMMDD_meta.json(含 media_id、thumb_media_id、theme)
Step 9 一键串联(推荐)
路线 A · run_pipeline(Markdown 素材 → 草稿):Step 5-8 一步跑完。
$PYTHON $SCRIPTS/run_pipeline.py \
--article article.md \
--cover cover.png \
--title "文章标题" \
--author "作者名" \
--digest "摘要(≤50字)" \
--theme cyan \ # 可选,留空自动选
--body-images img1.png,img2.png # 可选,自动上传并替换正文图
# 自动:压缩封面→上传封面→上传正文图并替换→转HTML→建草稿→归档
排版 HTML 直发(路线 B · 高质量排版)
若排版环节由外部排版器完成,产出的是 <section>…</section> 干净片段,跳过 Step 6 的 doocs 转换,直接用 publish_gzh.py 把排好的 HTML 发到草稿箱——排版质感通常远高于通用主题:
$PYTHON $SCRIPTS/publish_gzh.py \
--html article_formatted.html \
--cover cover.png \
--title "文章标题" \
--author "作者名" \
--digest "摘要(≤50字)" \
--dry-run # 先预演(不联网、不建草稿),确认图片清单与参数无误
# 去掉 --dry-run 即真实建草稿
publish_gzh.py 自动:压缩上传封面 → 扫描 HTML 内 <img>(本地路径 / http 外链自动下载并上传替换成微信素材 url,已是 mmbiz.qpic.cn 的保留)→ 建草稿 → 归档。
凭证读取顺序:本 skill .env → ~/.workbuddy/wechat-publisher.env(可用环境变量 WECHAT_ENV_FILE 指定别的路径)→ --app_id/--app_secret。
能力边界与限制
- 图片大小:微信素材图片上限 2MB(超了报
40006/45001)。封面建议压缩 ≤800KB(run_pipeline/compress_image自动处理);正文图也需 ≤2MB。 - 正文图外链:微信草稿正文不支持外链图片,必须用微信素材库返回的
url。run_pipeline.py的--body-images与publish_gzh.py都会自动替换。 - 正文图数量:单篇建议 ≤20 张,过多影响 App 端加载。
- 文章长度:微信草稿正文无硬性字数上限,但建议单篇 ≤5 万字;超长文章可正常转换,只是耗时略增,必要时建议拆分。
- 配图生成:本 skill 不生成图片,只做压缩与上传。
- 网络:需稳定访问
api.weixin.qq.com。网络抖动脚本会自动重试 3 次(指数退避),仍失败请检查网络/代理。 - API 配额:公众号按等级有每日 API 调用额度(素材上传、草稿创建等),超限返回对应 errcode,请稍后或次日再试。
- 群发:本 skill 只建草稿不群发(安全设计),群发需到公众号后台人工确认。
重试与故障排查
脚本已内置网络自动重试(scripts/retry_util.py,3 次指数退避),仅重试网络异常/5xx,不重试 4xx 业务错误。
> 遇到问题,先看按症状分类的手册:references/troubleshooting.md
> 凭证 / 图片 / 排版 / 发布 / 环境 五类分开写,每条给「现象 → 先查什么 → 怎么修」。
> 下面是常见错误码速查:
常见失败对照:
| errcode / 现象 | 原因 | 处理 |
|---|---|---|
| 40001 / 40125 | app_id / app_secret 错误 | 检查 .env 配置 |
| 40006 / 45001 | 图片超过 2MB | 压缩封面(≤800KB)/正文图(≤2MB) |
| 40007 | thumb_media_id 无效 | 确认封面上传成功返回的 media_id |
| 45001 | 多媒体文件过大 | 同图片大小限制 |
| 网络超时 / ConnectionError | 网络不稳/代理 | 脚本自动重试;仍失败检查防火墙/代理 |
| no_cover | 未传封面 | 公众号草稿强制要求封面,先上传封面拿 media_id |
> 凭证(AppSecret)绝不进入日志、文章或 prompt;失败信息只暴露 errcode 与可读原因。
铁律
- 封面图 必须有,否则微信拒收草稿。
- 正文图片必须用微信素材库
url,外链图片在 App 端不显示。 - 缩略图 ≤ 2MB,建议 JPEG。
- AppSecret 不进日志/文章/prompt。
- 默认只存草稿,群发需人工确认。
- 标题承诺的内容,正文必须兑现(写了"附教程"就得附)。
资源
scripts/config.py— .env 配置读取 + 按内容自动选主题(计分制,跨领域平局回落通用主题)scripts/setup_credentials.py— 凭证配置助手(检测 / 引导 / 联网验证 / 写回,错误码翻译成人话)scripts/retry_util.py— 网络请求自动重试(指数退避)scripts/upload_material.py— 上传图片素材,返回 thumb_media_id/url(带重试)scripts/markdown_to_wechat_doocs.py— MD→微信 HTML(5 主题)scripts/create_draft.py— 建草稿(支持可选 footer 追加,带重试)scripts/compress_image.py— 跨平台图片压缩(Pillow)scripts/score_topic.py— 四维选题打分排序scripts/check_quality.py— 发文前质量检查(4 类 9 项,退出码可接 CI)scripts/run_pipeline.py— 一键串联(Markdown 路线)scripts/publish_gzh.py— 排版 HTML 直发草稿(封面压缩上传 + 正文图自动替换 + 建草稿 + 归档,支持 --dry-run)references/writing-quality.md— 反翻译腔 L4 终检 + 14 型标题公式库references/topic-scoring.md— 四维选题评分标准references/collection-guide.md— 素材采集指南references/troubleshooting.md— 按症状分类的排障手册(凭证/图片/排版/发布/环境)templates/01-news-digest.md— 资讯速递模板templates/02-deep-dive.md— 深度解读模板templates/03-tool-review.md— 工具实测模板templates/04-opinion-column.md— 观点专栏模板.env.example— 配置模板