---
name: "wechat-article-automation"
display_name: "公众号文章自动化"
display_name_en: "Official Account Article Automation"
description: "把 Markdown 或纯文本内容排成可直接粘进微信公众号编辑器的富文本（微信原生 DOM 结构，复制粘贴不丢样式），并生成带「复制」按钮的本地预览页。支持长文、清单、日报等通用版式。用户想把文章或文案排成公众号格式、解决复制粘贴排版丢失、一键复制富文本到公众号编辑器时使用本技能。"
description_zh: "公众号文章自动化：将 Markdown / 纯文本排成微信原生 DOM 富文本（渐变、圆角、阴影均可存活），并支持主题词离线生成草稿骨架、网页链接抽取重排。生成带「复制公众号富文本」按钮的本地预览页。零凭据；默认零联网，仅在抽取指定网页链接时对该 URL 发起一次请求，不外传数据。不绑定任何私人题材。"
description_en: "WeChat Article Automation: turn Markdown or plain text into WeChat-native rich text that survives copy-paste (gradients, rounded corners, shadows preserved), with offline topic-to-outline drafting and web-link extraction. Local preview page with one-click copy. No credentials; zero network by default — only fetches the exact URL you give for link extraction, sending no data anywhere. No private topics bound."
version: "1.0.1"
slug: wechat-article-automation
displayName: 公众号文章自动化
summary: 把 Markdown / 纯文本排成可直接粘进公众号编辑器的富文本，复制粘贴不丢样式
license: MIT
author: "kaiw800"
category: content-creation
allowed-tools: "Bash"
---

# 公众号文章自动化（wechat-article-automation）

把 Markdown / 纯文本内容排成**可直接粘进微信公众号编辑器的富文本**，并生成带「复制公众号富文本」按钮的本地预览页。核心解决「复制粘贴后排版丢失」这一真实痛点。

## 第一步（必须先做）

```bash
node scripts/env-check.mjs
```

输出 `"ok": true` → 环境就绪；输出 `"ok": false` → 按 JSON 里 `error.hint` 的指引处理。

## 一期能力

### render — 内容转微信富文本

| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `--input` | 文件 | 是 | Markdown 或纯文本路径（含中文 / 空格需引号） |
| `--template` | 长文 / 清单 / 日报 | 否 | 视觉模板，默认长文 |
| `--output` | 文件 | 否 | 输出 HTML，默认 `<输入同名>.wechat.html` |

```bash
node scripts/render.mjs --input "D:/草稿/我的文章.md" --template 清单
```

输出一份 JSON（`ok`、输出路径、`<span` 与 `</span>` 标签计数断言结果）。

### preview — 生成复制预览页

```bash
node scripts/preview.mjs --input "D:/草稿/我的文章.wechat.html" --output "D:/草稿/我的文章.preview.html"
```

打开生成的 `.preview.html`，点「复制公众号富文本」，回到公众号编辑器粘贴即可。

## 二期能力

### topic — 主题词离线生成草稿骨架

零联网、零凭据。给一个主题词，自动铺好标题备选、各级小标题、每段引导占位和写作建议，渲染成带占位的微信富文本，**正文由你填**。

| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `--topic` | 字符串 | 是* | 主题词或一句话，如「露营装备选购」（可用 `--input` 文本文件的首行代替） |
| `--template` | 长文 / 清单 / 日报 | 否 | 视觉模板，默认长文 |
| `--output` | 文件 | 否 | 输出 HTML，默认 `<主题词>.wechat.html` |

```bash
node scripts/topic.mjs --topic "露营装备选购" --template 清单
```

输出的草稿里，`【引导段占位】` `【本段占位】` 这类中文括号文字是给你替换的提示，不是正文。写完后跑 `preview.mjs` 即可复制。

> 二期暂不做「AI 真写稿」：那需要你自备 LLM 的 API key（联网 + 凭据），与「零凭据」定位冲突。当前是离线骨架，任何环境可跑；真写稿留作后续可选增强。

### extract — 网页链接 / 本地文件重排

把网页或本地 HTML/Markdown 的正文抽出来，重排成微信富文本。

| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `--url` | 链接 | 是* | 网页链接（http/https）；**只抓该 URL**，不访问其他地址、不外传数据 |
| `--input` | 文件 | 是* | 本地文件：`.html/.htm` 走正文抽取，`.md/.txt` 直接解析 |
| `--template` | 长文 / 清单 / 日报 | 否 | 视觉模板，默认长文 |
| `--output` | 文件 | 否 | 输出 HTML，默认 `<输入同名>.wechat.html` |

```bash
node scripts/extract.mjs --url "https://example.com/article" --template 长文
node scripts/extract.mjs --input "D:/草稿/网页另存为.html"
```

抽取只做正文重排、**不声明原创**；落地前请自行核对来源与授权。抓取失败（403 / 超时 / 非 http(s)）会给出可读错误而非臆测。

## 三期能力

### push — 推送到草稿箱（可选 BYO 凭据增强）

**前置条件**：认证公众号权限 + AppID/Secret + 服务器 IP 白名单；**个人订阅号没有草稿箱接口**。凭据走环境变量 `WECHAT_APPID` / `WECHAT_SECRET`（或 `--appid` / `--secret` 覆盖），绝不硬编码、不随技能分发。本脚本**只写入草稿箱，不发表**。

| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `--input` | 文件 | 是 | render / topic / extract 产出的 `.wechat.html` |
| `--cover` | 文件 | 二选一 | 本地封面图（draft/add 必填 thumb_media_id） |
| `--cover-url` | 链接 | 二选一 | 封面图网址（自动下载后上传） |
| `--title` | 字符串 | 否 | 标题（缺省取正文首个标题块） |
| `--author` | 字符串 | 否 | 作者名 |
| `--digest` | 字符串 | 否 | 摘要 |
| `--content-source-url` | 链接 | 否 | 阅读原文链接 |
| `--token-file` | 文件 | 否 | token 缓存，默认 `.wechat_token.json` |

```bash
node scripts/push.mjs --input "D:/草稿/我的文章.wechat.html" --cover "D:/草稿/封面.jpg"
```

输出 `media_id` 与「已写入草稿箱（非发表）」提示。令牌失效（40001/42001）自动删缓存重取一次；封面上传瞬时故障（53402）自动等 10 秒重试一次。

### verify — 草稿箱字节级验证

push 拿到 `media_id` 后，回读 `draft/get` 比对推送前后结构与文本，断言微信重序列化后样式仍存活。

| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `--media-id` | 字符串 | 是 | push 返回的 media_id |
| `--input` | 文件 | 是 | 推送前的原稿 `.wechat.html`（用于比对） |
| `--token-file` | 文件 | 否 | 同 push 的 token 缓存 |

```bash
node scripts/verify.mjs --media-id <MEDIA_ID> --input "D:/草稿/我的文章.wechat.html"
```

通过则 `ok:true`；结构（span/section 计数）或文本不匹配则 `ok:false`，建议人工核对草稿箱实际内容。

## 为什么这样排（技术真相）

微信编辑器会重新序列化文档，样式丢失的**根因是标签结构而非 CSS 属性**。本技能采用微信原生结构（根 `<section>` + 块级 `<span style="display:block">` + 每个文本节点 `<span leaf="">`），因此 `linear-gradient`、`border-radius`、`box-shadow`、`rgba` 都能原样存活。

另一个易踩的坑：**每个块级元素都必须显式声明 `text-align`**（正文用 `left`、标题用 `center`）。因为 Chromium 下未设置 `text-align` 的节点**计算值为 `start`**，而微信《编辑器插件开发规范》§1.6 把 `start`/`end` 判为「非标准值」并逐段告警「文字对齐异常」（`left`/`center`/`right`/`justify` 才合法）。渲染器对此有强制断言——任何块缺 `text-align` 直接报错，所以无需你手动检查。详细规范见 [references/wechat-dom.md](references/wechat-dom.md)。

## 发布前自检（可选）

粘贴前想先确认是否违反微信内容规范，可用微信官方本地检测 CLI 对产出的 `.wechat.html` 跑一遍：

```bash
git clone https://github.com/wechatjs/verify-article-structure-spec.git
cd verify-article-structure-spec/cli
PUPPETEER_SKIP_DOWNLOAD=true npm install --legacy-peer-deps
PUPPETEER_EXECUTABLE_PATH="<本机 chrome.exe 路径>" npm run check "<你的文章>.wechat.html"
```

输出 `isValid: true（无违规）` 即通过。该步骤需联网安装、且会启动本机 Chrome，**非必需**——本技能产出的结构本身已按规范生成，装这一步只是多一道官方口径的保险。

## 暂不支持 / 后续版本

- **主题词 AI 真写稿**：需自备 LLM 的 API key（联网 + 凭据），与「零凭据」定位冲突，留作后续可选增强；当前二期仅提供离线骨架。
- **草稿箱一键推送的「自动发表」**：三期已实现「写入草稿箱（push）+ 回读验证（verify）」。但**发表是公开动作**，不在本技能内自动执行；需要发表请在公众号后台手动点，或另接发布流程。个人订阅号无草稿箱接口，仍只能用「复制富文本」通道。

## 合规

- 内置互动诱导词一票否决（点赞 / 关注 / 转发 / 收藏 / 留言 / 评论区…），生成内容若触发会提示改写。
- 本技能不内置任何题材模板，用户自备内容，本身不涉及题材合规风险；但用户自带内容仍需自行把关。

## 红线

1. 默认写出新文件，绝不覆盖用户源文件；覆盖须经确认。
2. 默认零联网、数据不出本机；**仅当用户显式给定网页链接做抽取时**，才对该 URL 发起一次请求，不访问其他地址、不向外发送任何数据。
3. 不硬编码任何凭据。
4. 不绑定任何用户私人题材、素材、配色、文案。

