Skip to content
Back to skills

Wechat Publisher

ASecurity

公众号文章发布工具。当用户说"存到公众号"、"发布到公众号"、"发到草稿箱"、"推到公众号"、"写到公众号"时触发。配合 kakarot-writer skill 使用:先用 kakarot-writer 风格生成 markdown 文章 → 用 wechat-publisher CLI 格式化并存入微信草稿箱。也支持纯 markdown 文件直接发布。 触发词:存到公众号、发布到公众号、发到草稿箱、推到公众号、写到公众号、发公众号、wechat publish 不触发情况:纯写作不涉及发布、不需要存草稿箱的情况。

  • 2 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 22, 2026
ai-agentspythonbashapi

Works with

  • cli
  • api

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 20 files and shows the line behind each finding

Scanned September 22, 2026

npx -y skills add Zhangs-11/zs-skills --skill wechat-publisher --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Wechat Publisher?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Wechat Publisher
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/zhangs-11-wechat-publisher/badge)](https://www.skillsdirectory.com/skills/zhangs-11-wechat-publisher)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: wechat-publisher
description: |
  公众号文章发布工具。当用户说"存到公众号"、"发布到公众号"、"发到草稿箱"、"推到公众号"、"写到公众号"时触发。配合 kakarot-writer skill 使用:先用 kakarot-writer 风格生成 markdown 文章 → 用 wechat-publisher CLI 格式化并存入微信草稿箱。也支持纯 markdown 文件直接发布。

  触发词:存到公众号、发布到公众号、发到草稿箱、推到公众号、写到公众号、发公众号、wechat publish

  不触发情况:纯写作不涉及发布、不需要存草稿箱的情况。
---

# wechat-publisher 公众号发布工具

作者在「卡卡罗特学AI」公众号写文章,写完后需要一键存到微信草稿箱,不用手动复制粘贴。

## 架构概览

```
kakarot-writer skill 生成 markdown 文章
       │
       ▼
复用 writer 已交付的正文图 + 21:9 封面
       │(素材缺失时才补图)
       ▼
guizang-social-card-skill 或 scripts/generate_wechat_images.py
       │
       ▼
wechat-publisher create --title "xxx" --content-file xxx.md --cover-file images/<文章名>/cover.jpg
       │
       ├─ formatter.py  →  Markdown → 微信兼容 HTML
       ├─ token.py      →  access_token 缓存管理
       ├─ client.py     →  微信 API HTTP 调用
       └─ 微信服务器     →  草稿箱 +1
```

## 安装

仅首次安装时执行。如果用户已经装过,跳过这一步。

### 1. 安装 Python 包

```bash
cd tools/wechat-publisher
python3 -m venv venv
venv/bin/pip install -e .
```

### 2. 创建配置文件

在 `~/.wechat-publisher/.env` 中写入:

```bash
WECHAT_APP_ID=wx你的AppID
WECHAT_APP_SECRET=你的AppSecret
WECHAT_AUTHOR=卡卡罗特学AI
WECHAT_DEFAULT_COVER_MEDIA_ID=你的封面media_id
```

**注意:** 密钥在用户本地 `~/.wechat-publisher/.env`,不在仓库里。`WECHAT_DEFAULT_COVER_MEDIA_ID` 先用 `wechat-publisher upload-cover` 上传一张封面图获取 media_id 再填入。

### 3. 添加 PATH

如果 `wechat-publisher` 命令找不到,用全路径:

```bash
# 或建立软链接
ln -sf $(pwd)/tools/wechat-publisher/venv/bin/wechat-publisher ~/.local/bin/wechat-publisher
```

### 4. IP 白名单

微信 API 要求调用方的公网 IP 在公众号后台白名单中。如果遇到 `40164` 错误,告诉用户当前 IP 并让用户去 mp.weixin.qq.com → 开发 → 基本配置 → IP 白名单 添加。

## 工作流

当用户说"写一篇 XX 文章存到公众号"时,必须按以下步骤执行:

### 第一步:写作
调用 kakarot-writer skill 生成 markdown 文章。

标题、事实边界、文章主线和口语风格以 kakarot-writer 的完整规则为准。发布 skill 不再重复发明另一套写作规则,避免两个 skill 互相冲突。

### 发布前编辑检查

进入配图前,确认文章已经完成 kakarot-writer 的自检,尤其检查:

- 标题承诺能被正文证据兑现,没有暗示不存在的实测或独家经历。
- 没有把推测写成亲历;数据、发布日期、榜单和引用没有未说明的事实缺口。
- 前三段已经建立事件、阅读理由或作者关系,全文围绕同一条主线推进。
- 口语来自真实语境,没有为了模仿作者批量堆叠口癖和夸张标点。

如果存在事实缺口,先向用户确认或收窄断言,不要带着问题进入发布流程。

如果 `kakarot-writer` 已交付正文图片、截图和封面,直接复用,不重新生成或覆盖。仍缺少素材时才保留下列占位标记:

```markdown
[插图:图片内容描述]
[绘图提示:可复制的英文 prompt,适合 Midjourney / DALL-E / 即梦 等生图工具]
```

例:
```markdown
[插图:传统RAG工作流程图]
[绘图提示:A clean technical diagram showing the classic RAG pipeline, flat design with blue and white color scheme, modern minimalist style.]
```

这告诉用户两个信息:**哪里需要配图**、**用什么 prompt 生成图片**。

**绘图提示的写法(重要):**
- **有创意,用视觉比喻概括语义**,不要把正文文字照搬进去。prompt 描述的是「一个画面/场景」,不是「这段话写了啥」。
- **纯英文**。中文一旦进 prompt,生图模型 Z-Image-Turbo 会把中文直接画到图上,且常带错别字。
- **画面里不要出现任何文字**(prompt 末尾脚本会自动追加强力的「无文字」约束 + negative_prompt,你自己写的时候也别要求图上有字)。
- 例(解释「海量上下文被收束成清晰的推理」):`A vast turbulent cloud of glowing particles funneling through a sleek device into one calm focused beam of blue light, flat editorial illustration, blue palette, no text`

### 第二步:保存
将文章保存到 `~/公众号草稿/` 目录。

### 第三步:检查并补齐图片

先检查文章中引用的本地图片是否存在,并确认已有 `21:9` 主封面。只要 `kakarot-writer` 已完成真实截图、正文图和封面,就跳过生图脚本,避免把已经确认的素材替换成概念图。

素材不完整时,优先回到 `kakarot-writer` 的交付清单补齐;封面优先调用 `guizang-social-card-skill` 的真实素材 B 方案。只有专用 Skill 不可用、且文章仍缺少必要图片时,才使用本 Skill 自带的 SiliconFlow 回退脚本,默认模型是 `Tongyi-MAI/Z-Image-Turbo`。

如果文章包含 `[插图:...]` / `[绘图提示:...]`,脚本会按这些 prompt 生成对应正文图(**优先走这条**,因为 prompt 是你手写的、有创意)。如果文章没有占位符,脚本会按正文段落自动插入 3 张配图,并生成封面图——auto 兜底通道会先用对话模型(`deepseek-ai/DeepSeek-V3`)把中文段落转成英文视觉概念再生图,**绝不把中文塞进画面**,从根上避免图上出现原文和错别字。封面也走概念化(不再把标题原文塞进 prompt,并去掉「杂志封面」这类诱导加标题字的措辞,缩写如 AI/GPT 也会被剔除)。封面对文字最敏感,**要最稳就手动传 `--cover-prompt "英文创意概念"`**。

**图片目录**:每篇文章的图存在以文件名命名的独立子目录 `images/<文章名>/` 下(封面 `cover.jpg`、正文 `01-image.jpg`…),多篇之间不会再互相覆盖。

> 所有生图 prompt 末尾都会自动叠加统一创作方向(视觉比喻、蓝色调、画面零文字)+ `negative_prompt` 负向词,进一步压制文字渲染。

**密钥只放在运行环境中,不写入仓库或文章文件。**

```bash
export SILICONFLOW_API_KEY="用户提供的 SiliconFlow API Key"
export WECHAT_PUBLISHER_SKILL_DIR="${WECHAT_PUBLISHER_SKILL_DIR:-$HOME/.codex/skills/wechat-publisher}"
export WECHAT_PUBLISHER_PYTHON="$WECHAT_PUBLISHER_SKILL_DIR/tools/wechat-publisher/venv/bin/python"
export WECHAT_PUBLISHER_BIN="$WECHAT_PUBLISHER_SKILL_DIR/tools/wechat-publisher/venv/bin/wechat-publisher"

"$WECHAT_PUBLISHER_PYTHON" "$WECHAT_PUBLISHER_SKILL_DIR/scripts/generate_wechat_images.py" \
  --article ~/公众号草稿/文件名.md \
  --title "文章标题" \
  --auto-insert 3
```

脚本会:

1. 调用 `https://api.siliconflow.cn/v1/images/generations` 生成图片。
2. 立即下载图片到 `~/公众号草稿/images/<文章名>/`,不要只保存临时 URL。
3. 把正文占位符替换成真实 Markdown 图片;没有占位符时,自动在正文段落后插入配图,例如 `![配图1](images/<文章名>/01-image.jpg)`。
4. 生成封面图 `images/<文章名>/cover.jpg`。

**硬性检查:** 继续发布前,文章中的所有图片路径都必须存在,所有占位符都已替换,并且有可用封面文件或 `cover_media_id`。只有实际执行回退脚本时,才要求命令输出至少一个 `IMAGE: ...` 和一个 `COVER: ...`。否则停止并报告缺失项。

### 第四步:对抗式事实审查(强制,不可跳过)

发布到草稿箱之前,必须自动跑一轮对抗式审查:

1. 派 2 个独立审查 agent(带 WebSearch/WebFetch),立场设定为「假定作者写错/编造,逐条推翻」:一个专攻**数字/榜单/价格/时间**,一个专攻**引语/人物身份/定性表述**
2. 审查结论与原始调研冲突时,必须亲自去一手来源(官方原文)定案,不采信任何单一 agent
3. 绝对化表述(「没法刷」「史上最X」「全球第一」)要么有一手来源,要么加「有分析说」「据官方说法」限定
4. 全部修正后才进入发布步骤,发布后把审查结果汇报给用户(❌抓出的错误 / ⚠️措辞修正 / ✅确认无误清单)

### 第五步:预检并尝试发布

`wechat-publisher` 会自动上传正文 Markdown 图片到微信 CDN。封面图用 `--cover-file` 上传成微信永久素材,再用返回的 `media_id` 创建草稿。已经是 `mmbiz.qpic.cn` 的图片不会重复上传。

发布前,CLI 会先执行统一的内容契约:移除开头 YAML frontmatter,只消费 `<!-- kakarot:delivery-appendix -->` 之前的公开正文,并拒绝正文里的一级标题、未隔离的截图清单/封面方案/备选标题/事实确认项。标题只通过 `--title` 传入,因此不会在正文中重复。摘要提取、图片上传、外链检查和 HTML 格式化全部使用同一份公开正文。

外链默认逐一做只读可达性检查,`404` 等失效链接会阻止上传。只有网络环境暂时不可用、且已经用其他方式逐个核验链接时,才能临时传 `--skip-link-check`;它不是常规发布选项。

```bash
# 检查当前公网 IP
curl -s ip.sb

# 只读预检,不上传图片、不创建草稿
"$WECHAT_PUBLISHER_BIN" preflight \
  --title "文章标题" \
  --content-file ~/公众号草稿/文件名.md \
  --cover-file ~/公众号草稿/images/<文章名>/cover.jpg

# 尝试发布
"$WECHAT_PUBLISHER_BIN" create \
  --title "文章标题" \
  --content-file ~/公众号草稿/文件名.md \
  --cover-file ~/公众号草稿/images/<文章名>/cover.jpg \
  --digest "120字以内摘要"
```

### 第六步:结果处理

**成功** → 告知用户 `SUCCESS: Draft created (media_id=xxx)`

**失败(40164 IP白名单)** → 告诉用户当前IP,让用户去微信后台添加白名单,然后重新运行发布命令

**失败(其他错误)** → 根据错误信息处理

**读取超时** → 创建或更新结果未知。先检查公众号草稿箱,不要立刻重复执行,以免生成重复草稿。

## 命令参考

### create — 创建草稿

```bash
# 从文件
wechat-publisher create --title "标题" --content-file article.md

# 自动上传封面文件
wechat-publisher create --title "标题" --content-file article.md --cover-file images/<文章名>/cover.jpg

# 从管道
cat article.md | wechat-publisher create --title "标题"
```

### update — 更新现有草稿

```bash
wechat-publisher update --media-id "xxx" --title "新标题" --content-file article.md --cover-file images/<文章名>/cover.jpg
```

**⚠️ 必须每次都带 `--cover-file` 或 `--cover-media-id`**,否则封面会被重置为默认封面(WECHAT_DEFAULT_COVER_MEDIA_ID)。只改正文/标题时也不能省。

### upload-image — 上传正文图片(返回 CDN URL)

```bash
wechat-publisher upload-image photo.jpg
# → SUCCESS: Image uploaded → http://mmbiz.qpic.cn/...
```

### upload-cover — 上传封面图(返回 media_id)

```bash
wechat-publisher upload-cover cover.jpg
# → SUCCESS: Cover uploaded (media_id=xxx)
```

## 样式机制

`formatter.py` 自动将 markdown 转为微信内联样式 HTML:

| 元素 | 效果 |
|------|------|
| 正文段落 | 16px, 深灰, 行距 1.85 |
| `===高亮===` | 蓝色渐变底强调 |
| `==注意小句==` | 仅把字变成主题蓝(无底色、不加粗),标关键句用,代替加粗 |
| `> 引用` | 💡 蓝色竖线卡片 |
| `## 二级标题` | 左竖线小标题:蓝色左竖线 + 同色蓝字 + 加粗,字号与正文一致(前置图标,标题没带 emoji 会自动补 🔹) |
| `### 三级标题` | 同款,竖线略细 |
| `---` | `· · ·` 分隔符 |
| `` `代码` `` | 浅灰底圆角代码 |
| ```代码块``` | 浅灰底、深色字、蓝色左边框的高对比代码块 |
| `**加粗**` | 700 字重深色 |
| `*斜体*` | 斜体 |
| 表格 | 微信兼容表格样式 |
| 外链 | 正文标注序号,底部生成参考资料 |

## 内容质检规则

高流量 AI 公众号文章发布前要做以下检查:

1. 标题有具体对象、反常识或真实体验,不使用空泛震惊体。
2. 前三行必须交代“发生了什么”和“为什么值得读”。
3. 只强调真正决定读者理解的关键判断,避免按固定段数机械加粗;跨平台母稿优先使用通用的 `**加粗**`,不主动加入平台私有语法。
4. 配图必须服务理解,且**图里不要出现任何文字**(生图模型画中文会出错别字)。优先用视觉比喻/概念图传达意思,绘图提示用纯英文手写、有创意,不要把正文照搬进 prompt。
5. 一手来源标为 POC、Preview、beta、experimental 或 RC 的能力保留成熟度限定;事实、官方说法和作者推断分层表达。
6. 官方仓库与文档的具体链接必须通过预检实际打开;不能只凭记忆猜默认分支是 `main` 或 `master`。
7. 发布前检查格式化后的代码块、表格和强调块:外层容器与内部文字元素都要明确设置高对比颜色。代码块优先浅底深字,确保微信清除内部 `code` 样式后仍能从外层继承清晰文字颜色。

## 常见错误

| 错误 | 原因 | 处理 |
|------|------|------|
| 40164 | IP 不在白名单 | 获取当前 IP,让用户添加白名单 |
| 40007 invalid media_id | 封面 media_id 无效或为空 | 上传封面图获取正确的 media_id |
| 40001 | token 过期或无效 | 会自动刷新,持久失败检查 appsecret 是否正确 |
| 45009 | 接口频率超限 | 会自动重试 |

## 发布前失败保护

- 如果缺少封面,命令会失败并提示配置 `WECHAT_DEFAULT_COVER_MEDIA_ID`、传 `--cover-media-id`,或传 `--cover-file`。
- 如果正文仍包含 `[插图:...]` / `[绘图提示:...]`,命令会失败,防止半成品进入草稿箱。
- 如果遇到 40164,命令会提示去微信后台添加当前公网 IP 白名单。

Files in this skill

  • .gitignore97 B
  • LICENSE1 KB
  • README.md7.3 KB
  • SKILL.md14.1 KB
  • scripts/generate_wechat_images.py18.9 KB
  • tests/test_generate_images_script.py12.1 KB
  • tools/wechat-publisher/.env.example129 B
  • tools/wechat-publisher/.gitignore49 B
  • tools/wechat-publisher/pyproject.toml380 B
  • tools/wechat-publisher/tests/test_assets.py4 KB
  • tools/wechat-publisher/tests/test_cli_helpers.py7.5 KB
  • tools/wechat-publisher/tests/test_client.py6 KB
  • tools/wechat-publisher/tests/test_formatter.py3.5 KB
  • tools/wechat-publisher/tests/test_linkcheck.py2.8 KB
  • tools/wechat-publisher/tests/test_publication.py5.1 KB
  • tools/wechat-publisher/tests/test_secure_download.py4.4 KB
  • tools/wechat-publisher/tests/test_token.py1.2 KB
  • tools/wechat-publisher/wechat_publisher/__init__.py22 B
  • tools/wechat-publisher/wechat_publisher/cli.py9.7 KB
  • tools/wechat-publisher/wechat_publisher/client.py10 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.