{"id":"fdb36b49-b356-460d-93dd-0c5fdd580c9c","entityType":"agent","slug":"clawhub-aiworkskills-aws-wechat-article-publish","name":"aws-wechat-article-publish","canonicalUrl":"https://www.xpersona.co/agent/clawhub-aiworkskills-aws-wechat-article-publish","canonicalPath":"/agent/clawhub-aiworkskills-aws-wechat-article-publish","generatedAt":"2026-10-10T15:53:05.803Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-10T13:12:22.739Z","emptyReason":null},"description":"公众号发布｜公众号草稿箱｜公众号群发｜图文推送｜微信 API｜wechat automation｜WeChat API automation｜auto publish｜scheduled publish — 公众号 API 发布工具，图文入草稿箱或直接群发，支持封面素材上传、发布前检查与 draft/published 模式切换。面向公众号运营、自动化内容团队、开发者。触发词：「发布」「提交」「群发」「推送」「发出去」「上传到公众号」「发到公众号」「可以发了吗」「发布前检查」。需要多环节串联（写+审+排+配图+发）请走 aws-wechat-article-main。 Skill: aws-wechat-article-publish Owner: aiworkskills Summary: 公众号发布｜公众号草稿箱｜公众号群发｜图文推送｜微信 API｜wechat automation｜WeChat API automation｜auto publish｜scheduled publish — 公众号 API 发布工具，图文入草稿箱或直接群发，支持封面素材上传、发布前检查与 draft/published 模式切换。面向公众号运营、自动化内容团队、开发者。触发词：「发布」「提交」「群发」「推送」「发出去」「上传到公众号」「发到公众号」「可以发了吗」「发布前检查」。需要多环节串联（写+审+排+配图+发）请走 aws-wechat-article-main。 Tags: api:1.0.17, automation:1.0.17, chinese:1.0.17, claude-code:1.0.","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.4K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s170f08a9xbhfkfp1vjv33y1ph842r9a:aws-wechat-article-publish","sourceUrl":"https://clawhub.ai/aiworkskills/aws-wechat-article-publish","homepage":"https://clawhub.ai/aiworkskills/skills/aws-wechat-article-publish","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/aiworkskills/aws-wechat-article-publish","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/aiworkskills/skills/aws-wechat-article-publish","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":63,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"公众号发布｜公众号草稿箱｜公众号群发｜图文推送｜微信 API｜wechat automation｜WeChat API automation｜auto publish｜scheduled publish — 公众号 API 发布工具，图文入草稿箱或直接群发，支持封面素材上传、发布前检查与 draft/published"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:12:22.739Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:12:22.739Z","emptyReason":null},"stars":null,"forks":null,"downloads":1419,"packageName":null,"latestVersion":"1.0.24","tractionLabel":"1.4K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:12:22.738Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T13:12:22.739Z","lastCrawledAt":"2026-10-10T13:12:22.738Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T13:12:22.738Z","lastVerifiedAt":null,"highlights":[{"version":"1.0.24","createdAt":"2026-09-07T16:07:22.027Z","changelog":"article.yaml 预设字段表加 default_format_scheme，本篇的排版配色可以落盘。","fileCount":11,"zipByteSize":35643},{"version":"1.0.23","createdAt":"2026-09-06T07:24:55.166Z","changelog":"封面裁剪框支持 2.35:1 优先，并记录 pic_crop_* 的回读方式；发布前检查不再对封面过度承诺；反代下线不再被误报成网络抖动；统一 {python} 解释器占位符。","fileCount":11,"zipByteSize":35779},{"version":"1.0.22","createdAt":"2026-04-22T23:24:23.931Z","changelog":"软化版套件完整性提示：说明工作流会读跨 skill 共享文档、单独安装时会 file-not-found；纯信息性语气，无 shell 循环、无 Agent 强指令","fileCount":11,"zipByteSize":32531},{"version":"1.0.20","createdAt":"2026-04-22T22:35:55.000Z","changelog":"修 scanner 精准点名：移除'不外传/不读仓库外'假陈述；补凭证/内容外发披露；sticker+review 补 WECHAT 凭证声明；空 env 的 skill 移除 primaryEnv；3 个脚本不再遍历父目录","fileCount":10,"zipByteSize":31037},{"version":"1.0.19","createdAt":"2026-04-22T16:36:32.581Z","changelog":"能力披露：frontmatter 加 metadata.openclaw.requires；body 加 Capabilities 段；降温前置依赖块（去 shell 循环与强指令语气）；article_init.py 不再读 Path.home()","fileCount":10,"zipByteSize":30749},{"version":"1.0.18","createdAt":"2026-04-22T15:53:31.762Z","changelog":"清理 tags 只留 latest；frontmatter 加 homepage+url；main/publish 加 automation 关键词","fileCount":10,"zipByteSize":30741},{"version":"1.0.17","createdAt":"2026-04-22T08:45:31.979Z","changelog":"加前置依赖检查：任一 skill 启动前要求 9 个套件全装，否则停止工作流","fileCount":10,"zipByteSize":30685},{"version":"1.0.16","createdAt":"2026-04-22T05:13:37.887Z","changelog":"压缩 description 做 SEO 密度优化","fileCount":10,"zipByteSize":30142}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s170f08a9xbhfkfp1vjv33y1ph842r9a:aws-wechat-article-publish","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-publish/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-publish/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-publish/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-publish/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-publish/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-publish/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T15:53:05.801Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-publish/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-publish/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-publish/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-publish/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-10T13:12:22.739Z","emptyReason":null},"readme":"Skill: aws-wechat-article-publish\n\nOwner: aiworkskills\n\nSummary: 公众号发布｜公众号草稿箱｜公众号群发｜图文推送｜微信 API｜wechat automation｜WeChat API automation｜auto publish｜scheduled publish — 公众号 API 发布工具，图文入草稿箱或直接群发，支持封面素材上传、发布前检查与 draft/published 模式切换。面向公众号运营、自动化内容团队、开发者。触发词：「发布」「提交」「群发」「推送」「发出去」「上传到公众号」「发到公众号」「可以发了吗」「发布前检查」。需要多环节串联（写+审+排+配图+发）请走 aws-wechat-article-main。\n\nTags: api:1.0.17, automation:1.0.17, chinese:1.0.17, claude-code:1.0.17, latest:1.0.24, publish:1.0.17, wechat:1.0.17, wechat-api:1.0.17\n\nVersion history:\n\nv1.0.24 | 2026-09-07T16:07:22.027Z | user\n\narticle.yaml 预设字段表加 default_format_scheme，本篇的排版配色可以落盘。\n\nv1.0.23 | 2026-09-06T07:24:55.166Z | user\n\n封面裁剪框支持 2.35:1 优先，并记录 pic_crop_* 的回读方式；发布前检查不再对封面过度承诺；反代下线不再被误报成网络抖动；统一 {python} 解释器占位符。\n\nv1.0.22 | 2026-04-22T23:24:23.931Z | user\n\n软化版套件完整性提示：说明工作流会读跨 skill 共享文档、单独安装时会 file-not-found；纯信息性语气，无 shell 循环、无 Agent 强指令\n\nv1.0.20 | 2026-04-22T22:35:55.000Z | user\n\n修 scanner 精准点名：移除'不外传/不读仓库外'假陈述；补凭证/内容外发披露；sticker+review 补 WECHAT 凭证声明；空 env 的 skill 移除 primaryEnv；3 个脚本不再遍历父目录\n\nv1.0.19 | 2026-04-22T16:36:32.581Z | user\n\n能力披露：frontmatter 加 metadata.openclaw.requires；body 加 Capabilities 段；降温前置依赖块（去 shell 循环与强指令语气）；article_init.py 不再读 Path.home()\n\nv1.0.18 | 2026-04-22T15:53:31.762Z | user\n\n清理 tags 只留 latest；frontmatter 加 homepage+url；main/publish 加 automation 关键词\n\nv1.0.17 | 2026-04-22T08:45:31.979Z | user\n\n加前置依赖检查：任一 skill 启动前要求 9 个套件全装，否则停止工作流\n\nv1.0.16 | 2026-04-22T05:13:37.887Z | user\n\n压缩 description 做 SEO 密度优化\n\nv1.0.15 | 2026-04-22T04:50:04.003Z | user\n\nSEO 优化：补关键词/友好名/价值主张/GitHub 链接\n\nv1.0.14 | 2026-04-22T04:35:15.439Z | user\n\n对齐 git tag v1.0.14\n\nv1.0.1 | 2026-04-22T04:25:57.828Z | user\n\n首发/补套件说明：跨 skill 相对引用需同 skills/ 目录一起安装\n\nv1.0.0 | 2026-04-01T03:44:59.120Z | auto\n\n- Initial release of the AWS WeChat article publishing skill.\n- Supports publishing articles to WeChat Official Accounts via API (draft or published), with pre-publish checks.\n- Guides account selection and configuration validation, including multi-account support and credential checks.\n- Handles article status tracking via article.yaml (`publish_completed: true/false`) for workflow management.\n- Provides robust error handling, directory structure guidance, and step-by-step user interaction flow.\n- Includes CLI scripts for publishing, environment validation, and account management.\n\nArchive index:\n\nArchive v1.0.24: 11 files, 35643 bytes\n\nFiles: references/api-reference.md (4969b), references/pre-publish-checklist.md (536b), references/submit-guide.md (2408b), references/usage.md (2323b), scripts/article_init.py (8593b), scripts/getdraft.py (16742b), scripts/publish.py (46849b), skill-card.md (2925b), skill.json (494b), SKILL.md (13513b), _meta.json (146b)\n\nFile v1.0.24:SKILL.md\n\n---\nname: aws-wechat-article-publish\ndescription: 公众号发布｜公众号草稿箱｜公众号群发｜图文推送｜微信 API｜wechat automation｜WeChat API automation｜auto publish｜scheduled publish — 公众号 API 发布工具，图文入草稿箱或直接群发，支持封面素材上传、发布前检查与 draft/published 模式切换。面向公众号运营、自动化内容团队、开发者。触发词：「发布」「提交」「群发」「推送」「发出去」「上传到公众号」「发到公众号」「可以发了吗」「发布前检查」。需要多环节串联（写+审+排+配图+发）请走 aws-wechat-article-main。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env:\n        - WECHAT_1_APPID\n        - WECHAT_1_APPSECRET\n      bins:\n        - python3\n    primaryEnv: aws.env\n---\n\n# 发布\n\n**公众号 API 直连发布** —— 图文入草稿箱或直接群发，素材上传、发布前检查一站式完成。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 调 `publish.py` **直连微信公众号官方 API** 发布图文。**会把本篇 `article.html` 与 `imgs/*` 文件作为 POST body 上传到微信服务器。** 具体行为：\n\n- **凭证读取**：`aws.env` 的 `WECHAT_{N}_APPID` / `WECHAT_{N}_APPSECRET`（多槽位支持 N≥1）\n- **凭证外发**：`APPID` / `APPSECRET` 以 query string 形式发给 `api.weixin.qq.com/cgi-bin/token` 换 `access_token`；后续请求带 `access_token` query string。微信返回的 `access_token` 在进程内存短期缓存，**不落盘**\n- **内容外发**：本篇封面、正文插图以 multipart upload 发给 `material/add_material`；`article.html` 正文与标题/摘要以 JSON POST 发给 `draft/add`、`freepublish/submit`\n- **网络目标**：默认 `api.weixin.qq.com`；用户可在 `WECHAT_{N}_API_BASE` / `config.yaml.wechat_api_base` 自配反代\n- **文件读**：仓库内 `.aws-article/config.yaml`、`aws.env`、本篇 `article.yaml`、`article.html`、`imgs/*`\n- **文件写**：仅本篇 `article.yaml` 的状态字段（`media_id`、`publish_id`、`publish_completed`）\n- **shell**：仅 `{python} {baseDir}/scripts/publish.py`、`getdraft.py`、`article_init.py`（`{python}` = 本机 Python 3 解释器，见 [main SKILL 第 0 步](../aws-wechat-article-main/SKILL.md)：Windows 用 `py -3 -X utf8`，macOS / Linux 用 `python3`）\n\n**建议**：首次运行用 `publish_method: draft` 只入草稿箱确认效果，再切 `published` 真正群发。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的**发布环节**（入口 `aws-wechat-article-main`）。工作流中的若干步骤会读取同级 `../aws-wechat-article-main/references/*.md` 等共享文档（首次引导、articlescreening schema、env/config 示例等）。\n\n- **套件完整装齐到同一 `skills/` 根目录**时，跨 skill 引用都能读到。\n- **单独安装本 skill** 时，跨 skill 引用的步骤会在读取阶段遇到 `file not found`；但 `publish.py`、`getdraft.py`、`article_init.py` 这几个脚本本身可独立运行（只要 `aws.env` 与 `.aws-article/config.yaml` 就绪）。\n\n完整 9 slug 清单见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n通过微信公众号 API 将排版稿写入**草稿箱**或再**提交发布**（由 **`config.yaml`** 的 **`publish_method`** 与命令行 **`--publish`** 控制）。\n\n## 配置检查 ⛔\n\n任何操作执行前，**必须**按 **[首次引导](../aws-wechat-article-main/references/first-time-setup.md)** 执行其中的 **「检测顺序」**。检测通过后才能进行以下操作（或用户明确书面确认「本次不检查」）：\n\n## 脚本目录\n\n**Agent 执行**：确定本 SKILL.md 所在目录为 `{baseDir}`。发布子命令在 **`{baseDir}/scripts/publish.py`**（项目根执行）。\n\n| 脚本 / 子命令 | 用途 |\n|--------|------|\n| **`article_init.py`** | 初始化或更新本篇 **`article.yaml`**（及可选 **`closing.md`**）。用于总览 **本篇准备**（建目录后）或 **发布前** 补全元数据。仓库根执行：`{python} {baseDir}/scripts/article_init.py <文章目录> [--title … --author … --digest …]` |\n| **`getdraft.py`** | 独立于 `publish.py`：用于正式文章查询（`published-list` / `published-fields` / `publish-get` / `article-get`，对应 `freepublish/*`），可用于 `embeds.related_articles.manual` 为空时自动补全推荐链接。注意：`freepublish/*` 需要公众号具备对应接口权限。仓库根：`{python} {baseDir}/scripts/getdraft.py published-fields` |\n| `check-screening` | 校验 **`config.yaml`** 的 **`publish_method`**（**`draft`** / **`published`** / **`none`**） |\n| `check-wechat-env` | 按 **`config.yaml` 槽位**检查 `aws.env` 的 `WECHAT_N_APPID` / `WECHAT_N_APPSECRET` 是否已填（**调用 `publish.py` 前建议跑**） |\n| `check` | 环境检查：`aws.env`、各槽位、依赖、可选探测 token |\n| `accounts` | 列出 **`config.yaml`** 中各微信槽位名称，并标记 `aws.env` 凭证缺项 |\n| `full` / `token` / … | 调微信 API（需 **`aws.env`** 微信凭证） |\n\n## 凭证与 `publish_method` ⛔\n\n### `publish_method`（以仓库 **`config.yaml`** 为准）\n\n| 值 | 含义 | 行为 |\n|----|------|------|\n| **`draft`**（默认） | 只进公众号**草稿箱** | **`full`** 创建草稿后**不**调用 freepublish 提交发布。 |\n| **`published`** | 草稿 + **提交发布** | **`full`** 创建草稿后继续提交发布（异步）。**`full --publish`** 可**单次强制**带发布，即使当前为 **`draft`**。 |\n| **`none`** | 用户明确不填微信 | **`full`** **立即退出**，不调任何微信接口（**`--publish`** 也会被忽略）。其它子命令（`token` 等）仍要凭证。 |\n\n### 多账号时如何选槽位\n\n1. 运行 **`{python} {baseDir}/scripts/publish.py accounts`**，从 **`config.yaml` 的 `wechat_accounts` + `wechat_N_name`** 向用户展示列表（例如：`您有2个账号：1.\"xiaoming\"，2.\"xiaoz\"`）必须询问用户选择哪个账号发布到草稿箱，然后根据用户选择发布到指定的账号。\n2. 在 **`config.yaml`** 写 **`wechat_publish_slot: <整数>`**，**或**命令行 **`--account <序号或名称>`**（**CLI 优先**，见 [articlescreening-schema.md](../aws-wechat-article-main/references/articlescreening-schema.md)）。\n\n### 全局环境\n\n在仓库根具备 **`aws.env`**（微信密钥）与 **`config.yaml`**（微信槽位数量与名称）。写作/生图见 **`validate_env.py`**（微信未齐仍可先做内容）。**`publish_method: none`** 时 **`full`** 会跳过；**`draft`/`published`** 发布前建议 **`check-wechat-env`**。API 端点优先取 **`WECHAT_N_API_BASE`**，若槽位未配则回退 **`config.yaml.wechat_api_base`**（两者都空时使用官方）。\n\n### 作者名回退\n\n`full` / `create-draft` 若 **`article.yaml` 无 author**，回退 **`config.yaml`** 的 **`default_author`**。\n\n### `publish_completed`（本篇是否已发布完成）\n\n- 字段在**本篇** **`article.yaml`**。**`publish.py` 不读、不改**；由智能体维护。\n- **`false`**：发布流程未闭环。\n- **`true`**：已视为发布完成（草稿已确认 / 或 **`published`** 流程成功且运营确认）。\n\n**本篇发布真正结束后**：将 **`publish_completed: true`** 写回 **`article.yaml`**。\n\n**写回 `true` 的前置门禁（缺啥补啥）**：\n\n1. `article.html` 存在；\n2. 文章目录存在封面图 `cover.(png/jpg/jpeg/webp)`；\n\n   **封面裁剪框**：微信只收一张封面，但 `draft/add` 可附带两个裁剪框，分别决定 **2.35:1**（订阅号信息流首图）与 **1:1**（分享卡片、公众号主页、历史列表）怎么裁；不传时微信自行居中裁切。`publish.py` 会按封面实际尺寸自动算出两个框并随草稿提交（需 Pillow；未安装则跳过，交给微信默认行为）。\n   \n   设计取向是 **2.35:1 优先**——信息流那一眼决定点不点，1:1 作降级视图。所以封面按 2.35:1 构图即可，不必为迁就方形而牺牲主视图。\n   \n   需要手动指定时，在本篇 `article.yaml` 写 **`pic_crop_235_1`** / **`pic_crop_1_1`**（`X1_Y1_X2_Y2` 归一化 0~1），脚本不再覆盖。注意裁出区域的宽高比须与目标比例一致，否则接口返回 **53402**「封面裁剪失败」。\n3. `article.md` 与 `article.html` 中均不含 `placeholder`；\n4. 发布命令成功并拿到回执（`media_id` 或 `publish_id`）。\n\n任一不满足：只可标记为“已提交草稿，未闭环”，**不得**写回 `publish_completed: true`。\n\n## 用户仅说「发布」且未明确路径时 ⛔\n\n在用户**未给出** `drafts/…` 路径、仅说「发布文章」「帮我发一下」等时：\n\n1. **确定本篇目录**：列出仓库下 **`drafts/`** 中子目录；若**多篇**，请用户**指定一篇**或选「最新修改」的一篇再读该目录 **`article.yaml`**。**勿**在未确认目录时假定路径。\n2. 读取该目录 **`article.yaml`** 中的 **`publish_completed`**（YAML 布尔：`true` / `false`；**缺省按 `false` 处理**）。\n\n| `publish_completed` | 智能体对用户说明（可略作口语化，勿改含义） |\n|---------------------|---------------------------------------------|\n| **`true`** | 告知：**项目里本篇文档已按记录成功发布**；问：**您是否需要编写新文章？** 若需要 → 转交 [main](../aws-wechat-article-main/SKILL.md) / [writing](../aws-wechat-article-writing/SKILL.md) 从本篇准备或选题起走。 |\n| **`false`** 或缺省 | 读取 **`article.yaml`** 的 **`title`**（若无则用目录名简述），说明：**《{title}》尚未执行完成（发布流程未闭环）**；问：**是否需要继续并完成发布？** 或 **编写新文章？** 若继续本篇 → 再核对 **`config.yaml`** 的 **`publish_method`**、**`check-screening`**、**`check-wechat-env`** 等。 |\n\n## 工作流\n\n```\n发布进度：\n- [ ] 前置：配置检查（见本节「配置检查」）⛔\n- [ ] 第0步：若用户未给路径 → 选本篇目录 → 读 publish_completed → 按上表分流（true/false）\n- [ ] 第1步：读 **`config.yaml`** → **`draft` / `published`**（及是否 **`full --publish`**）\n- [ ] 第2步：读取 **`config.yaml`** 的 `wechat_accounts` + `wechat_N_name` 向用户展示账号列表并询问目标槽位；随后跑 **`check-wechat-env`** 校验 `aws.env` 凭证 → **`wechat_publish_slot` 或 `--account`**\n- [ ] 第3步：发布前检查（checklist + **`check-screening`** + **`check`**）\n- [ ] 第4步：准备文章目录\n- [ ] 第5步：**`full`**（仅草稿或含发布，视上步）\n- [ ] 第6步：确认结果与用户说明\n- [ ] 第7步：成功后写回 **`article.yaml`** 的 **`publish_completed: true`**；按需归档\n```\n\n## 交互顺序（最小提问）\n\n0) **未给路径时**：先按上文 **「用户仅说发布」** 处理 **`publish_completed`**；用户选 **继续本篇** 后再做下列步骤。  \n1) **先看 `config.yaml` 的 `publish_method`**：**`draft`** = 默认只进草稿箱；**`published`** 或 **`full --publish`** = 再提交发布。  \n2) **多槽位**：展示账号列表（来源：`config.yaml` 的 `wechat_accounts` + `wechat_N_name`），**必须请用户选槽位** → **`wechat_publish_slot`** 或 **`--account`**。  \n3) 缺微信字段：运行 **`check-wechat-env`**，补全 **`aws.env`** 后再发。  \n4) **发布失败**（由脚本 stderr / 微信 errcode 判断）：  \n   - **网络类**（超时、连接失败、5xx）：脚本已对单次请求 **自动重试 1 次**；仍失败 → 告知「网络不可用，请稍后重试或检查代理」。  \n   - **凭证/配置类**（如 token 失败带 errcode、缺字段）→ 提示 **第几槽位**、检查 **APPID/SECRET、IP 白名单**，用户改正后再执行 **`full`** / **`publish`**。\n5) **中间产物缺失**（封面缺失 / 存在 `placeholder`）：先补产物再发；若用户坚持先发草稿，必须明确告知“正文配图未完成”，且保持 `publish_completed: false`。\n\n## 命令示例（仓库根）\n\n```bash\n{python} {baseDir}/scripts/publish.py check-screening\n{python} {baseDir}/scripts/publish.py check-wechat-env\n{python} {baseDir}/scripts/publish.py accounts\n{python} {baseDir}/scripts/publish.py check\n{python} {baseDir}/scripts/publish.py --account 1 full drafts/YYYYMMDD-标题slug/\n{python} {baseDir}/scripts/getdraft.py published-fields\n```\n\n详见 [references/usage.md](references/usage.md)、[references/submit-guide.md](references/submit-guide.md)、[references/api-reference.md](references/api-reference.md)。\n\n## 过程文件\n\n| 读取 | 产出 |\n|------|------|\n| `article.html`、`imgs/`、**`article.yaml`**（含 **`publish_completed`** 等）、**`.aws-article/config.yaml`**、**`aws.env`**（微信槽位） | 发布到公众号草稿或提交发布；**成功后**由智能体将 **`publish_completed: true`** 写回 **`article.yaml`**（`publish.py` 不改此键） |\n\nFile v1.0.24:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-publish\",\n  \"version\": \"1.0.24\",\n  \"publishedAt\": 1788797242027\n}\n\nFile v1.0.24:references/api-reference.md\n\n# 微信公众号 API 参考\n\n## 接口一览\n\n| 接口 | 方法 | 路径 | 用途 |\n|------|------|------|------|\n| 获取 token | GET | `/token` | 获取 access_token |\n| 上传永久素材 | POST | `/material/add_material` | 上传封面图，返回 media_id |\n| 上传正文图片 | POST | `/media/uploadimg` | 上传正文内图片，返回 URL |\n| 新增草稿 | POST | `/draft/add` | 创建图文草稿 |\n| 发布草稿 | POST | `/freepublish/submit` | 发布草稿（异步） |\n| 查询发布状态 | POST | `/freepublish/get` | 查询发布结果 |\n\n所有接口基础 URL：`https://api.weixin.qq.com/cgi-bin`\n\n## 获取 access_token\n\n```\nGET /token?grant_type=client_credential&appid={APPID}&secret={APPSECRET}\n```\n\n返回：\n```json\n{\"access_token\": \"...\", \"expires_in\": 7200}\n```\n\n有效期 2 小时，需缓存复用，避免频繁请求。\n\n## 上传封面图（永久素材）\n\n```\nPOST /material/add_material?access_token={TOKEN}&type=image\nContent-Type: multipart/form-data\n```\n\n- 字段名：`media`\n- 限制：10MB，支持 bmp/png/jpeg/jpg/gif\n- 永久素材上限：100,000 张\n\n返回：\n```json\n{\"media_id\": \"...\", \"url\": \"...\"}\n```\n\n`media_id` 用于 `draft/add` 的 `thumb_media_id` 字段。\n\n## 上传正文图片\n\n```\nPOST /media/uploadimg?access_token={TOKEN}\nContent-Type: multipart/form-data\n```\n\n- 字段名：`media`\n- 限制：1MB，支持 jpg/png\n- 不占用素材库配额\n- 返回的 URL 可直接在正文 HTML 中使用\n\n返回：\n```json\n{\"url\": \"https://mmbiz.qpic.cn/...\"}\n```\n\n## 新增草稿\n\n```\nPOST /draft/add?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\n  \"articles\": [{\n    \"title\": \"标题（≤32字）\",\n    \"author\": \"作者（≤16字）\",\n    \"digest\": \"摘要（≤128字，仅单图文）\",\n    \"content\": \"HTML 正文（≤2万字符，图片 URL 必须来自 uploadimg）\",\n    \"thumb_media_id\": \"封面图 media_id\",\n    \"content_source_url\": \"原文链接\",\n    \"need_open_comment\": 1,\n    \"only_fans_can_comment\": 0\n  }]\n}\n```\n\n返回：\n```json\n{\"media_id\": \"...\"}\n```\n\n## 发布草稿\n\n```\nPOST /freepublish/submit?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\"media_id\": \"草稿的 media_id\"}\n```\n\n返回：\n```json\n{\"publish_id\": \"...\", \"msg_data_id\": \"...\"}\n```\n\n**注意**：发布为异步操作，返回成功仅表示任务提交成功。\n\n## 查询发布状态\n\n```\nPOST /freepublish/get?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\"publish_id\": \"...\"}\n```\n\n返回 `publish_status`：\n\n| 值 | 含义 |\n|----|------|\n| 0 | 发布成功 |\n| 1 | 发布中 |\n| 2 | 原创失败 |\n| 3 | 常规失败 |\n| 4 | 平台审核不通过 |\n| 5 | 已删除 |\n| 6 | 已封禁 |\n\n## 常见错误码\n\n| 错误码 | 含义 | 处理 |\n|--------|------|------|\n| 40001 | access_token 无效 | 重新获取 token |\n| 40004 | 不合法的媒体文件类型 | 检查图片格式 |\n| 40009 | 图片大小超限 | 封面 ≤10MB，正文图 ≤1MB |\n| 45009 | API 调用超限 | 等待后重试 |\n| 45028 | 接口无权限 | 检查公众号类型和权限 |\n| 48001 | API 未授权 | 检查公众号开发者设置 |\n\n## 凭证配置\n\n在仓库根 **`aws.env`** 中配置微信槽位（勿提交含真密钥的文件）：\n\n```env\nNUMBER_ACCOUNTS=1\nWECHAT_1_NAME=主号\nWECHAT_1_APPID=你的AppID\nWECHAT_1_APPSECRET=你的AppSecret\nWECHAT_1_API_BASE=\n```\n\n键名与 `skills/aws-wechat-article-main/references/env.example.yaml` 一致。多账号递增 `WECHAT_2_*` 等。\n\n## 权限要求\n\n- 需要已认证的服务号或订阅号\n- AppID 和 AppSecret 在「开发 → 基本配置」获取\n- 调用服务器 IP 需加入白名单\n\n## 官方文档\n\n- [新增草稿](https://developers.weixin.qq.com/doc/subscription/api/draftbox/draftmanage/api_draft_add)\n- [发布草稿](https://developers.weixin.qq.com/doc/subscription/api/public/api_freepublish_submit.html)\n- [上传永久素材](https://developers.weixin.qq.com/doc/subscription/api/material/permanent/api_addmaterial.html)\n- [上传正文图片](https://developers.weixin.qq.com/doc/subscription/en/api/material/permanent/api_uploadimage)\n\n## 封面裁剪框 pic_crop_* 的回读\n\n`draft/add` 接受 `pic_crop_235_1` / `pic_crop_1_1`（归一化 `X1_Y1_X2_Y2`），但\n**`draft/get` 不回显这两个字段**——它把值归一化后放进 `cover_info.crop_percent_list`：\n\n```json\n\"cover_info\": {\n  \"crop_percent_list\": [\n    {\"ratio\": \"2.35_1\", \"x1\": \"0.001515\", \"y1\": \"0\", \"x2\": \"0.998485\", \"y2\": \"1\"},\n    {\"ratio\": \"1_1\",    \"x1\": \"0.287879\", \"y1\": \"0\", \"x2\": \"0.712121\", \"y2\": \"1\"}\n  ]\n}\n```\n\n不知道这点会得出「微信忽略了裁剪框」的错误结论——在 `news_item[0]` 里查\n`pic_crop_235_1` 只会拿到 `None`。校验请读 `cover_info.crop_percent_list`，\n`ratio` 用下划线写法（`2.35_1` / `1_1`）。\n\n实测（1584x672 封面）微信原样存下，六位小数完全一致；比例不匹配时才会报 53402。\n\nFile v1.0.24:references/pre-publish-checklist.md\n\n# 发布前检查清单\n\n在审稿通过后、实际提交前执行，确保可安全发布。\n\n## 检查项\n\n- [ ] 标题、摘要、作者已最终确认\n- [ ] 正文无未替换的占位符或草稿标记\n- [ ] 敏感词与错别字已在审稿中修正\n- [ ] 封面图已就绪（已上传或路径有效）\n- [ ] 正文内图片齐全，图注格式正确\n- [ ] 原创/转载标注已按配置处理\n- [ ] 文末引导区块已就位\n- [ ] 如需开启评论/仅粉丝可评，已确认设置\n\n全部勾选后执行提交步骤。\n\nFile v1.0.24:references/submit-guide.md\n\n# 提交到公众号后台\n\n## 方式一：API 提交（推荐）\n\n使用 `skills/aws-wechat-article-publish/scripts/publish.py`，通过微信公众号 API 完成发布。\n\n### 前置准备\n\n1. 在仓库根 **`aws.env`** 中填写微信槽位（与 `skills/aws-wechat-article-main/references/env.example.yaml` 键名一致），例如单账号：\n   ```env\n   NUMBER_ACCOUNTS=1\n   WECHAT_1_NAME=主号\n   WECHAT_1_APPID=你的AppID\n   WECHAT_1_APPSECRET=你的AppSecret\n   WECHAT_1_API_BASE=\n   ```\n   多账号递增 `WECHAT_2_*` 等；发布前可运行 `{python} skills/aws-wechat-article-publish/scripts/publish.py check-wechat-env` 检查缺项。\n\n2. 在公众平台「开发 → 基本配置」中将服务器 IP 加入白名单\n\n3. 准备文章目录：\n   ```\n   article/\n   ├── article.yaml    # 标题、作者、摘要等元信息\n   ├── article.html    # 排版后的正文 HTML\n   ├── cover.jpg       # 封面图\n   └── imgs/           # 正文内图片\n   ```\n\n### 一键发布\n\n```bash\n# 创建草稿（不发布，可在后台预览）\n{python} skills/aws-wechat-article-publish/scripts/publish.py full article/\n\n# 创建草稿并立即发布\n{python} skills/aws-wechat-article-publish/scripts/publish.py full article/ --publish\n```\n\n### 分步操作\n\n```bash\n# 获取 token\n{python} skills/aws-wechat-article-publish/scripts/publish.py token\n\n# 上传封面图\n{python} skills/aws-wechat-article-publish/scripts/publish.py upload-thumb cover.jpg\n\n# 上传正文图片\n{python} skills/aws-wechat-article-publish/scripts/publish.py upload-content-image imgs/img1.png\n\n# 创建草稿（需要先准备好 article.yaml）\n{python} skills/aws-wechat-article-publish/scripts/publish.py create-draft article.yaml\n\n# 发布\n{python} skills/aws-wechat-article-publish/scripts/publish.py publish <media_id>\n\n# 查询状态\n{python} skills/aws-wechat-article-publish/scripts/publish.py status <publish_id>\n```\n\n接口详情与错误码：[api-reference.md](api-reference.md)\n\n## 方式二：手动提交\n\n1. 登录微信公众平台（mp.weixin.qq.com）\n2. 进入「素材管理」或「草稿箱」→ 新建图文消息\n3. 填写标题、作者、摘要\n4. 将排版后的正文粘贴到正文编辑区\n5. 上传封面图，设置封面\n6. 逐一上传正文内图片并插入对应位置\n7. 设置评论权限（开启/仅粉丝可评）\n8. 保存为草稿或直接群发\n\nFile v1.0.24:references/usage.md\n\n# 发布脚本用法\n\n脚本路径：**`skills/aws-wechat-article-publish/scripts/publish.py`**（在**仓库根**执行）。\n\n- **微信凭证**来自仓库根 **`aws.env`**：`NUMBER_ACCOUNTS`、`WECHAT_1_NAME`、`WECHAT_1_APPID`、`WECHAT_1_APPSECRET`、`WECHAT_1_API_BASE`（1..N 槽位）。`WECHAT_N_API_BASE` 可空（空则官方 `https://api.weixin.qq.com`）。\n- **`publish_method`** 在 **`config.yaml`**：**`draft`**（默认）= **`full`** 只进**草稿箱**；**`published`** = 再**提交发布**；**`none`** = **`full`** **不调接口**（用户不填微信）。**`full --publish`** 可在 **`draft`** 下单次强制发布（**`none`** 下仍跳过）。\n\n## `publish_method` 检查\n\n```bash\n{python} skills/aws-wechat-article-publish/scripts/publish.py check-screening\n{python} skills/aws-wechat-article-publish/scripts/publish.py check-screening --config .aws-article/config.yaml\n```\n\n## 微信槽位检查\n\n```bash\n{python} skills/aws-wechat-article-publish/scripts/publish.py check-wechat-env\n{python} skills/aws-wechat-article-publish/scripts/publish.py accounts\n```\n\n## 一键全流程\n\n```bash\n{python} skills/aws-wechat-article-publish/scripts/publish.py full path/to/article-dir/\n\n{python} skills/aws-wechat-article-publish/scripts/publish.py full path/to/article-dir/ --publish\n\n{python} skills/aws-wechat-article-publish/scripts/publish.py --account 2 full path/to/article-dir/\n```\n\n## 正式文章读取（`getdraft.py`）\n\n与 **`publish.py` 独立**，用于 **`freepublish/batchget`** / **`freepublish/get`** / **`freepublish/getarticle`**（仓库根执行）：\n\n```bash\n{python} skills/aws-wechat-article-publish/scripts/getdraft.py published-fields\n{python} skills/aws-wechat-article-publish/scripts/getdraft.py publish-get <publish_id>\n{python} skills/aws-wechat-article-publish/scripts/getdraft.py article-get <article_id>\n```\n\n## 分步操作\n\n```bash\n{python} skills/aws-wechat-article-publish/scripts/publish.py token\n{python} skills/aws-wechat-article-publish/scripts/publish.py upload-thumb cover.jpg\n{python} skills/aws-wechat-article-publish/scripts/publish.py upload-content-image img.png\n{python} skills/aws-wechat-article-publish/scripts/publish.py create-draft path/to/article.yaml\n{python} skills/aws-wechat-article-publish/scripts/publish.py publish <media_id>\n```\n\nFile v1.0.24:skill-card.md\n\n## Description:\n\nPublishes prepared articles to WeChat Official Accounts by uploading article assets, creating drafts, running pre-publish checks, and optionally submitting public releases.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[aiworkskills](https://clawhub.ai/user/aiworkskills)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nContent operations teams, developers, and WeChat Official Account operators use this skill to create WeChat article drafts, upload cover and body images, submit articles for publication, and inspect publish status.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can send WeChat credentials and unpublished article content to a configured API endpoint.\n\nMitigation: Keep aws.env out of version control, use the default official WeChat API endpoint when possible, and avoid custom API_BASE or proxy settings unless the endpoint is trusted.\n\nRisk: The release evidence security verdict is suspicious and recommends review before installation.\n\nMitigation: Install only from trusted configurations and review the skill, environment settings, and intended target account before execution.\n\nRisk: A publish action can move content from a draft workflow to public distribution.\n\nMitigation: Use draft mode first and require explicit account and article confirmation before any public publish.\n\n## Reference(s):\n\n- [Usage](references/usage.md)\n- [Submit Guide](references/submit-guide.md)\n- [Pre-Publish Checklist](references/pre-publish-checklist.md)\n- [WeChat Official Account API Reference](references/api-reference.md)\n- [ClawHub Skill Page](https://clawhub.ai/aiworkskills/skills/aws-wechat-article-publish)\n- [WeChat Add Draft API](https://developers.weixin.qq.com/doc/subscription/api/draftbox/draftmanage/api_draft_add)\n- [WeChat Free Publish Submit API](https://developers.weixin.qq.com/doc/subscription/api/public/api_freepublish_submit.html)\n- [WeChat Add Permanent Material API](https://developers.weixin.qq.com/doc/subscription/api/material/permanent/api_addmaterial.html)\n- [WeChat Upload Image API](https://developers.weixin.qq.com/doc/subscription/en/api/material/permanent/api_uploadimage)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with inline shell commands and JSON or configuration snippets]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May produce WeChat media_id, publish_id, and status values, and may update article.yaml publication state fields.]\n\n## Skill Version(s):\n\n1.0.24 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.0.24:skill.json\n\n{\n  \"name\": \"aws-wechat-article-publish\",\n  \"version\": \"0.5.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"将文章发布到微信公众号，支持 API 发布和手动提交，含发布前检查。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"publish\", \"api\"],\n  \"permissions\": [\"filesystem\", \"network\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}\n\nArchive v1.0.23: 11 files, 35779 bytes\n\nFiles: references/api-reference.md (4969b), references/pre-publish-checklist.md (536b), references/submit-guide.md (2408b), references/usage.md (2323b), scripts/article_init.py (8564b), scripts/getdraft.py (16742b), scripts/publish.py (46849b), skill-card.md (3048b), skill.json (494b), SKILL.md (13513b), _meta.json (146b)\n\nFile v1.0.23:SKILL.md\n\n---\nname: aws-wechat-article-publish\ndescription: 公众号发布｜公众号草稿箱｜公众号群发｜图文推送｜微信 API｜wechat automation｜WeChat API automation｜auto publish｜scheduled publish — 公众号 API 发布工具，图文入草稿箱或直接群发，支持封面素材上传、发布前检查与 draft/published 模式切换。面向公众号运营、自动化内容团队、开发者。触发词：「发布」「提交」「群发」「推送」「发出去」「上传到公众号」「发到公众号」「可以发了吗」「发布前检查」。需要多环节串联（写+审+排+配图+发）请走 aws-wechat-article-main。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env:\n        - WECHAT_1_APPID\n        - WECHAT_1_APPSECRET\n      bins:\n        - python3\n    primaryEnv: aws.env\n---\n\n# 发布\n\n**公众号 API 直连发布** —— 图文入草稿箱或直接群发，素材上传、发布前检查一站式完成。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 调 `publish.py` **直连微信公众号官方 API** 发布图文。**会把本篇 `article.html` 与 `imgs/*` 文件作为 POST body 上传到微信服务器。** 具体行为：\n\n- **凭证读取**：`aws.env` 的 `WECHAT_{N}_APPID` / `WECHAT_{N}_APPSECRET`（多槽位支持 N≥1）\n- **凭证外发**：`APPID` / `APPSECRET` 以 query string 形式发给 `api.weixin.qq.com/cgi-bin/token` 换 `access_token`；后续请求带 `access_token` query string。微信返回的 `access_token` 在进程内存短期缓存，**不落盘**\n- **内容外发**：本篇封面、正文插图以 multipart upload 发给 `material/add_material`；`article.html` 正文与标题/摘要以 JSON POST 发给 `draft/add`、`freepublish/submit`\n- **网络目标**：默认 `api.weixin.qq.com`；用户可在 `WECHAT_{N}_API_BASE` / `config.yaml.wechat_api_base` 自配反代\n- **文件读**：仓库内 `.aws-article/config.yaml`、`aws.env`、本篇 `article.yaml`、`article.html`、`imgs/*`\n- **文件写**：仅本篇 `article.yaml` 的状态字段（`media_id`、`publish_id`、`publish_completed`）\n- **shell**：仅 `{python} {baseDir}/scripts/publish.py`、`getdraft.py`、`article_init.py`（`{python}` = 本机 Python 3 解释器，见 [main SKILL 第 0 步](../aws-wechat-article-main/SKILL.md)：Windows 用 `py -3 -X utf8`，macOS / Linux 用 `python3`）\n\n**建议**：首次运行用 `publish_method: draft` 只入草稿箱确认效果，再切 `published` 真正群发。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的**发布环节**（入口 `aws-wechat-article-main`）。工作流中的若干步骤会读取同级 `../aws-wechat-article-main/references/*.md` 等共享文档（首次引导、articlescreening schema、env/config 示例等）。\n\n- **套件完整装齐到同一 `skills/` 根目录**时，跨 skill 引用都能读到。\n- **单独安装本 skill** 时，跨 skill 引用的步骤会在读取阶段遇到 `file not found`；但 `publish.py`、`getdraft.py`、`article_init.py` 这几个脚本本身可独立运行（只要 `aws.env` 与 `.aws-article/config.yaml` 就绪）。\n\n完整 9 slug 清单见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n通过微信公众号 API 将排版稿写入**草稿箱**或再**提交发布**（由 **`config.yaml`** 的 **`publish_method`** 与命令行 **`--publish`** 控制）。\n\n## 配置检查 ⛔\n\n任何操作执行前，**必须**按 **[首次引导](../aws-wechat-article-main/references/first-time-setup.md)** 执行其中的 **「检测顺序」**。检测通过后才能进行以下操作（或用户明确书面确认「本次不检查」）：\n\n## 脚本目录\n\n**Agent 执行**：确定本 SKILL.md 所在目录为 `{baseDir}`。发布子命令在 **`{baseDir}/scripts/publish.py`**（项目根执行）。\n\n| 脚本 / 子命令 | 用途 |\n|--------|------|\n| **`article_init.py`** | 初始化或更新本篇 **`article.yaml`**（及可选 **`closing.md`**）。用于总览 **本篇准备**（建目录后）或 **发布前** 补全元数据。仓库根执行：`{python} {baseDir}/scripts/article_init.py <文章目录> [--title … --author … --digest …]` |\n| **`getdraft.py`** | 独立于 `publish.py`：用于正式文章查询（`published-list` / `published-fields` / `publish-get` / `article-get`，对应 `freepublish/*`），可用于 `embeds.related_articles.manual` 为空时自动补全推荐链接。注意：`freepublish/*` 需要公众号具备对应接口权限。仓库根：`{python} {baseDir}/scripts/getdraft.py published-fields` |\n| `check-screening` | 校验 **`config.yaml`** 的 **`publish_method`**（**`draft`** / **`published`** / **`none`**） |\n| `check-wechat-env` | 按 **`config.yaml` 槽位**检查 `aws.env` 的 `WECHAT_N_APPID` / `WECHAT_N_APPSECRET` 是否已填（**调用 `publish.py` 前建议跑**） |\n| `check` | 环境检查：`aws.env`、各槽位、依赖、可选探测 token |\n| `accounts` | 列出 **`config.yaml`** 中各微信槽位名称，并标记 `aws.env` 凭证缺项 |\n| `full` / `token` / … | 调微信 API（需 **`aws.env`** 微信凭证） |\n\n## 凭证与 `publish_method` ⛔\n\n### `publish_method`（以仓库 **`config.yaml`** 为准）\n\n| 值 | 含义 | 行为 |\n|----|------|------|\n| **`draft`**（默认） | 只进公众号**草稿箱** | **`full`** 创建草稿后**不**调用 freepublish 提交发布。 |\n| **`published`** | 草稿 + **提交发布** | **`full`** 创建草稿后继续提交发布（异步）。**`full --publish`** 可**单次强制**带发布，即使当前为 **`draft`**。 |\n| **`none`** | 用户明确不填微信 | **`full`** **立即退出**，不调任何微信接口（**`--publish`** 也会被忽略）。其它子命令（`token` 等）仍要凭证。 |\n\n### 多账号时如何选槽位\n\n1. 运行 **`{python} {baseDir}/scripts/publish.py accounts`**，从 **`config.yaml` 的 `wechat_accounts` + `wechat_N_name`** 向用户展示列表（例如：`您有2个账号：1.\"xiaoming\"，2.\"xiaoz\"`）必须询问用户选择哪个账号发布到草稿箱，然后根据用户选择发布到指定的账号。\n2. 在 **`config.yaml`** 写 **`wechat_publish_slot: <整数>`**，**或**命令行 **`--account <序号或名称>`**（**CLI 优先**，见 [articlescreening-schema.md](../aws-wechat-article-main/references/articlescreening-schema.md)）。\n\n### 全局环境\n\n在仓库根具备 **`aws.env`**（微信密钥）与 **`config.yaml`**（微信槽位数量与名称）。写作/生图见 **`validate_env.py`**（微信未齐仍可先做内容）。**`publish_method: none`** 时 **`full`** 会跳过；**`draft`/`published`** 发布前建议 **`check-wechat-env`**。API 端点优先取 **`WECHAT_N_API_BASE`**，若槽位未配则回退 **`config.yaml.wechat_api_base`**（两者都空时使用官方）。\n\n### 作者名回退\n\n`full` / `create-draft` 若 **`article.yaml` 无 author**，回退 **`config.yaml`** 的 **`default_author`**。\n\n### `publish_completed`（本篇是否已发布完成）\n\n- 字段在**本篇** **`article.yaml`**。**`publish.py` 不读、不改**；由智能体维护。\n- **`false`**：发布流程未闭环。\n- **`true`**：已视为发布完成（草稿已确认 / 或 **`published`** 流程成功且运营确认）。\n\n**本篇发布真正结束后**：将 **`publish_completed: true`** 写回 **`article.yaml`**。\n\n**写回 `true` 的前置门禁（缺啥补啥）**：\n\n1. `article.html` 存在；\n2. 文章目录存在封面图 `cover.(png/jpg/jpeg/webp)`；\n\n   **封面裁剪框**：微信只收一张封面，但 `draft/add` 可附带两个裁剪框，分别决定 **2.35:1**（订阅号信息流首图）与 **1:1**（分享卡片、公众号主页、历史列表）怎么裁；不传时微信自行居中裁切。`publish.py` 会按封面实际尺寸自动算出两个框并随草稿提交（需 Pillow；未安装则跳过，交给微信默认行为）。\n   \n   设计取向是 **2.35:1 优先**——信息流那一眼决定点不点，1:1 作降级视图。所以封面按 2.35:1 构图即可，不必为迁就方形而牺牲主视图。\n   \n   需要手动指定时，在本篇 `article.yaml` 写 **`pic_crop_235_1`** / **`pic_crop_1_1`**（`X1_Y1_X2_Y2` 归一化 0~1），脚本不再覆盖。注意裁出区域的宽高比须与目标比例一致，否则接口返回 **53402**「封面裁剪失败」。\n3. `article.md` 与 `article.html` 中均不含 `placeholder`；\n4. 发布命令成功并拿到回执（`media_id` 或 `publish_id`）。\n\n任一不满足：只可标记为“已提交草稿，未闭环”，**不得**写回 `publish_completed: true`。\n\n## 用户仅说「发布」且未明确路径时 ⛔\n\n在用户**未给出** `drafts/…` 路径、仅说「发布文章」「帮我发一下」等时：\n\n1. **确定本篇目录**：列出仓库下 **`drafts/`** 中子目录；若**多篇**，请用户**指定一篇**或选「最新修改」的一篇再读该目录 **`article.yaml`**。**勿**在未确认目录时假定路径。\n2. 读取该目录 **`article.yaml`** 中的 **`publish_completed`**（YAML 布尔：`true` / `false`；**缺省按 `false` 处理**）。\n\n| `publish_completed` | 智能体对用户说明（可略作口语化，勿改含义） |\n|---------------------|---------------------------------------------|\n| **`true`** | 告知：**项目里本篇文档已按记录成功发布**；问：**您是否需要编写新文章？** 若需要 → 转交 [main](../aws-wechat-article-main/SKILL.md) / [writing](../aws-wechat-article-writing/SKILL.md) 从本篇准备或选题起走。 |\n| **`false`** 或缺省 | 读取 **`article.yaml`** 的 **`title`**（若无则用目录名简述），说明：**《{title}》尚未执行完成（发布流程未闭环）**；问：**是否需要继续并完成发布？** 或 **编写新文章？** 若继续本篇 → 再核对 **`config.yaml`** 的 **`publish_method`**、**`check-screening`**、**`check-wechat-env`** 等。 |\n\n## 工作流\n\n```\n发布进度：\n- [ ] 前置：配置检查（见本节「配置检查」）⛔\n- [ ] 第0步：若用户未给路径 → 选本篇目录 → 读 publish_completed → 按上表分流（true/false）\n- [ ] 第1步：读 **`config.yaml`** → **`draft` / `published`**（及是否 **`full --publish`**）\n- [ ] 第2步：读取 **`config.yaml`** 的 `wechat_accounts` + `wechat_N_name` 向用户展示账号列表并询问目标槽位；随后跑 **`check-wechat-env`** 校验 `aws.env` 凭证 → **`wechat_publish_slot` 或 `--account`**\n- [ ] 第3步：发布前检查（checklist + **`check-screening`** + **`check`**）\n- [ ] 第4步：准备文章目录\n- [ ] 第5步：**`full`**（仅草稿或含发布，视上步）\n- [ ] 第6步：确认结果与用户说明\n- [ ] 第7步：成功后写回 **`article.yaml`** 的 **`publish_completed: true`**；按需归档\n```\n\n## 交互顺序（最小提问）\n\n0) **未给路径时**：先按上文 **「用户仅说发布」** 处理 **`publish_completed`**；用户选 **继续本篇** 后再做下列步骤。  \n1) **先看 `config.yaml` 的 `publish_method`**：**`draft`** = 默认只进草稿箱；**`published`** 或 **`full --publish`** = 再提交发布。  \n2) **多槽位**：展示账号列表（来源：`config.yaml` 的 `wechat_accounts` + `wechat_N_name`），**必须请用户选槽位** → **`wechat_publish_slot`** 或 **`--account`**。  \n3) 缺微信字段：运行 **`check-wechat-env`**，补全 **`aws.env`** 后再发。  \n4) **发布失败**（由脚本 stderr / 微信 errcode 判断）：  \n   - **网络类**（超时、连接失败、5xx）：脚本已对单次请求 **自动重试 1 次**；仍失败 → 告知「网络不可用，请稍后重试或检查代理」。  \n   - **凭证/配置类**（如 token 失败带 errcode、缺字段）→ 提示 **第几槽位**、检查 **APPID/SECRET、IP 白名单**，用户改正后再执行 **`full`** / **`publish`**。\n5) **中间产物缺失**（封面缺失 / 存在 `placeholder`）：先补产物再发；若用户坚持先发草稿，必须明确告知“正文配图未完成”，且保持 `publish_completed: false`。\n\n## 命令示例（仓库根）\n\n```bash\n{python} {baseDir}/scripts/publish.py check-screening\n{python} {baseDir}/scripts/publish.py check-wechat-env\n{python} {baseDir}/scripts/publish.py accounts\n{python} {baseDir}/scripts/publish.py check\n{python} {baseDir}/scripts/publish.py --account 1 full drafts/YYYYMMDD-标题slug/\n{python} {baseDir}/scripts/getdraft.py published-fields\n```\n\n详见 [references/usage.md](references/usage.md)、[references/submit-guide.md](references/submit-guide.md)、[references/api-reference.md](references/api-reference.md)。\n\n## 过程文件\n\n| 读取 | 产出 |\n|------|------|\n| `article.html`、`imgs/`、**`article.yaml`**（含 **`publish_completed`** 等）、**`.aws-article/config.yaml`**、**`aws.env`**（微信槽位） | 发布到公众号草稿或提交发布；**成功后**由智能体将 **`publish_completed: true`** 写回 **`article.yaml`**（`publish.py` 不改此键） |\n\nFile v1.0.23:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-publish\",\n  \"version\": \"1.0.23\",\n  \"publishedAt\": 1788679495166\n}\n\nFile v1.0.23:references/api-reference.md\n\n# 微信公众号 API 参考\n\n## 接口一览\n\n| 接口 | 方法 | 路径 | 用途 |\n|------|------|------|------|\n| 获取 token | GET | `/token` | 获取 access_token |\n| 上传永久素材 | POST | `/material/add_material` | 上传封面图，返回 media_id |\n| 上传正文图片 | POST | `/media/uploadimg` | 上传正文内图片，返回 URL |\n| 新增草稿 | POST | `/draft/add` | 创建图文草稿 |\n| 发布草稿 | POST | `/freepublish/submit` | 发布草稿（异步） |\n| 查询发布状态 | POST | `/freepublish/get` | 查询发布结果 |\n\n所有接口基础 URL：`https://api.weixin.qq.com/cgi-bin`\n\n## 获取 access_token\n\n```\nGET /token?grant_type=client_credential&appid={APPID}&secret={APPSECRET}\n```\n\n返回：\n```json\n{\"access_token\": \"...\", \"expires_in\": 7200}\n```\n\n有效期 2 小时，需缓存复用，避免频繁请求。\n\n## 上传封面图（永久素材）\n\n```\nPOST /material/add_material?access_token={TOKEN}&type=image\nContent-Type: multipart/form-data\n```\n\n- 字段名：`media`\n- 限制：10MB，支持 bmp/png/jpeg/jpg/gif\n- 永久素材上限：100,000 张\n\n返回：\n```json\n{\"media_id\": \"...\", \"url\": \"...\"}\n```\n\n`media_id` 用于 `draft/add` 的 `thumb_media_id` 字段。\n\n## 上传正文图片\n\n```\nPOST /media/uploadimg?access_token={TOKEN}\nContent-Type: multipart/form-data\n```\n\n- 字段名：`media`\n- 限制：1MB，支持 jpg/png\n- 不占用素材库配额\n- 返回的 URL 可直接在正文 HTML 中使用\n\n返回：\n```json\n{\"url\": \"https://mmbiz.qpic.cn/...\"}\n```\n\n## 新增草稿\n\n```\nPOST /draft/add?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\n  \"articles\": [{\n    \"title\": \"标题（≤32字）\",\n    \"author\": \"作者（≤16字）\",\n    \"digest\": \"摘要（≤128字，仅单图文）\",\n    \"content\": \"HTML 正文（≤2万字符，图片 URL 必须来自 uploadimg）\",\n    \"thumb_media_id\": \"封面图 media_id\",\n    \"content_source_url\": \"原文链接\",\n    \"need_open_comment\": 1,\n    \"only_fans_can_comment\": 0\n  }]\n}\n```\n\n返回：\n```json\n{\"media_id\": \"...\"}\n```\n\n## 发布草稿\n\n```\nPOST /freepublish/submit?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\"media_id\": \"草稿的 media_id\"}\n```\n\n返回：\n```json\n{\"publish_id\": \"...\", \"msg_data_id\": \"...\"}\n```\n\n**注意**：发布为异步操作，返回成功仅表示任务提交成功。\n\n## 查询发布状态\n\n```\nPOST /freepublish/get?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\"publish_id\": \"...\"}\n```\n\n返回 `publish_status`：\n\n| 值 | 含义 |\n|----|------|\n| 0 | 发布成功 |\n| 1 | 发布中 |\n| 2 | 原创失败 |\n| 3 | 常规失败 |\n| 4 | 平台审核不通过 |\n| 5 | 已删除 |\n| 6 | 已封禁 |\n\n## 常见错误码\n\n| 错误码 | 含义 | 处理 |\n|--------|------|------|\n| 40001 | access_token 无效 | 重新获取 token |\n| 40004 | 不合法的媒体文件类型 | 检查图片格式 |\n| 40009 | 图片大小超限 | 封面 ≤10MB，正文图 ≤1MB |\n| 45009 | API 调用超限 | 等待后重试 |\n| 45028 | 接口无权限 | 检查公众号类型和权限 |\n| 48001 | API 未授权 | 检查公众号开发者设置 |\n\n## 凭证配置\n\n在仓库根 **`aws.env`** 中配置微信槽位（勿提交含真密钥的文件）：\n\n```env\nNUMBER_ACCOUNTS=1\nWECHAT_1_NAME=主号\nWECHAT_1_APPID=你的AppID\nWECHAT_1_APPSECRET=你的AppSecret\nWECHAT_1_API_BASE=\n```\n\n键名与 `skills/aws-wechat-article-main/references/env.example.yaml` 一致。多账号递增 `WECHAT_2_*` 等。\n\n## 权限要求\n\n- 需要已认证的服务号或订阅号\n- AppID 和 AppSecret 在「开发 → 基本配置」获取\n- 调用服务器 IP 需加入白名单\n\n## 官方文档\n\n- [新增草稿](https://developers.weixin.qq.com/doc/subscription/api/draftbox/draftmanage/api_draft_add)\n- [发布草稿](https://developers.weixin.qq.com/doc/subscription/api/public/api_freepublish_submit.html)\n- [上传永久素材](https://developers.weixin.qq.com/doc/subscription/api/material/permanent/api_addmaterial.html)\n- [上传正文图片](https://developers.weixin.qq.com/doc/subscription/en/api/material/permanent/api_uploadimage)\n\n## 封面裁剪框 pic_crop_* 的回读\n\n`draft/add` 接受 `pic_crop_235_1` / `pic_crop_1_1`（归一化 `X1_Y1_X2_Y2`），但\n**`draft/get` 不回显这两个字段**——它把值归一化后放进 `cover_info.crop_percent_list`：\n\n```json\n\"cover_info\": {\n  \"crop_percent_list\": [\n    {\"ratio\": \"2.35_1\", \"x1\": \"0.001515\", \"y1\": \"0\", \"x2\": \"0.998485\", \"y2\": \"1\"},\n    {\"ratio\": \"1_1\",    \"x1\": \"0.287879\", \"y1\": \"0\", \"x2\": \"0.712121\", \"y2\": \"1\"}\n  ]\n}\n```\n\n不知道这点会得出「微信忽略了裁剪框」的错误结论——在 `news_item[0]` 里查\n`pic_crop_235_1` 只会拿到 `None`。校验请读 `cover_info.crop_percent_list`，\n`ratio` 用下划线写法（`2.35_1` / `1_1`）。\n\n实测（1584x672 封面）微信原样存下，六位小数完全一致；比例不匹配时才会报 53402。\n\nFile v1.0.23:references/pre-publish-checklist.md\n\n# 发布前检查清单\n\n在审稿通过后、实际提交前执行，确保可安全发布。\n\n## 检查项\n\n- [ ] 标题、摘要、作者已最终确认\n- [ ] 正文无未替换的占位符或草稿标记\n- [ ] 敏感词与错别字已在审稿中修正\n- [ ] 封面图已就绪（已上传或路径有效）\n- [ ] 正文内图片齐全，图注格式正确\n- [ ] 原创/转载标注已按配置处理\n- [ ] 文末引导区块已就位\n- [ ] 如需开启评论/仅粉丝可评，已确认设置\n\n全部勾选后执行提交步骤。\n\nFile v1.0.23:references/submit-guide.md\n\n# 提交到公众号后台\n\n## 方式一：API 提交（推荐）\n\n使用 `skills/aws-wechat-article-publish/scripts/publish.py`，通过微信公众号 API 完成发布。\n\n### 前置准备\n\n1. 在仓库根 **`aws.env`** 中填写微信槽位（与 `skills/aws-wechat-article-main/references/env.example.yaml` 键名一致），例如单账号：\n   ```env\n   NUMBER_ACCOUNTS=1\n   WECHAT_1_NAME=主号\n   WECHAT_1_APPID=你的AppID\n   WECHAT_1_APPSECRET=你的AppSecret\n   WECHAT_1_API_BASE=\n   ```\n   多账号递增 `WECHAT_2_*` 等；发布前可运行 `{python} skills/aws-wechat-article-publish/scripts/publish.py check-wechat-env` 检查缺项。\n\n2. 在公众平台「开发 → 基本配置」中将服务器 IP 加入白名单\n\n3. 准备文章目录：\n   ```\n   article/\n   ├── article.yaml    # 标题、作者、摘要等元信息\n   ├── article.html    # 排版后的正文 HTML\n   ├── cover.jpg       # 封面图\n   └── imgs/           # 正文内图片\n   ```\n\n### 一键发布\n\n```bash\n# 创建草稿（不发布，可在后台预览）\n{python} skills/aws-wechat-article-publish/scripts/publish.py full article/\n\n# 创建草稿并立即发布\n{python} skills/aws-wechat-article-publish/scripts/publish.py full article/ --publish\n```\n\n### 分步操作\n\n```bash\n# 获取 token\n{python} skills/aws-wechat-article-publish/scripts/publish.py token\n\n# 上传封面图\n{python} skills/aws-wechat-article-publish/scripts/publish.py upload-thumb cover.jpg\n\n# 上传正文图片\n{python} skills/aws-wechat-article-publish/scripts/publish.py upload-content-image imgs/img1.png\n\n# 创建草稿（需要先准备好 article.yaml）\n{python} skills/aws-wechat-article-publish/scripts/publish.py create-draft article.yaml\n\n# 发布\n{python} skills/aws-wechat-article-publish/scripts/publish.py publish <media_id>\n\n# 查询状态\n{python} skills/aws-wechat-article-publish/scripts/publish.py status <publish_id>\n```\n\n接口详情与错误码：[api-reference.md](api-reference.md)\n\n## 方式二：手动提交\n\n1. 登录微信公众平台（mp.weixin.qq.com）\n2. 进入「素材管理」或「草稿箱」→ 新建图文消息\n3. 填写标题、作者、摘要\n4. 将排版后的正文粘贴到正文编辑区\n5. 上传封面图，设置封面\n6. 逐一上传正文内图片并插入对应位置\n7. 设置评论权限（开启/仅粉丝可评）\n8. 保存为草稿或直接群发\n\nFile v1.0.23:references/usage.md\n\n# 发布脚本用法\n\n脚本路径：**`skills/aws-wechat-article-publish/scripts/publish.py`**（在**仓库根**执行）。\n\n- **微信凭证**来自仓库根 **`aws.env`**：`NUMBER_ACCOUNTS`、`WECHAT_1_NAME`、`WECHAT_1_APPID`、`WECHAT_1_APPSECRET`、`WECHAT_1_API_BASE`（1..N 槽位）。`WECHAT_N_API_BASE` 可空（空则官方 `https://api.weixin.qq.com`）。\n- **`publish_method`** 在 **`config.yaml`**：**`draft`**（默认）= **`full`** 只进**草稿箱**；**`published`** = 再**提交发布**；**`none`** = **`full`** **不调接口**（用户不填微信）。**`full --publish`** 可在 **`draft`** 下单次强制发布（**`none`** 下仍跳过）。\n\n## `publish_method` 检查\n\n```bash\n{python} skills/aws-wechat-article-publish/scripts/publish.py check-screening\n{python} skills/aws-wechat-article-publish/scripts/publish.py check-screening --config .aws-article/config.yaml\n```\n\n## 微信槽位检查\n\n```bash\n{python} skills/aws-wechat-article-publish/scripts/publish.py check-wechat-env\n{python} skills/aws-wechat-article-publish/scripts/publish.py accounts\n```\n\n## 一键全流程\n\n```bash\n{python} skills/aws-wechat-article-publish/scripts/publish.py full path/to/article-dir/\n\n{python} skills/aws-wechat-article-publish/scripts/publish.py full path/to/article-dir/ --publish\n\n{python} skills/aws-wechat-article-publish/scripts/publish.py --account 2 full path/to/article-dir/\n```\n\n## 正式文章读取（`getdraft.py`）\n\n与 **`publish.py` 独立**，用于 **`freepublish/batchget`** / **`freepublish/get`** / **`freepublish/getarticle`**（仓库根执行）：\n\n```bash\n{python} skills/aws-wechat-article-publish/scripts/getdraft.py published-fields\n{python} skills/aws-wechat-article-publish/scripts/getdraft.py publish-get <publish_id>\n{python} skills/aws-wechat-article-publish/scripts/getdraft.py article-get <article_id>\n```\n\n## 分步操作\n\n```bash\n{python} skills/aws-wechat-article-publish/scripts/publish.py token\n{python} skills/aws-wechat-article-publish/scripts/publish.py upload-thumb cover.jpg\n{python} skills/aws-wechat-article-publish/scripts/publish.py upload-content-image img.png\n{python} skills/aws-wechat-article-publish/scripts/publish.py create-draft path/to/article.yaml\n{python} skills/aws-wechat-article-publish/scripts/publish.py publish <media_id>\n```\n\nFile v1.0.23:skill-card.md\n\n## Description:\n\nPublishes prepared WeChat Official Account articles to draft or submission workflows through the WeChat API, with cover upload, pre-publish checks, and draft/published mode controls.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[aiworkskills](https://clawhub.ai/user/aiworkskills)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nExternal operators, automation teams, and developers use this skill to move finalized WeChat Official Account content into the official draft box or submit it for publication. It supports account selection, configuration checks, media upload, and status tracking for prepared article directories.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Configured custom API endpoints can receive WeChat secrets, access tokens, article content, and images.\n\nMitigation: Keep WECHAT_N_API_BASE and wechat_api_base empty unless intentionally using a trusted HTTPS proxy, and verify the destination before running token, query, upload, full, or publish commands.\n\nRisk: The skill can move content from draft preparation into WeChat publication workflows.\n\nMitigation: Prefer draft mode first, confirm account and publish_method configuration, and require explicit confirmation before submitting content for publication.\n\nRisk: WeChat credentials are expected in aws.env.\n\nMitigation: Keep aws.env out of source control and use tightly scoped WeChat credentials.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/aiworkskills/skills/aws-wechat-article-publish)\n- [Publisher profile](https://clawhub.ai/user/aiworkskills)\n- [微信公众号 API 参考](references/api-reference.md)\n- [发布脚本用法](references/usage.md)\n- [提交到公众号](references/submit-guide.md)\n- [发布前检查清单](references/pre-publish-checklist.md)\n- [WeChat draft add API](https://developers.weixin.qq.com/doc/subscription/api/draftbox/draftmanage/api_draft_add)\n- [WeChat freepublish submit API](https://developers.weixin.qq.com/doc/subscription/api/public/api_freepublish_submit.html)\n- [WeChat add permanent material API](https://developers.weixin.qq.com/doc/subscription/api/material/permanent/api_addmaterial.html)\n- [WeChat upload article image API](https://developers.weixin.qq.com/doc/subscription/en/api/material/permanent/api_uploadimage)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown guidance with inline shell commands and JSON/YAML configuration notes]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May issue WeChat API calls and update article status files when the user proceeds with publishing.]\n\n## Skill Version(s):\n\n1.0.23 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.0.23:skill.json\n\n{\n  \"name\": \"aws-wechat-article-publish\",\n  \"version\": \"0.5.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"将文章发布到微信公众号，支持 API 发布和手动提交，含发布前检查。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"publish\", \"api\"],\n  \"permissions\": [\"filesystem\", \"network\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}\n\nArchive v1.0.22: 11 files, 32531 bytes\n\nFiles: references/api-reference.md (4153b), references/pre-publish-checklist.md (536b), references/submit-guide.md (2390b), references/usage.md (2293b), scripts/article_init.py (8283b), scripts/getdraft.py (16742b), scripts/publish.py (42311b), skill-card.md (2673b), skill.json (494b), SKILL.md (12465b), _meta.json (146b)\n\nFile v1.0.22:SKILL.md\n\n---\nname: aws-wechat-article-publish\ndescription: 公众号发布｜公众号草稿箱｜公众号群发｜图文推送｜微信 API｜wechat automation｜WeChat API automation｜auto publish｜scheduled publish — 公众号 API 发布工具，图文入草稿箱或直接群发，支持封面素材上传、发布前检查与 draft/published 模式切换。面向公众号运营、自动化内容团队、开发者。触发词：「发布」「提交」「群发」「推送」「发出去」「上传到公众号」「发到公众号」「可以发了吗」「发布前检查」。需要多环节串联（写+审+排+配图+发）请走 aws-wechat-article-main。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env:\n        - WECHAT_1_APPID\n        - WECHAT_1_APPSECRET\n      bins:\n        - python3\n    primaryEnv: aws.env\n---\n\n# 发布\n\n**公众号 API 直连发布** —— 图文入草稿箱或直接群发，素材上传、发布前检查一站式完成。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 调 `publish.py` **直连微信公众号官方 API** 发布图文。**会把本篇 `article.html` 与 `imgs/*` 文件作为 POST body 上传到微信服务器。** 具体行为：\n\n- **凭证读取**：`aws.env` 的 `WECHAT_{N}_APPID` / `WECHAT_{N}_APPSECRET`（多槽位支持 N≥1）\n- **凭证外发**：`APPID` / `APPSECRET` 以 query string 形式发给 `api.weixin.qq.com/cgi-bin/token` 换 `access_token`；后续请求带 `access_token` query string。微信返回的 `access_token` 在进程内存短期缓存，**不落盘**\n- **内容外发**：本篇封面、正文插图以 multipart upload 发给 `material/add_material`；`article.html` 正文与标题/摘要以 JSON POST 发给 `draft/add`、`freepublish/submit`\n- **网络目标**：默认 `api.weixin.qq.com`；用户可在 `WECHAT_{N}_API_BASE` / `config.yaml.wechat_api_base` 自配反代\n- **文件读**：仓库内 `.aws-article/config.yaml`、`aws.env`、本篇 `article.yaml`、`article.html`、`imgs/*`\n- **文件写**：仅本篇 `article.yaml` 的状态字段（`media_id`、`publish_id`、`publish_completed`）\n- **shell**：仅 `python3 {baseDir}/scripts/publish.py`、`getdraft.py`、`article_init.py`\n\n**建议**：首次运行用 `publish_method: draft` 只入草稿箱确认效果，再切 `published` 真正群发。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的**发布环节**（入口 `aws-wechat-article-main`）。工作流中的若干步骤会读取同级 `../aws-wechat-article-main/references/*.md` 等共享文档（首次引导、articlescreening schema、env/config 示例等）。\n\n- **套件完整装齐到同一 `skills/` 根目录**时，跨 skill 引用都能读到。\n- **单独安装本 skill** 时，跨 skill 引用的步骤会在读取阶段遇到 `file not found`；但 `publish.py`、`getdraft.py`、`article_init.py` 这几个脚本本身可独立运行（只要 `aws.env` 与 `.aws-article/config.yaml` 就绪）。\n\n完整 9 slug 清单见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n通过微信公众号 API 将排版稿写入**草稿箱**或再**提交发布**（由 **`config.yaml`** 的 **`publish_method`** 与命令行 **`--publish`** 控制）。\n\n## 配置检查 ⛔\n\n任何操作执行前，**必须**按 **[首次引导](../aws-wechat-article-main/references/first-time-setup.md)** 执行其中的 **「检测顺序」**。检测通过后才能进行以下操作（或用户明确书面确认「本次不检查」）：\n\n## 脚本目录\n\n**Agent 执行**：确定本 SKILL.md 所在目录为 `{baseDir}`。发布子命令在 **`{baseDir}/scripts/publish.py`**（项目根执行）。\n\n| 脚本 / 子命令 | 用途 |\n|--------|------|\n| **`article_init.py`** | 初始化或更新本篇 **`article.yaml`**（及可选 **`closing.md`**）。用于总览 **本篇准备**（建目录后）或 **发布前** 补全元数据。仓库根执行：`python {baseDir}/scripts/article_init.py <文章目录> [--title … --author … --digest …]` |\n| **`getdraft.py`** | 独立于 `publish.py`：用于正式文章查询（`published-list` / `published-fields` / `publish-get` / `article-get`，对应 `freepublish/*`），可用于 `embeds.related_articles.manual` 为空时自动补全推荐链接。注意：`freepublish/*` 需要公众号具备对应接口权限。仓库根：`python {baseDir}/scripts/getdraft.py published-fields` |\n| `check-screening` | 校验 **`config.yaml`** 的 **`publish_method`**（**`draft`** / **`published`** / **`none`**） |\n| `check-wechat-env` | 按 **`config.yaml` 槽位**检查 `aws.env` 的 `WECHAT_N_APPID` / `WECHAT_N_APPSECRET` 是否已填（**调用 `publish.py` 前建议跑**） |\n| `check` | 环境检查：`aws.env`、各槽位、依赖、可选探测 token |\n| `accounts` | 列出 **`config.yaml`** 中各微信槽位名称，并标记 `aws.env` 凭证缺项 |\n| `full` / `token` / … | 调微信 API（需 **`aws.env`** 微信凭证） |\n\n## 凭证与 `publish_method` ⛔\n\n### `publish_method`（以仓库 **`config.yaml`** 为准）\n\n| 值 | 含义 | 行为 |\n|----|------|------|\n| **`draft`**（默认） | 只进公众号**草稿箱** | **`full`** 创建草稿后**不**调用 freepublish 提交发布。 |\n| **`published`** | 草稿 + **提交发布** | **`full`** 创建草稿后继续提交发布（异步）。**`full --publish`** 可**单次强制**带发布，即使当前为 **`draft`**。 |\n| **`none`** | 用户明确不填微信 | **`full`** **立即退出**，不调任何微信接口（**`--publish`** 也会被忽略）。其它子命令（`token` 等）仍要凭证。 |\n\n### 多账号时如何选槽位\n\n1. 运行 **`python {baseDir}/scripts/publish.py accounts`**，从 **`config.yaml` 的 `wechat_accounts` + `wechat_N_name`** 向用户展示列表（例如：`您有2个账号：1.\"xiaoming\"，2.\"xiaoz\"`）必须询问用户选择哪个账号发布到草稿箱，然后根据用户选择发布到指定的账号。\n2. 在 **`config.yaml`** 写 **`wechat_publish_slot: <整数>`**，**或**命令行 **`--account <序号或名称>`**（**CLI 优先**，见 [articlescreening-schema.md](../aws-wechat-article-main/references/articlescreening-schema.md)）。\n\n### 全局环境\n\n在仓库根具备 **`aws.env`**（微信密钥）与 **`config.yaml`**（微信槽位数量与名称）。写作/生图见 **`validate_env.py`**（微信未齐仍可先做内容）。**`publish_method: none`** 时 **`full`** 会跳过；**`draft`/`published`** 发布前建议 **`check-wechat-env`**。API 端点优先取 **`WECHAT_N_API_BASE`**，若槽位未配则回退 **`config.yaml.wechat_api_base`**（两者都空时使用官方）。\n\n### 作者名回退\n\n`full` / `create-draft` 若 **`article.yaml` 无 author**，回退 **`config.yaml`** 的 **`default_author`**。\n\n### `publish_completed`（本篇是否已发布完成）\n\n- 字段在**本篇** **`article.yaml`**。**`publish.py` 不读、不改**；由智能体维护。\n- **`false`**：发布流程未闭环。\n- **`true`**：已视为发布完成（草稿已确认 / 或 **`published`** 流程成功且运营确认）。\n\n**本篇发布真正结束后**：将 **`publish_completed: true`** 写回 **`article.yaml`**。\n\n**写回 `true` 的前置门禁（缺啥补啥）**：\n\n1. `article.html` 存在；\n2. 文章目录存在封面图 `cover.(png/jpg/jpeg/webp)`；\n3. `article.md` 与 `article.html` 中均不含 `placeholder`；\n4. 发布命令成功并拿到回执（`media_id` 或 `publish_id`）。\n\n任一不满足：只可标记为“已提交草稿，未闭环”，**不得**写回 `publish_completed: true`。\n\n## 用户仅说「发布」且未明确路径时 ⛔\n\n在用户**未给出** `drafts/…` 路径、仅说「发布文章」「帮我发一下」等时：\n\n1. **确定本篇目录**：列出仓库下 **`drafts/`** 中子目录；若**多篇**，请用户**指定一篇**或选「最新修改」的一篇再读该目录 **`article.yaml`**。**勿**在未确认目录时假定路径。\n2. 读取该目录 **`article.yaml`** 中的 **`publish_completed`**（YAML 布尔：`true` / `false`；**缺省按 `false` 处理**）。\n\n| `publish_completed` | 智能体对用户说明（可略作口语化，勿改含义） |\n|---------------------|---------------------------------------------|\n| **`true`** | 告知：**项目里本篇文档已按记录成功发布**；问：**您是否需要编写新文章？** 若需要 → 转交 [main](../aws-wechat-article-main/SKILL.md) / [writing](../aws-wechat-article-writing/SKILL.md) 从本篇准备或选题起走。 |\n| **`false`** 或缺省 | 读取 **`article.yaml`** 的 **`title`**（若无则用目录名简述），说明：**《{title}》尚未执行完成（发布流程未闭环）**；问：**是否需要继续并完成发布？** 或 **编写新文章？** 若继续本篇 → 再核对 **`config.yaml`** 的 **`publish_method`**、**`check-screening`**、**`check-wechat-env`** 等。 |\n\n## 工作流\n\n```\n发布进度：\n- [ ] 前置：配置检查（见本节「配置检查」）⛔\n- [ ] 第0步：若用户未给路径 → 选本篇目录 → 读 publish_completed → 按上表分流（true/false）\n- [ ] 第1步：读 **`config.yaml`** → **`draft` / `published`**（及是否 **`full --publish`**）\n- [ ] 第2步：读取 **`config.yaml`** 的 `wechat_accounts` + `wechat_N_name` 向用户展示账号列表并询问目标槽位；随后跑 **`check-wechat-env`** 校验 `aws.env` 凭证 → **`wechat_publish_slot` 或 `--account`**\n- [ ] 第3步：发布前检查（checklist + **`check-screening`** + **`check`**）\n- [ ] 第4步：准备文章目录\n- [ ] 第5步：**`full`**（仅草稿或含发布，视上步）\n- [ ] 第6步：确认结果与用户说明\n- [ ] 第7步：成功后写回 **`article.yaml`** 的 **`publish_completed: true`**；按需归档\n```\n\n## 交互顺序（最小提问）\n\n0) **未给路径时**：先按上文 **「用户仅说发布」** 处理 **`publish_completed`**；用户选 **继续本篇** 后再做下列步骤。  \n1) **先看 `config.yaml` 的 `publish_method`**：**`draft`** = 默认只进草稿箱；**`published`** 或 **`full --publish`** = 再提交发布。  \n2) **多槽位**：展示账号列表（来源：`config.yaml` 的 `wechat_accounts` + `wechat_N_name`），**必须请用户选槽位** → **`wechat_publish_slot`** 或 **`--account`**。  \n3) 缺微信字段：运行 **`check-wechat-env`**，补全 **`aws.env`** 后再发。  \n4) **发布失败**（由脚本 stderr / 微信 errcode 判断）：  \n   - **网络类**（超时、连接失败、5xx）：脚本已对单次请求 **自动重试 1 次**；仍失败 → 告知「网络不可用，请稍后重试或检查代理」。  \n   - **凭证/配置类**（如 token 失败带 errcode、缺字段）→ 提示 **第几槽位**、检查 **APPID/SECRET、IP 白名单**，用户改正后再执行 **`full`** / **`publish`**。\n5) **中间产物缺失**（封面缺失 / 存在 `placeholder`）：先补产物再发；若用户坚持先发草稿，必须明确告知“正文配图未完成”，且保持 `publish_completed: false`。\n\n## 命令示例（仓库根）\n\n```bash\npython {baseDir}/scripts/publish.py check-screening\npython {baseDir}/scripts/publish.py check-wechat-env\npython {baseDir}/scripts/publish.py accounts\npython {baseDir}/scripts/publish.py check\npython {baseDir}/scripts/publish.py --account 1 full drafts/YYYYMMDD-标题slug/\npython {baseDir}/scripts/getdraft.py published-fields\n```\n\n详见 [references/usage.md](references/usage.md)、[references/submit-guide.md](references/submit-guide.md)、[references/api-reference.md](references/api-reference.md)。\n\n## 过程文件\n\n| 读取 | 产出 |\n|------|------|\n| `article.html`、`imgs/`、**`article.yaml`**（含 **`publish_completed`** 等）、**`.aws-article/config.yaml`**、**`aws.env`**（微信槽位） | 发布到公众号草稿或提交发布；**成功后**由智能体将 **`publish_completed: true`** 写回 **`article.yaml`**（`publish.py` 不改此键） |\n\nFile v1.0.22:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-publish\",\n  \"version\": \"1.0.22\",\n  \"publishedAt\": 1776900263931\n}\n\nFile v1.0.22:references/api-reference.md\n\n# 微信公众号 API 参考\n\n## 接口一览\n\n| 接口 | 方法 | 路径 | 用途 |\n|------|------|------|------|\n| 获取 token | GET | `/token` | 获取 access_token |\n| 上传永久素材 | POST | `/material/add_material` | 上传封面图，返回 media_id |\n| 上传正文图片 | POST | `/media/uploadimg` | 上传正文内图片，返回 URL |\n| 新增草稿 | POST | `/draft/add` | 创建图文草稿 |\n| 发布草稿 | POST | `/freepublish/submit` | 发布草稿（异步） |\n| 查询发布状态 | POST | `/freepublish/get` | 查询发布结果 |\n\n所有接口基础 URL：`https://api.weixin.qq.com/cgi-bin`\n\n## 获取 access_token\n\n```\nGET /token?grant_type=client_credential&appid={APPID}&secret={APPSECRET}\n```\n\n返回：\n```json\n{\"access_token\": \"...\", \"expires_in\": 7200}\n```\n\n有效期 2 小时，需缓存复用，避免频繁请求。\n\n## 上传封面图（永久素材）\n\n```\nPOST /material/add_material?access_token={TOKEN}&type=image\nContent-Type: multipart/form-data\n```\n\n- 字段名：`media`\n- 限制：10MB，支持 bmp/png/jpeg/jpg/gif\n- 永久素材上限：100,000 张\n\n返回：\n```json\n{\"media_id\": \"...\", \"url\": \"...\"}\n```\n\n`media_id` 用于 `draft/add` 的 `thumb_media_id` 字段。\n\n## 上传正文图片\n\n```\nPOST /media/uploadimg?access_token={TOKEN}\nContent-Type: multipart/form-data\n```\n\n- 字段名：`media`\n- 限制：1MB，支持 jpg/png\n- 不占用素材库配额\n- 返回的 URL 可直接在正文 HTML 中使用\n\n返回：\n```json\n{\"url\": \"https://mmbiz.qpic.cn/...\"}\n```\n\n## 新增草稿\n\n```\nPOST /draft/add?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\n  \"articles\": [{\n    \"title\": \"标题（≤32字）\",\n    \"author\": \"作者（≤16字）\",\n    \"digest\": \"摘要（≤128字，仅单图文）\",\n    \"content\": \"HTML 正文（≤2万字符，图片 URL 必须来自 uploadimg）\",\n    \"thumb_media_id\": \"封面图 media_id\",\n    \"content_source_url\": \"原文链接\",\n    \"need_open_comment\": 1,\n    \"only_fans_can_comment\": 0\n  }]\n}\n```\n\n返回：\n```json\n{\"media_id\": \"...\"}\n```\n\n## 发布草稿\n\n```\nPOST /freepublish/submit?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\"media_id\": \"草稿的 media_id\"}\n```\n\n返回：\n```json\n{\"publish_id\": \"...\", \"msg_data_id\": \"...\"}\n```\n\n**注意**：发布为异步操作，返回成功仅表示任务提交成功。\n\n## 查询发布状态\n\n```\nPOST /freepublish/get?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\"publish_id\": \"...\"}\n```\n\n返回 `publish_status`：\n\n| 值 | 含义 |\n|----|------|\n| 0 | 发布成功 |\n| 1 | 发布中 |\n| 2 | 原创失败 |\n| 3 | 常规失败 |\n| 4 | 平台审核不通过 |\n| 5 | 已删除 |\n| 6 | 已封禁 |\n\n## 常见错误码\n\n| 错误码 | 含义 | 处理 |\n|--------|------|------|\n| 40001 | access_token 无效 | 重新获取 token |\n| 40004 | 不合法的媒体文件类型 | 检查图片格式 |\n| 40009 | 图片大小超限 | 封面 ≤10MB，正文图 ≤1MB |\n| 45009 | API 调用超限 | 等待后重试 |\n| 45028 | 接口无权限 | 检查公众号类型和权限 |\n| 48001 | API 未授权 | 检查公众号开发者设置 |\n\n## 凭证配置\n\n在仓库根 **`aws.env`** 中配置微信槽位（勿提交含真密钥的文件）：\n\n```env\nNUMBER_ACCOUNTS=1\nWECHAT_1_NAME=主号\nWECHAT_1_APPID=你的AppID\nWECHAT_1_APPSECRET=你的AppSecret\nWECHAT_1_API_BASE=\n```\n\n键名与 `skills/aws-wechat-article-main/references/env.example.yaml` 一致。多账号递增 `WECHAT_2_*` 等。\n\n## 权限要求\n\n- 需要已认证的服务号或订阅号\n- AppID 和 AppSecret 在「开发 → 基本配置」获取\n- 调用服务器 IP 需加入白名单\n\n## 官方文档\n\n- [新增草稿](https://developers.weixin.qq.com/doc/subscription/api/draftbox/draftmanage/api_draft_add)\n- [发布草稿](https://developers.weixin.qq.com/doc/subscription/api/public/api_freepublish_submit.html)\n- [上传永久素材](https://developers.weixin.qq.com/doc/subscription/api/material/permanent/api_addmaterial.html)\n- [上传正文图片](https://developers.weixin.qq.com/doc/subscription/en/api/material/permanent/api_uploadimage)\n\nFile v1.0.22:references/pre-publish-checklist.md\n\n# 发布前检查清单\n\n在审稿通过后、实际提交前执行，确保可安全发布。\n\n## 检查项\n\n- [ ] 标题、摘要、作者已最终确认\n- [ ] 正文无未替换的占位符或草稿标记\n- [ ] 敏感词与错别字已在审稿中修正\n- [ ] 封面图已就绪（已上传或路径有效）\n- [ ] 正文内图片齐全，图注格式正确\n- [ ] 原创/转载标注已按配置处理\n- [ ] 文末引导区块已就位\n- [ ] 如需开启评论/仅粉丝可评，已确认设置\n\n全部勾选后执行提交步骤。\n\nFile v1.0.22:references/submit-guide.md\n\n# 提交到公众号后台\n\n## 方式一：API 提交（推荐）\n\n使用 `skills/aws-wechat-article-publish/scripts/publish.py`，通过微信公众号 API 完成发布。\n\n### 前置准备\n\n1. 在仓库根 **`aws.env`** 中填写微信槽位（与 `skills/aws-wechat-article-main/references/env.example.yaml` 键名一致），例如单账号：\n   ```env\n   NUMBER_ACCOUNTS=1\n   WECHAT_1_NAME=主号\n   WECHAT_1_APPID=你的AppID\n   WECHAT_1_APPSECRET=你的AppSecret\n   WECHAT_1_API_BASE=\n   ```\n   多账号递增 `WECHAT_2_*` 等；发布前可运行 `python skills/aws-wechat-article-publish/scripts/publish.py check-wechat-env` 检查缺项。\n\n2. 在公众平台「开发 → 基本配置」中将服务器 IP 加入白名单\n\n3. 准备文章目录：\n   ```\n   article/\n   ├── article.yaml    # 标题、作者、摘要等元信息\n   ├── article.html    # 排版后的正文 HTML\n   ├── cover.jpg       # 封面图\n   └── imgs/           # 正文内图片\n   ```\n\n### 一键发布\n\n```bash\n# 创建草稿（不发布，可在后台预览）\npython skills/aws-wechat-article-publish/scripts/publish.py full article/\n\n# 创建草稿并立即发布\npython skills/aws-wechat-article-publish/scripts/publish.py full article/ --publish\n```\n\n### 分步操作\n\n```bash\n# 获取 token\npython skills/aws-wechat-article-publish/scripts/publish.py token\n\n# 上传封面图\npython skills/aws-wechat-article-publish/scripts/publish.py upload-thumb cover.jpg\n\n# 上传正文图片\npython skills/aws-wechat-article-publish/scripts/publish.py upload-content-image imgs/img1.png\n\n# 创建草稿（需要先准备好 article.yaml）\npython skills/aws-wechat-article-publish/scripts/publish.py create-draft article.yaml\n\n# 发布\npython skills/aws-wechat-article-publish/scripts/publish.py publish <media_id>\n\n# 查询状态\npython skills/aws-wechat-article-publish/scripts/publish.py status <publish_id>\n```\n\n接口详情与错误码：[api-reference.md](api-reference.md)\n\n## 方式二：手动提交\n\n1. 登录微信公众平台（mp.weixin.qq.com）\n2. 进入「素材管理」或「草稿箱」→ 新建图文消息\n3. 填写标题、作者、摘要\n4. 将排版后的正文粘贴到正文编辑区\n5. 上传封面图，设置封面\n6. 逐一上传正文内图片并插入对应位置\n7. 设置评论权限（开启/仅粉丝可评）\n8. 保存为草稿或直接群发\n\nFile v1.0.22:references/usage.md\n\n# 发布脚本用法\n\n脚本路径：**`skills/aws-wechat-article-publish/scripts/publish.py`**（在**仓库根**执行）。\n\n- **微信凭证**来自仓库根 **`aws.env`**：`NUMBER_ACCOUNTS`、`WECHAT_1_NAME`、`WECHAT_1_APPID`、`WECHAT_1_APPSECRET`、`WECHAT_1_API_BASE`（1..N 槽位）。`WECHAT_N_API_BASE` 可空（空则官方 `https://api.weixin.qq.com`）。\n- **`publish_method`** 在 **`config.yaml`**：**`draft`**（默认）= **`full`** 只进**草稿箱**；**`published`** = 再**提交发布**；**`none`** = **`full`** **不调接口**（用户不填微信）。**`full --publish`** 可在 **`draft`** 下单次强制发布（**`none`** 下仍跳过）。\n\n## `publish_method` 检查\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py check-screening\npython skills/aws-wechat-article-publish/scripts/publish.py check-screening --config .aws-article/config.yaml\n```\n\n## 微信槽位检查\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py check-wechat-env\npython skills/aws-wechat-article-publish/scripts/publish.py accounts\n```\n\n## 一键全流程\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py full path/to/article-dir/\n\npython skills/aws-wechat-article-publish/scripts/publish.py full path/to/article-dir/ --publish\n\npython skills/aws-wechat-article-publish/scripts/publish.py --account 2 full path/to/article-dir/\n```\n\n## 正式文章读取（`getdraft.py`）\n\n与 **`publish.py` 独立**，用于 **`freepublish/batchget`** / **`freepublish/get`** / **`freepublish/getarticle`**（仓库根执行）：\n\n```bash\npython skills/aws-wechat-article-publish/scripts/getdraft.py published-fields\npython skills/aws-wechat-article-publish/scripts/getdraft.py publish-get <publish_id>\npython skills/aws-wechat-article-publish/scripts/getdraft.py article-get <article_id>\n```\n\n## 分步操作\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py token\npython skills/aws-wechat-article-publish/scripts/publish.py upload-thumb cover.jpg\npython skills/aws-wechat-article-publish/scripts/publish.py upload-content-image img.png\npython skills/aws-wechat-article-publish/scripts/publish.py create-draft path/to/article.yaml\npython skills/aws-wechat-article-publish/scripts/publish.py publish <media_id>\n```\n\nFile v1.0.22:skill-card.md\n\n## Description: <br>\nPublishes prepared WeChat Official Account articles to drafts or submits them for release through the WeChat API, with credential checks, cover and image uploads, and pre-publish review steps. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[aiworkskills](https://clawhub.ai/user/aiworkskills) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nContent operations teams, developers, and agents use this skill to move a prepared article directory into a WeChat Official Account draft or publishing workflow. It is intended for controlled release workflows where credentials, article assets, and publication mode are checked before the API call. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill handles live WeChat credentials and sends article files to an API endpoint. <br>\nMitigation: Use a dedicated WeChat account, keep aws.env out of version control, and confirm the destination API base before running publishing commands. <br>\nRisk: A configurable API base or proxy could route credentials and content to an untrusted endpoint. <br>\nMitigation: Allow only the official WeChat API endpoint or a trusted approved proxy, and review any configured API base before execution. <br>\nRisk: Publishing commands can create drafts or submit live content. <br>\nMitigation: Run draft mode or an explicit dry run first, require confirmation before live publishing, and review the pre-publish checklist before marking the article complete. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/aiworkskills/aws-wechat-article-publish) <br>\n- [Usage guide](references/usage.md) <br>\n- [Submit guide](references/submit-guide.md) <br>\n- [WeChat API reference](references/api-reference.md) <br>\n- [Pre-publish checklist](references/pre-publish-checklist.md) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown guidance with shell commands, configuration checks, and status updates] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May create WeChat drafts or submit live publishing requests when credentials, article assets, and publish mode are confirmed.] <br>\n\n## Skill Version(s): <br>\n1.0.22 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v1.0.22:skill.json\n\n{\n  \"name\": \"aws-wechat-article-publish\",\n  \"version\": \"0.4.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"将文章发布到微信公众号，支持 API 发布和手动提交，含发布前检查。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"publish\", \"api\"],\n  \"permissions\": [\"filesystem\", \"network\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}\n\nArchive v1.0.20: 10 files, 31037 bytes\n\nFiles: references/api-reference.md (4153b), references/pre-publish-checklist.md (536b), references/submit-guide.md (2390b), references/usage.md (2293b), scripts/article_init.py (8283b), scripts/getdraft.py (16742b), scripts/publish.py (42311b), skill.json (494b), SKILL.md (11930b), _meta.json (146b)\n\nFile v1.0.20:SKILL.md\n\n---\nname: aws-wechat-article-publish\ndescription: 公众号发布｜公众号草稿箱｜公众号群发｜图文推送｜微信 API｜wechat automation｜WeChat API automation｜auto publish｜scheduled publish — 公众号 API 发布工具，图文入草稿箱或直接群发，支持封面素材上传、发布前检查与 draft/published 模式切换。面向公众号运营、自动化内容团队、开发者。触发词：「发布」「提交」「群发」「推送」「发出去」「上传到公众号」「发到公众号」「可以发了吗」「发布前检查」。需要多环节串联（写+审+排+配图+发）请走 aws-wechat-article-main。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env:\n        - WECHAT_1_APPID\n        - WECHAT_1_APPSECRET\n      bins:\n        - python3\n    primaryEnv: aws.env\n---\n\n# 发布\n\n**公众号 API 直连发布** —— 图文入草稿箱或直接群发，素材上传、发布前检查一站式完成。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 调 `publish.py` **直连微信公众号官方 API** 发布图文。**会把本篇 `article.html` 与 `imgs/*` 文件作为 POST body 上传到微信服务器。** 具体行为：\n\n- **凭证读取**：`aws.env` 的 `WECHAT_{N}_APPID` / `WECHAT_{N}_APPSECRET`（多槽位支持 N≥1）\n- **凭证外发**：`APPID` / `APPSECRET` 以 query string 形式发给 `api.weixin.qq.com/cgi-bin/token` 换 `access_token`；后续请求带 `access_token` query string。微信返回的 `access_token` 在进程内存短期缓存，**不落盘**\n- **内容外发**：本篇封面、正文插图以 multipart upload 发给 `material/add_material`；`article.html` 正文与标题/摘要以 JSON POST 发给 `draft/add`、`freepublish/submit`\n- **网络目标**：默认 `api.weixin.qq.com`；用户可在 `WECHAT_{N}_API_BASE` / `config.yaml.wechat_api_base` 自配反代\n- **文件读**：仓库内 `.aws-article/config.yaml`、`aws.env`、本篇 `article.yaml`、`article.html`、`imgs/*`\n- **文件写**：仅本篇 `article.yaml` 的状态字段（`media_id`、`publish_id`、`publish_completed`）\n- **shell**：仅 `python3 {baseDir}/scripts/publish.py`、`getdraft.py`、`article_init.py`\n\n**建议**：首次运行用 `publish_method: draft` 只入草稿箱确认效果，再切 `published` 真正群发。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的发布环节（入口 `aws-wechat-article-main`）。完整说明见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n通过微信公众号 API 将排版稿写入**草稿箱**或再**提交发布**（由 **`config.yaml`** 的 **`publish_method`** 与命令行 **`--publish`** 控制）。\n\n## 配置检查 ⛔\n\n任何操作执行前，**必须**按 **[首次引导](../aws-wechat-article-main/references/first-time-setup.md)** 执行其中的 **「检测顺序」**。检测通过后才能进行以下操作（或用户明确书面确认「本次不检查」）：\n\n## 脚本目录\n\n**Agent 执行**：确定本 SKILL.md 所在目录为 `{baseDir}`。发布子命令在 **`{baseDir}/scripts/publish.py`**（项目根执行）。\n\n| 脚本 / 子命令 | 用途 |\n|--------|------|\n| **`article_init.py`** | 初始化或更新本篇 **`article.yaml`**（及可选 **`closing.md`**）。用于总览 **本篇准备**（建目录后）或 **发布前** 补全元数据。仓库根执行：`python {baseDir}/scripts/article_init.py <文章目录> [--title … --author … --digest …]` |\n| **`getdraft.py`** | 独立于 `publish.py`：用于正式文章查询（`published-list` / `published-fields` / `publish-get` / `article-get`，对应 `freepublish/*`），可用于 `embeds.related_articles.manual` 为空时自动补全推荐链接。注意：`freepublish/*` 需要公众号具备对应接口权限。仓库根：`python {baseDir}/scripts/getdraft.py published-fields` |\n| `check-screening` | 校验 **`config.yaml`** 的 **`publish_method`**（**`draft`** / **`published`** / **`none`**） |\n| `check-wechat-env` | 按 **`config.yaml` 槽位**检查 `aws.env` 的 `WECHAT_N_APPID` / `WECHAT_N_APPSECRET` 是否已填（**调用 `publish.py` 前建议跑**） |\n| `check` | 环境检查：`aws.env`、各槽位、依赖、可选探测 token |\n| `accounts` | 列出 **`config.yaml`** 中各微信槽位名称，并标记 `aws.env` 凭证缺项 |\n| `full` / `token` / … | 调微信 API（需 **`aws.env`** 微信凭证） |\n\n## 凭证与 `publish_method` ⛔\n\n### `publish_method`（以仓库 **`config.yaml`** 为准）\n\n| 值 | 含义 | 行为 |\n|----|------|------|\n| **`draft`**（默认） | 只进公众号**草稿箱** | **`full`** 创建草稿后**不**调用 freepublish 提交发布。 |\n| **`published`** | 草稿 + **提交发布** | **`full`** 创建草稿后继续提交发布（异步）。**`full --publish`** 可**单次强制**带发布，即使当前为 **`draft`**。 |\n| **`none`** | 用户明确不填微信 | **`full`** **立即退出**，不调任何微信接口（**`--publish`** 也会被忽略）。其它子命令（`token` 等）仍要凭证。 |\n\n### 多账号时如何选槽位\n\n1. 运行 **`python {baseDir}/scripts/publish.py accounts`**，从 **`config.yaml` 的 `wechat_accounts` + `wechat_N_name`** 向用户展示列表（例如：`您有2个账号：1.\"xiaoming\"，2.\"xiaoz\"`）必须询问用户选择哪个账号发布到草稿箱，然后根据用户选择发布到指定的账号。\n2. 在 **`config.yaml`** 写 **`wechat_publish_slot: <整数>`**，**或**命令行 **`--account <序号或名称>`**（**CLI 优先**，见 [articlescreening-schema.md](../aws-wechat-article-main/references/articlescreening-schema.md)）。\n\n### 全局环境\n\n在仓库根具备 **`aws.env`**（微信密钥）与 **`config.yaml`**（微信槽位数量与名称）。写作/生图见 **`validate_env.py`**（微信未齐仍可先做内容）。**`publish_method: none`** 时 **`full`** 会跳过；**`draft`/`published`** 发布前建议 **`check-wechat-env`**。API 端点优先取 **`WECHAT_N_API_BASE`**，若槽位未配则回退 **`config.yaml.wechat_api_base`**（两者都空时使用官方）。\n\n### 作者名回退\n\n`full` / `create-draft` 若 **`article.yaml` 无 author**，回退 **`config.yaml`** 的 **`default_author`**。\n\n### `publish_completed`（本篇是否已发布完成）\n\n- 字段在**本篇** **`article.yaml`**。**`publish.py` 不读、不改**；由智能体维护。\n- **`false`**：发布流程未闭环。\n- **`true`**：已视为发布完成（草稿已确认 / 或 **`published`** 流程成功且运营确认）。\n\n**本篇发布真正结束后**：将 **`publish_completed: true`** 写回 **`article.yaml`**。\n\n**写回 `true` 的前置门禁（缺啥补啥）**：\n\n1. `article.html` 存在；\n2. 文章目录存在封面图 `cover.(png/jpg/jpeg/webp)`；\n3. `article.md` 与 `article.html` 中均不含 `placeholder`；\n4. 发布命令成功并拿到回执（`media_id` 或 `publish_id`）。\n\n任一不满足：只可标记为“已提交草稿，未闭环”，**不得**写回 `publish_completed: true`。\n\n## 用户仅说「发布」且未明确路径时 ⛔\n\n在用户**未给出** `drafts/…` 路径、仅说「发布文章」「帮我发一下」等时：\n\n1. **确定本篇目录**：列出仓库下 **`drafts/`** 中子目录；若**多篇**，请用户**指定一篇**或选「最新修改」的一篇再读该目录 **`article.yaml`**。**勿**在未确认目录时假定路径。\n2. 读取该目录 **`article.yaml`** 中的 **`publish_completed`**（YAML 布尔：`true` / `false`；**缺省按 `false` 处理**）。\n\n| `publish_completed` | 智能体对用户说明（可略作口语化，勿改含义） |\n|---------------------|---------------------------------------------|\n| **`true`** | 告知：**项目里本篇文档已按记录成功发布**；问：**您是否需要编写新文章？** 若需要 → 转交 [main](../aws-wechat-article-main/SKILL.md) / [writing](../aws-wechat-article-writing/SKILL.md) 从本篇准备或选题起走。 |\n| **`false`** 或缺省 | 读取 **`article.yaml`** 的 **`title`**（若无则用目录名简述），说明：**《{title}》尚未执行完成（发布流程未闭环）**；问：**是否需要继续并完成发布？** 或 **编写新文章？** 若继续本篇 → 再核对 **`config.yaml`** 的 **`publish_method`**、**`check-screening`**、**`check-wechat-env`** 等。 |\n\n## 工作流\n\n```\n发布进度：\n- [ ] 前置：配置检查（见本节「配置检查」）⛔\n- [ ] 第0步：若用户未给路径 → 选本篇目录 → 读 publish_completed → 按上表分流（true/false）\n- [ ] 第1步：读 **`config.yaml`** → **`draft` / `published`**（及是否 **`full --publish`**）\n- [ ] 第2步：读取 **`config.yaml`** 的 `wechat_accounts` + `wechat_N_name` 向用户展示账号列表并询问目标槽位；随后跑 **`check-wechat-env`** 校验 `aws.env` 凭证 → **`wechat_publish_slot` 或 `--account`**\n- [ ] 第3步：发布前检查（checklist + **`check-screening`** + **`check`**）\n- [ ] 第4步：准备文章目录\n- [ ] 第5步：**`full`**（仅草稿或含发布，视上步）\n- [ ] 第6步：确认结果与用户说明\n- [ ] 第7步：成功后写回 **`article.yaml`** 的 **`publish_completed: true`**；按需归档\n```\n\n## 交互顺序（最小提问）\n\n0) **未给路径时**：先按上文 **「用户仅说发布」** 处理 **`publish_completed`**；用户选 **继续本篇** 后再做下列步骤。  \n1) **先看 `config.yaml` 的 `publish_method`**：**`draft`** = 默认只进草稿箱；**`published`** 或 **`full --publish`** = 再提交发布。  \n2) **多槽位**：展示账号列表（来源：`config.yaml` 的 `wechat_accounts` + `wechat_N_name`），**必须请用户选槽位** → **`wechat_publish_slot`** 或 **`--account`**。  \n3) 缺微信字段：运行 **`check-wechat-env`**，补全 **`aws.env`** 后再发。  \n4) **发布失败**（由脚本 stderr / 微信 errcode 判断）：  \n   - **网络类**（超时、连接失败、5xx）：脚本已对单次请求 **自动重试 1 次**；仍失败 → 告知「网络不可用，请稍后重试或检查代理」。  \n   - **凭证/配置类**（如 token 失败带 errcode、缺字段）→ 提示 **第几槽位**、检查 **APPID/SECRET、IP 白名单**，用户改正后再执行 **`full`** / **`publish`**。\n5) **中间产物缺失**（封面缺失 / 存在 `placeholder`）：先补产物再发；若用户坚持先发草稿，必须明确告知“正文配图未完成”，且保持 `publish_completed: false`。\n\n## 命令示例（仓库根）\n\n```bash\npython {baseDir}/scripts/publish.py check-screening\npython {baseDir}/scripts/publish.py check-wechat-env\npython {baseDir}/scripts/publish.py accounts\npython {baseDir}/scripts/publish.py check\npython {baseDir}/scripts/publish.py --account 1 full drafts/YYYYMMDD-标题slug/\npython {baseDir}/scripts/getdraft.py published-fields\n```\n\n详见 [references/usage.md](references/usage.md)、[references/submit-guide.md](references/submit-guide.md)、[references/api-reference.md](references/api-reference.md)。\n\n## 过程文件\n\n| 读取 | 产出 |\n|------|------|\n| `article.html`、`imgs/`、**`article.yaml`**（含 **`publish_completed`** 等）、**`.aws-article/config.yaml`**、**`aws.env`**（微信槽位） | 发布到公众号草稿或提交发布；**成功后**由智能体将 **`publish_completed: true`** 写回 **`article.yaml`**（`publish.py` 不改此键） |\n\nFile v1.0.20:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-publish\",\n  \"version\": \"1.0.20\",\n  \"publishedAt\": 1776897355000\n}\n\nFile v1.0.20:references/api-reference.md\n\n# 微信公众号 API 参考\n\n## 接口一览\n\n| 接口 | 方法 | 路径 | 用途 |\n|------|------|------|------|\n| 获取 token | GET | `/token` | 获取 access_token |\n| 上传永久素材 | POST | `/material/add_material` | 上传封面图，返回 media_id |\n| 上传正文图片 | POST | `/media/uploadimg` | 上传正文内图片，返回 URL |\n| 新增草稿 | POST | `/draft/add` | 创建图文草稿 |\n| 发布草稿 | POST | `/freepublish/submit` | 发布草稿（异步） |\n| 查询发布状态 | POST | `/freepublish/get` | 查询发布结果 |\n\n所有接口基础 URL：`https://api.weixin.qq.com/cgi-bin`\n\n## 获取 access_token\n\n```\nGET /token?grant_type=client_credential&appid={APPID}&secret={APPSECRET}\n```\n\n返回：\n```json\n{\"access_token\": \"...\", \"expires_in\": 7200}\n```\n\n有效期 2 小时，需缓存复用，避免频繁请求。\n\n## 上传封面图（永久素材）\n\n```\nPOST /material/add_material?access_token={TOKEN}&type=image\nContent-Type: multipart/form-data\n```\n\n- 字段名：`media`\n- 限制：10MB，支持 bmp/png/jpeg/jpg/gif\n- 永久素材上限：100,000 张\n\n返回：\n```json\n{\"media_id\": \"...\", \"url\": \"...\"}\n```\n\n`media_id` 用于 `draft/add` 的 `thumb_media_id` 字段。\n\n## 上传正文图片\n\n```\nPOST /media/uploadimg?access_token={TOKEN}\nContent-Type: multipart/form-data\n```\n\n- 字段名：`media`\n- 限制：1MB，支持 jpg/png\n- 不占用素材库配额\n- 返回的 URL 可直接在正文 HTML 中使用\n\n返回：\n```json\n{\"url\": \"https://mmbiz.qpic.cn/...\"}\n```\n\n## 新增草稿\n\n```\nPOST /draft/add?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\n  \"articles\": [{\n    \"title\": \"标题（≤32字）\",\n    \"author\": \"作者（≤16字）\",\n    \"digest\": \"摘要（≤128字，仅单图文）\",\n    \"content\": \"HTML 正文（≤2万字符，图片 URL 必须来自 uploadimg）\",\n    \"thumb_media_id\": \"封面图 media_id\",\n    \"content_source_url\": \"原文链接\",\n    \"need_open_comment\": 1,\n    \"only_fans_can_comment\": 0\n  }]\n}\n```\n\n返回：\n```json\n{\"media_id\": \"...\"}\n```\n\n## 发布草稿\n\n```\nPOST /freepublish/submit?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\"media_id\": \"草稿的 media_id\"}\n```\n\n返回：\n```json\n{\"publish_id\": \"...\", \"msg_data_id\": \"...\"}\n```\n\n**注意**：发布为异步操作，返回成功仅表示任务提交成功。\n\n## 查询发布状态\n\n```\nPOST /freepublish/get?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\"publish_id\": \"...\"}\n```\n\n返回 `publish_status`：\n\n| 值 | 含义 |\n|----|------|\n| 0 | 发布成功 |\n| 1 | 发布中 |\n| 2 | 原创失败 |\n| 3 | 常规失败 |\n| 4 | 平台审核不通过 |\n| 5 | 已删除 |\n| 6 | 已封禁 |\n\n## 常见错误码\n\n| 错误码 | 含义 | 处理 |\n|--------|------|------|\n| 40001 | access_token 无效 | 重新获取 token |\n| 40004 | 不合法的媒体文件类型 | 检查图片格式 |\n| 40009 | 图片大小超限 | 封面 ≤10MB，正文图 ≤1MB |\n| 45009 | API 调用超限 | 等待后重试 |\n| 45028 | 接口无权限 | 检查公众号类型和权限 |\n| 48001 | API 未授权 | 检查公众号开发者设置 |\n\n## 凭证配置\n\n在仓库根 **`aws.env`** 中配置微信槽位（勿提交含真密钥的文件）：\n\n```env\nNUMBER_ACCOUNTS=1\nWECHAT_1_NAME=主号\nWECHAT_1_APPID=你的AppID\nWECHAT_1_APPSECRET=你的AppSecret\nWECHAT_1_API_BASE=\n```\n\n键名与 `skills/aws-wechat-article-main/references/env.example.yaml` 一致。多账号递增 `WECHAT_2_*` 等。\n\n## 权限要求\n\n- 需要已认证的服务号或订阅号\n- AppID 和 AppSecret 在「开发 → 基本配置」获取\n- 调用服务器 IP 需加入白名单\n\n## 官方文档\n\n- [新增草稿](https://developers.weixin.qq.com/doc/subscription/api/draftbox/draftmanage/api_draft_add)\n- [发布草稿](https://developers.weixin.qq.com/doc/subscription/api/public/api_freepublish_submit.html)\n- [上传永久素材](https://developers.weixin.qq.com/doc/subscription/api/material/permanent/api_addmaterial.html)\n- [上传正文图片](https://developers.weixin.qq.com/doc/subscription/en/api/material/permanent/api_uploadimage)\n\nFile v1.0.20:references/pre-publish-checklist.md\n\n# 发布前检查清单\n\n在审稿通过后、实际提交前执行，确保可安全发布。\n\n## 检查项\n\n- [ ] 标题、摘要、作者已最终确认\n- [ ] 正文无未替换的占位符或草稿标记\n- [ ] 敏感词与错别字已在审稿中修正\n- [ ] 封面图已就绪（已上传或路径有效）\n- [ ] 正文内图片齐全，图注格式正确\n- [ ] 原创/转载标注已按配置处理\n- [ ] 文末引导区块已就位\n- [ ] 如需开启评论/仅粉丝可评，已确认设置\n\n全部勾选后执行提交步骤。\n\nFile v1.0.20:references/submit-guide.md\n\n# 提交到公众号后台\n\n## 方式一：API 提交（推荐）\n\n使用 `skills/aws-wechat-article-publish/scripts/publish.py`，通过微信公众号 API 完成发布。\n\n### 前置准备\n\n1. 在仓库根 **`aws.env`** 中填写微信槽位（与 `skills/aws-wechat-article-main/references/env.example.yaml` 键名一致），例如单账号：\n   ```env\n   NUMBER_ACCOUNTS=1\n   WECHAT_1_NAME=主号\n   WECHAT_1_APPID=你的AppID\n   WECHAT_1_APPSECRET=你的AppSecret\n   WECHAT_1_API_BASE=\n   ```\n   多账号递增 `WECHAT_2_*` 等；发布前可运行 `python skills/aws-wechat-article-publish/scripts/publish.py check-wechat-env` 检查缺项。\n\n2. 在公众平台「开发 → 基本配置」中将服务器 IP 加入白名单\n\n3. 准备文章目录：\n   ```\n   article/\n   ├── article.yaml    # 标题、作者、摘要等元信息\n   ├── article.html    # 排版后的正文 HTML\n   ├── cover.jpg       # 封面图\n   └── imgs/           # 正文内图片\n   ```\n\n### 一键发布\n\n```bash\n# 创建草稿（不发布，可在后台预览）\npython skills/aws-wechat-article-publish/scripts/publish.py full article/\n\n# 创建草稿并立即发布\npython skills/aws-wechat-article-publish/scripts/publish.py full article/ --publish\n```\n\n### 分步操作\n\n```bash\n# 获取 token\npython skills/aws-wechat-article-publish/scripts/publish.py token\n\n# 上传封面图\npython skills/aws-wechat-article-publish/scripts/publish.py upload-thumb cover.jpg\n\n# 上传正文图片\npython skills/aws-wechat-article-publish/scripts/publish.py upload-content-image imgs/img1.png\n\n# 创建草稿（需要先准备好 article.yaml）\npython skills/aws-wechat-article-publish/scripts/publish.py create-draft article.yaml\n\n# 发布\npython skills/aws-wechat-article-publish/scripts/publish.py publish <media_id>\n\n# 查询状态\npython skills/aws-wechat-article-publish/scripts/publish.py status <publish_id>\n```\n\n接口详情与错误码：[api-reference.md](api-reference.md)\n\n## 方式二：手动提交\n\n1. 登录微信公众平台（mp.weixin.qq.com）\n2. 进入「素材管理」或「草稿箱」→ 新建图文消息\n3. 填写标题、作者、摘要\n4. 将排版后的正文粘贴到正文编辑区\n5. 上传封面图，设置封面\n6. 逐一上传正文内图片并插入对应位置\n7. 设置评论权限（开启/仅粉丝可评）\n8. 保存为草稿或直接群发\n\nFile v1.0.20:references/usage.md\n\n# 发布脚本用法\n\n脚本路径：**`skills/aws-wechat-article-publish/scripts/publish.py`**（在**仓库根**执行）。\n\n- **微信凭证**来自仓库根 **`aws.env`**：`NUMBER_ACCOUNTS`、`WECHAT_1_NAME`、`WECHAT_1_APPID`、`WECHAT_1_APPSECRET`、`WECHAT_1_API_BASE`（1..N 槽位）。`WECHAT_N_API_BASE` 可空（空则官方 `https://api.weixin.qq.com`）。\n- **`publish_method`** 在 **`config.yaml`**：**`draft`**（默认）= **`full`** 只进**草稿箱**；**`published`** = 再**提交发布**；**`none`** = **`full`** **不调接口**（用户不填微信）。**`full --publish`** 可在 **`draft`** 下单次强制发布（**`none`** 下仍跳过）。\n\n## `publish_method` 检查\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py check-screening\npython skills/aws-wechat-article-publish/scripts/publish.py check-screening --config .aws-article/config.yaml\n```\n\n## 微信槽位检查\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py check-wechat-env\npython skills/aws-wechat-article-publish/scripts/publish.py accounts\n```\n\n## 一键全流程\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py full path/to/article-dir/\n\npython skills/aws-wechat-article-publish/scripts/publish.py full path/to/article-dir/ --publish\n\npython skills/aws-wechat-article-publish/scripts/publish.py --account 2 full path/to/article-dir/\n```\n\n## 正式文章读取（`getdraft.py`）\n\n与 **`publish.py` 独立**，用于 **`freepublish/batchget`** / **`freepublish/get`** / **`freepublish/getarticle`**（仓库根执行）：\n\n```bash\npython skills/aws-wechat-article-publish/scripts/getdraft.py published-fields\npython skills/aws-wechat-article-publish/scripts/getdraft.py publish-get <publish_id>\npython skills/aws-wechat-article-publish/scripts/getdraft.py article-get <article_id>\n```\n\n## 分步操作\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py token\npython skills/aws-wechat-article-publish/scripts/publish.py upload-thumb cover.jpg\npython skills/aws-wechat-article-publish/scripts/publish.py upload-content-image img.png\npython skills/aws-wechat-article-publish/scripts/publish.py create-draft path/to/article.yaml\npython skills/aws-wechat-article-publish/scripts/publish.py publish <media_id>\n```\n\nFile v1.0.20:skill.json\n\n{\n  \"name\": \"aws-wechat-article-publish\",\n  \"version\": \"0.4.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"将文章发布到微信公众号，支持 API 发布和手动提交，含发布前检查。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"publish\", \"api\"],\n  \"permissions\": [\"filesystem\", \"network\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}\n\nArchive v1.0.19: 10 files, 30749 bytes\n\nFiles: references/api-reference.md (4153b), references/pre-publish-checklist.md (536b), references/submit-guide.md (2390b), references/usage.md (2293b), scripts/article_init.py (8283b), scripts/getdraft.py (16559b), scripts/publish.py (42311b), skill.json (494b), SKILL.md (11543b), _meta.json (146b)\n\nFile v1.0.19:SKILL.md\n\n---\nname: aws-wechat-article-publish\ndescription: 公众号发布｜公众号草稿箱｜公众号群发｜图文推送｜微信 API｜wechat automation｜WeChat API automation｜auto publish｜scheduled publish — 公众号 API 发布工具，图文入草稿箱或直接群发，支持封面素材上传、发布前检查与 draft/published 模式切换。面向公众号运营、自动化内容团队、开发者。触发词：「发布」「提交」「群发」「推送」「发出去」「上传到公众号」「发到公众号」「可以发了吗」「发布前检查」。需要多环节串联（写+审+排+配图+发）请走 aws-wechat-article-main。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env:\n        - WECHAT_1_APPID\n        - WECHAT_1_APPSECRET\n      bins:\n        - python3\n    primaryEnv: aws.env\n---\n\n# 发布\n\n**公众号 API 直连发布** —— 图文入草稿箱或直接群发，素材上传、发布前检查一站式完成。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 调 `publish.py` 直连微信公众号官方 API 发布图文。\n\n- **凭证**：读取仓库根 `aws.env` 的 `WECHAT_{N}_APPID` / `WECHAT_{N}_APPSECRET`（多槽位支持 N≥1）；微信返回的 `access_token` 仅在进程内存短期缓存，不落盘\n- **网络**：对 `api.weixin.qq.com`（或用户自配的 `WECHAT_{N}_API_BASE` / `config.yaml.wechat_api_base`）发请求 —— `token`、`material/add_material`、`draft/add`、`freepublish/submit`、`freepublish/batchget`\n- **文件读**：仓库内 `.aws-article/config.yaml`、`aws.env`、本篇 `article.yaml`、`article.html`、`imgs/*`（素材上传）\n- **文件写**：仅本篇 `article.yaml` 的状态字段（`media_id`、`publish_id`、`publish_completed`）\n- **shell**：仅 `python3 {baseDir}/scripts/publish.py`、`getdraft.py`、`article_init.py`\n\n凭证由用户本地保管；微信 API 响应仅写回本篇元数据，不外传。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的发布环节（入口 `aws-wechat-article-main`）。完整说明见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n通过微信公众号 API 将排版稿写入**草稿箱**或再**提交发布**（由 **`config.yaml`** 的 **`publish_method`** 与命令行 **`--publish`** 控制）。\n\n## 配置检查 ⛔\n\n任何操作执行前，**必须**按 **[首次引导](../aws-wechat-article-main/references/first-time-setup.md)** 执行其中的 **「检测顺序」**。检测通过后才能进行以下操作（或用户明确书面确认「本次不检查」）：\n\n## 脚本目录\n\n**Agent 执行**：确定本 SKILL.md 所在目录为 `{baseDir}`。发布子命令在 **`{baseDir}/scripts/publish.py`**（项目根执行）。\n\n| 脚本 / 子命令 | 用途 |\n|--------|------|\n| **`article_init.py`** | 初始化或更新本篇 **`article.yaml`**（及可选 **`closing.md`**）。用于总览 **本篇准备**（建目录后）或 **发布前** 补全元数据。仓库根执行：`python {baseDir}/scripts/article_init.py <文章目录> [--title … --author … --digest …]` |\n| **`getdraft.py`** | 独立于 `publish.py`：用于正式文章查询（`published-list` / `published-fields` / `publish-get` / `article-get`，对应 `freepublish/*`），可用于 `embeds.related_articles.manual` 为空时自动补全推荐链接。注意：`freepublish/*` 需要公众号具备对应接口权限。仓库根：`python {baseDir}/scripts/getdraft.py published-fields` |\n| `check-screening` | 校验 **`config.yaml`** 的 **`publish_method`**（**`draft`** / **`published`** / **`none`**） |\n| `check-wechat-env` | 按 **`config.yaml` 槽位**检查 `aws.env` 的 `WECHAT_N_APPID` / `WECHAT_N_APPSECRET` 是否已填（**调用 `publish.py` 前建议跑**） |\n| `check` | 环境检查：`aws.env`、各槽位、依赖、可选探测 token |\n| `accounts` | 列出 **`config.yaml`** 中各微信槽位名称，并标记 `aws.env` 凭证缺项 |\n| `full` / `token` / … | 调微信 API（需 **`aws.env`** 微信凭证） |\n\n## 凭证与 `publish_method` ⛔\n\n### `publish_method`（以仓库 **`config.yaml`** 为准）\n\n| 值 | 含义 | 行为 |\n|----|------|------|\n| **`draft`**（默认） | 只进公众号**草稿箱** | **`full`** 创建草稿后**不**调用 freepublish 提交发布。 |\n| **`published`** | 草稿 + **提交发布** | **`full`** 创建草稿后继续提交发布（异步）。**`full --publish`** 可**单次强制**带发布，即使当前为 **`draft`**。 |\n| **`none`** | 用户明确不填微信 | **`full`** **立即退出**，不调任何微信接口（**`--publish`** 也会被忽略）。其它子命令（`token` 等）仍要凭证。 |\n\n### 多账号时如何选槽位\n\n1. 运行 **`python {baseDir}/scripts/publish.py accounts`**，从 **`config.yaml` 的 `wechat_accounts` + `wechat_N_name`** 向用户展示列表（例如：`您有2个账号：1.\"xiaoming\"，2.\"xiaoz\"`）必须询问用户选择哪个账号发布到草稿箱，然后根据用户选择发布到指定的账号。\n2. 在 **`config.yaml`** 写 **`wechat_publish_slot: <整数>`**，**或**命令行 **`--account <序号或名称>`**（**CLI 优先**，见 [articlescreening-schema.md](../aws-wechat-article-main/references/articlescreening-schema.md)）。\n\n### 全局环境\n\n在仓库根具备 **`aws.env`**（微信密钥）与 **`config.yaml`**（微信槽位数量与名称）。写作/生图见 **`validate_env.py`**（微信未齐仍可先做内容）。**`publish_method: none`** 时 **`full`** 会跳过；**`draft`/`published`** 发布前建议 **`check-wechat-env`**。API 端点优先取 **`WECHAT_N_API_BASE`**，若槽位未配则回退 **`config.yaml.wechat_api_base`**（两者都空时使用官方）。\n\n### 作者名回退\n\n`full` / `create-draft` 若 **`article.yaml` 无 author**，回退 **`config.yaml`** 的 **`default_author`**。\n\n### `publish_completed`（本篇是否已发布完成）\n\n- 字段在**本篇** **`article.yaml`**。**`publish.py` 不读、不改**；由智能体维护。\n- **`false`**：发布流程未闭环。\n- **`true`**：已视为发布完成（草稿已确认 / 或 **`published`** 流程成功且运营确认）。\n\n**本篇发布真正结束后**：将 **`publish_completed: true`** 写回 **`article.yaml`**。\n\n**写回 `true` 的前置门禁（缺啥补啥）**：\n\n1. `article.html` 存在；\n2. 文章目录存在封面图 `cover.(png/jpg/jpeg/webp)`；\n3. `article.md` 与 `article.html` 中均不含 `placeholder`；\n4. 发布命令成功并拿到回执（`media_id` 或 `publish_id`）。\n\n任一不满足：只可标记为“已提交草稿，未闭环”，**不得**写回 `publish_completed: true`。\n\n## 用户仅说「发布」且未明确路径时 ⛔\n\n在用户**未给出** `drafts/…` 路径、仅说「发布文章」「帮我发一下」等时：\n\n1. **确定本篇目录**：列出仓库下 **`drafts/`** 中子目录；若**多篇**，请用户**指定一篇**或选「最新修改」的一篇再读该目录 **`article.yaml`**。**勿**在未确认目录时假定路径。\n2. 读取该目录 **`article.yaml`** 中的 **`publish_completed`**（YAML 布尔：`true` / `false`；**缺省按 `false` 处理**）。\n\n| `publish_completed` | 智能体对用户说明（可略作口语化，勿改含义） |\n|---------------------|---------------------------------------------|\n| **`true`** | 告知：**项目里本篇文档已按记录成功发布**；问：**您是否需要编写新文章？** 若需要 → 转交 [main](../aws-wechat-article-main/SKILL.md) / [writing](../aws-wechat-article-writing/SKILL.md) 从本篇准备或选题起走。 |\n| **`false`** 或缺省 | 读取 **`article.yaml`** 的 **`title`**（若无则用目录名简述），说明：**《{title}》尚未执行完成（发布流程未闭环）**；问：**是否需要继续并完成发布？** 或 **编写新文章？** 若继续本篇 → 再核对 **`config.yaml`** 的 **`publish_method`**、**`check-screening`**、**`check-wechat-env`** 等。 |\n\n## 工作流\n\n```\n发布进度：\n- [ ] 前置：配置检查（见本节「配置检查」）⛔\n- [ ] 第0步：若用户未给路径 → 选本篇目录 → 读 publish_completed → 按上表分流（true/false）\n- [ ] 第1步：读 **`config.yaml`** → **`draft` / `published`**（及是否 **`full --publish`**）\n- [ ] 第2步：读取 **`config.yaml`** 的 `wechat_accounts` + `wechat_N_name` 向用户展示账号列表并询问目标槽位；随后跑 **`check-wechat-env`** 校验 `aws.env` 凭证 → **`wechat_publish_slot` 或 `--account`**\n- [ ] 第3步：发布前检查（checklist + **`check-screening`** + **`check`**）\n- [ ] 第4步：准备文章目录\n- [ ] 第5步：**`full`**（仅草稿或含发布，视上步）\n- [ ] 第6步：确认结果与用户说明\n- [ ] 第7步：成功后写回 **`article.yaml`** 的 **`publish_completed: true`**；按需归档\n```\n\n## 交互顺序（最小提问）\n\n0) **未给路径时**：先按上文 **「用户仅说发布」** 处理 **`publish_completed`**；用户选 **继续本篇** 后再做下列步骤。  \n1) **先看 `config.yaml` 的 `publish_method`**：**`draft`** = 默认只进草稿箱；**`published`** 或 **`full --publish`** = 再提交发布。  \n2) **多槽位**：展示账号列表（来源：`config.yaml` 的 `wechat_accounts` + `wechat_N_name`），**必须请用户选槽位** → **`wechat_publish_slot`** 或 **`--account`**。  \n3) 缺微信字段：运行 **`check-wechat-env`**，补全 **`aws.env`** 后再发。  \n4) **发布失败**（由脚本 stderr / 微信 errcode 判断）：  \n   - **网络类**（超时、连接失败、5xx）：脚本已对单次请求 **自动重试 1 次**；仍失败 → 告知「网络不可用，请稍后重试或检查代理」。  \n   - **凭证/配置类**（如 token 失败带 errcode、缺字段）→ 提示 **第几槽位**、检查 **APPID/SECRET、IP 白名单**，用户改正后再执行 **`full`** / **`publish`**。\n5) **中间产物缺失**（封面缺失 / 存在 `placeholder`）：先补产物再发；若用户坚持先发草稿，必须明确告知“正文配图未完成”，且保持 `publish_completed: false`。\n\n## 命令示例（仓库根）\n\n```bash\npython {baseDir}/scripts/publish.py check-screening\npython {baseDir}/scripts/publish.py check-wechat-env\npython {baseDir}/scripts/publish.py accounts\npython {baseDir}/scripts/publish.py check\npython {baseDir}/scripts/publish.py --account 1 full drafts/YYYYMMDD-标题slug/\npython {baseDir}/scripts/getdraft.py published-fields\n```\n\n详见 [references/usage.md](references/usage.md)、[references/submit-guide.md](references/submit-guide.md)、[references/api-reference.md](references/api-reference.md)。\n\n## 过程文件\n\n| 读取 | 产出 |\n|------|------|\n| `article.html`、`imgs/`、**`article.yaml`**（含 **`publish_completed`** 等）、**`.aws-article/config.yaml`**、**`aws.env`**（微信槽位） | 发布到公众号草稿或提交发布；**成功后**由智能体将 **`publish_completed: true`** 写回 **`article.yaml`**（`publish.py` 不改此键） |\n\nFile v1.0.19:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-publish\",\n  \"version\": \"1.0.19\",\n  \"publishedAt\": 1776875792581\n}\n\nFile v1.0.19:references/api-reference.md\n\n# 微信公众号 API 参考\n\n## 接口一览\n\n| 接口 | 方法 | 路径 | 用途 |\n|------|------|------|------|\n| 获取 token | GET | `/token` | 获取 access_token |\n| 上传永久素材 | POST | `/material/add_material` | 上传封面图，返回 media_id |\n| 上传正文图片 | POST | `/media/uploadimg` | 上传正文内图片，返回 URL |\n| 新增草稿 | POST | `/draft/add` | 创建图文草稿 |\n| 发布草稿 | POST | `/freepublish/submit` | 发布草稿（异步） |\n| 查询发布状态 | POST | `/freepublish/get` | 查询发布结果 |\n\n所有接口基础 URL：`https://api.weixin.qq.com/cgi-bin`\n\n## 获取 access_token\n\n```\nGET /token?grant_type=client_credential&appid={APPID}&secret={APPSECRET}\n```\n\n返回：\n```json\n{\"access_token\": \"...\", \"expires_in\": 7200}\n```\n\n有效期 2 小时，需缓存复用，避免频繁请求。\n\n## 上传封面图（永久素材）\n\n```\nPOST /material/add_material?access_token={TOKEN}&type=image\nContent-Type: multipart/form-data\n```\n\n- 字段名：`media`\n- 限制：10MB，支持 bmp/png/jpeg/jpg/gif\n- 永久素材上限：100,000 张\n\n返回：\n```json\n{\"media_id\": \"...\", \"url\": \"...\"}\n```\n\n`media_id` 用于 `draft/add` 的 `thumb_media_id` 字段。\n\n## 上传正文图片\n\n```\nPOST /media/uploadimg?access_token={TOKEN}\nContent-Type: multipart/form-data\n```\n\n- 字段名：`media`\n- 限制：1MB，支持 jpg/png\n- 不占用素材库配额\n- 返回的 URL 可直接在正文 HTML 中使用\n\n返回：\n```json\n{\"url\": \"https://mmbiz.qpic.cn/...\"}\n```\n\n## 新增草稿\n\n```\nPOST /draft/add?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\n  \"articles\": [{\n    \"title\": \"标题（≤32字）\",\n    \"author\": \"作者（≤16字）\",\n    \"digest\": \"摘要（≤128字，仅单图文）\",\n    \"content\": \"HTML 正文（≤2万字符，图片 URL 必须来自 uploadimg）\",\n    \"thumb_media_id\": \"封面图 media_id\",\n    \"content_source_url\": \"原文链接\",\n    \"need_open_comment\": 1,\n    \"only_fans_can_comment\": 0\n  }]\n}\n```\n\n返回：\n```json\n{\"media_id\": \"...\"}\n```\n\n## 发布草稿\n\n```\nPOST /freepublish/submit?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\"media_id\": \"草稿的 media_id\"}\n```\n\n返回：\n```json\n{\"publish_id\": \"...\", \"msg_data_id\": \"...\"}\n```\n\n**注意**：发布为异步操作，返回成功仅表示任务提交成功。\n\n## 查询发布状态\n\n```\nPOST /freepublish/get?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\"publish_id\": \"...\"}\n```\n\n返回 `publish_status`：\n\n| 值 | 含义 |\n|----|------|\n| 0 | 发布成功 |\n| 1 | 发布中 |\n| 2 | 原创失败 |\n| 3 | 常规失败 |\n| 4 | 平台审核不通过 |\n| 5 | 已删除 |\n| 6 | 已封禁 |\n\n## 常见错误码\n\n| 错误码 | 含义 | 处理 |\n|--------|------|------|\n| 40001 | access_token 无效 | 重新获取 token |\n| 40004 | 不合法的媒体文件类型 | 检查图片格式 |\n| 40009 | 图片大小超限 | 封面 ≤10MB，正文图 ≤1MB |\n| 45009 | API 调用超限 | 等待后重试 |\n| 45028 | 接口无权限 | 检查公众号类型和权限 |\n| 48001 | API 未授权 | 检查公众号开发者设置 |\n\n## 凭证配置\n\n在仓库根 **`aws.env`** 中配置微信槽位（勿提交含真密钥的文件）：\n\n```env\nNUMBER_ACCOUNTS=1\nWECHAT_1_NAME=主号\nWECHAT_1_APPID=你的AppID\nWECHAT_1_APPSECRET=你的AppSecret\nWECHAT_1_API_BASE=\n```\n\n键名与 `skills/aws-wechat-article-main/references/env.example.yaml` 一致。多账号递增 `WECHAT_2_*` 等。\n\n## 权限要求\n\n- 需要已认证的服务号或订阅号\n- AppID 和 AppSecret 在「开发 → 基本配置」获取\n- 调用服务器 IP 需加入白名单\n\n## 官方文档\n\n- [新增草稿](https://developers.weixin.qq.com/doc/subscription/api/draftbox/draftmanage/api_draft_add)\n- [发布草稿](https://developers.weixin.qq.com/doc/subscription/api/public/api_freepublish_submit.html)\n- [上传永久素材](https://developers.weixin.qq.com/doc/subscription/api/material/permanent/api_addmaterial.html)\n- [上传正文图片](https://developers.weixin.qq.com/doc/subscription/en/api/material/permanent/api_uploadimage)\n\nFile v1.0.19:references/pre-publish-checklist.md\n\n# 发布前检查清单\n\n在审稿通过后、实际提交前执行，确保可安全发布。\n\n## 检查项\n\n- [ ] 标题、摘要、作者已最终确认\n- [ ] 正文无未替换的占位符或草稿标记\n- [ ] 敏感词与错别字已在审稿中修正\n- [ ] 封面图已就绪（已上传或路径有效）\n- [ ] 正文内图片齐全，图注格式正确\n- [ ] 原创/转载标注已按配置处理\n- [ ] 文末引导区块已就位\n- [ ] 如需开启评论/仅粉丝可评，已确认设置\n\n全部勾选后执行提交步骤。\n\nFile v1.0.19:references/submit-guide.md\n\n# 提交到公众号后台\n\n## 方式一：API 提交（推荐）\n\n使用 `skills/aws-wechat-article-publish/scripts/publish.py`，通过微信公众号 API 完成发布。\n\n### 前置准备\n\n1. 在仓库根 **`aws.env`** 中填写微信槽位（与 `skills/aws-wechat-article-main/references/env.example.yaml` 键名一致），例如单账号：\n   ```env\n   NUMBER_ACCOUNTS=1\n   WECHAT_1_NAME=主号\n   WECHAT_1_APPID=你的AppID\n   WECHAT_1_APPSECRET=你的AppSecret\n   WECHAT_1_API_BASE=\n   ```\n   多账号递增 `WECHAT_2_*` 等；发布前可运行 `python skills/aws-wechat-article-publish/scripts/publish.py check-wechat-env` 检查缺项。\n\n2. 在公众平台「开发 → 基本配置」中将服务器 IP 加入白名单\n\n3. 准备文章目录：\n   ```\n   article/\n   ├── article.yaml    # 标题、作者、摘要等元信息\n   ├── article.html    # 排版后的正文 HTML\n   ├── cover.jpg       # 封面图\n   └── imgs/           # 正文内图片\n   ```\n\n### 一键发布\n\n```bash\n# 创建草稿（不发布，可在后台预览）\npython skills/aws-wechat-article-publish/scripts/publish.py full article/\n\n# 创建草稿并立即发布\npython skills/aws-wechat-article-publish/scripts/publish.py full article/ --publish\n```\n\n### 分步操作\n\n```bash\n# 获取 token\npython skills/aws-wechat-article-publish/scripts/publish.py token\n\n# 上传封面图\npython skills/aws-wechat-article-publish/scripts/publish.py upload-thumb cover.jpg\n\n# 上传正文图片\npython skills/aws-wechat-article-publish/scripts/publish.py upload-content-image imgs/img1.png\n\n# 创建草稿（需要先准备好 article.yaml）\npython skills/aws-wechat-article-publish/scripts/publish.py create-draft article.yaml\n\n# 发布\npython skills/aws-wechat-article-publish/scripts/publish.py publish <media_id>\n\n# 查询状态\npython skills/aws-wechat-article-publish/scripts/publish.py status <publish_id>\n```\n\n接口详情与错误码：[api-reference.md](api-reference.md)\n\n## 方式二：手动提交\n\n1. 登录微信公众平台（mp.weixin.qq.com）\n2. 进入「素材管理」或「草稿箱」→ 新建图文消息\n3. 填写标题、作者、摘要\n4. 将排版后的正文粘贴到正文编辑区\n5. 上传封面图，设置封面\n6. 逐一上传正文内图片并插入对应位置\n7. 设置评论权限（开启/仅粉丝可评）\n8. 保存为草稿或直接群发\n\nFile v1.0.19:references/usage.md\n\n# 发布脚本用法\n\n脚本路径：**`skills/aws-wechat-article-publish/scripts/publish.py`**（在**仓库根**执行）。\n\n- **微信凭证**来自仓库根 **`aws.env`**：`NUMBER_ACCOUNTS`、`WECHAT_1_NAME`、`WECHAT_1_APPID`、`WECHAT_1_APPSECRET`、`WECHAT_1_API_BASE`（1..N 槽位）。`WECHAT_N_API_BASE` 可空（空则官方 `https://api.weixin.qq.com`）。\n- **`publish_method`** 在 **`config.yaml`**：**`draft`**（默认）= **`full`** 只进**草稿箱**；**`published`** = 再**提交发布**；**`none`** = **`full`** **不调接口**（用户不填微信）。**`full --publish`** 可在 **`draft`** 下单次强制发布（**`none`** 下仍跳过）。\n\n## `publish_method` 检查\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py check-screening\npython skills/aws-wechat-article-publish/scripts/publish.py check-screening --config .aws-article/config.yaml\n```\n\n## 微信槽位检查\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py check-wechat-env\npython skills/aws-wechat-article-publish/scripts/publish.py accounts\n```\n\n## 一键全流程\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py full path/to/article-dir/\n\npython skills/aws-wechat-article-publish/scripts/publish.py full path/to/article-dir/ --publish\n\npython skills/aws-wechat-article-publish/scripts/publish.py --account 2 full path/to/article-dir/\n```\n\n## 正式文章读取（`getdraft.py`）\n\n与 **`publish.py` 独立**，用于 **`freepublish/batchget`** / **`freepublish/get`** / **`freepublish/getarticle`**（仓库根执行）：\n\n```bash\npython skills/aws-wechat-article-publish/scripts/getdraft.py published-fields\npython skills/aws-wechat-article-publish/scripts/getdraft.py publish-get <publish_id>\npython skills/aws-wechat-article-publish/scripts/getdraft.py article-get <article_id>\n```\n\n## 分步操作\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py token\npython skills/aws-wechat-article-publish/scripts/publish.py upload-thumb cover.jpg\npython skills/aws-wechat-article-publish/scripts/publish.py upload-content-image img.png\npython skills/aws-wechat-article-publish/scripts/publish.py create-draft path/to/article.yaml\npython skills/aws-wechat-article-publish/scripts/publish.py publish <media_id>\n```\n\nFile v1.0.19:skill.json\n\n{\n  \"name\": \"aws-wechat-article-publish\",\n  \"version\": \"0.4.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"将文章发布到微信公众号，支持 API 发布和手动提交，含发布前检查。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"publish\", \"api\"],\n  \"permissions\": [\"filesystem\", \"network\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}\n\nArchive v1.0.18: 10 files, 30741 bytes\n\nFiles: references/api-reference.md (4153b), references/pre-publish-checklist.md (536b), references/submit-guide.md (2390b), references/usage.md (2293b), scripts/article_init.py (8262b), scripts/getdraft.py (16559b), scripts/publish.py (42311b), skill.json (494b), SKILL.md (11765b), _meta.json (146b)\n\nFile v1.0.18:SKILL.md\n\n---\nname: aws-wechat-article-publish\ndescription: 公众号发布｜公众号草稿箱｜公众号群发｜图文推送｜微信 API｜wechat automation｜WeChat API automation｜auto publish｜scheduled publish — 公众号 API 发布工具，图文入草稿箱或直接群发，支持封面素材上传、发布前检查与 draft/published 模式切换。面向公众号运营、自动化内容团队、开发者。触发词：「发布」「提交」「群发」「推送」「发出去」「上传到公众号」「发到公众号」「可以发了吗」「发布前检查」。需要多环节串联（写+审+排+配图+发）请走 aws-wechat-article-main。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\n---\n\n# 发布\n\n**公众号 API 直连发布** —— 图文入草稿箱或直接群发，素材上传、发布前检查一站式完成。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 前置依赖 ⛔ 套件必须装齐\n\n`aws-wechat-article-*` 一条龙套件的 9 个 skill 互相引用首次引导、环境校验与规则文档。**单独安装任一 skill 无法正常工作**，必须装齐 9 个：\n\n```\naws-wechat-article-main\naws-wechat-article-topics\naws-wechat-article-writing\naws-wechat-article-review\naws-wechat-article-formatting\naws-wechat-article-images\naws-wechat-article-publish\naws-wechat-article-assets\naws-wechat-sticker\n```\n\n**Agent：进入下方工作流前，先检查当前 `skills/` 目录下上述 9 个子目录是否都存在。**\n\n**若任一缺失** → 停止本 skill 工作流，**不得**尝试代替用户跑脚本或继续；按下述话术回复用户：\n\n> 本套件需 9 个 skill 都装齐才能使用。检测到缺少：`<列出缺失项>`。请执行：\n>\n> ```bash\n> # macOS / Linux / Git Bash\n> for slug in aws-wechat-article-main aws-wechat-article-topics aws-wechat-article-writing aws-wechat-article-review aws-wechat-article-formatting aws-wechat-article-images aws-wechat-article-publish aws-wechat-article-assets aws-wechat-sticker; do\n>   clawhub install \"$slug\"\n> done\n> ```\n>\n> ```powershell\n> # Windows PowerShell\n> 'aws-wechat-article-main','aws-wechat-article-topics','aws-wechat-article-writing','aws-wechat-article-review','aws-wechat-article-formatting','aws-wechat-article-images','aws-wechat-article-publish','aws-wechat-article-assets','aws-wechat-sticker' | ForEach-Object { clawhub install $_ }\n> ```\n>\n> 装完再回本 skill 让我继续。\n\n**9 个全部存在** → 按下方工作流继续。\n\n通过微信公众号 API 将排版稿写入**草稿箱**或再**提交发布**（由 **`config.yaml`** 的 **`publish_method`** 与命令行 **`--publish`** 控制）。\n\n## 配置检查 ⛔\n\n任何操作执行前，**必须**按 **[首次引导](../aws-wechat-article-main/references/first-time-setup.md)** 执行其中的 **「检测顺序」**。检测通过后才能进行以下操作（或用户明确书面确认「本次不检查」）：\n\n## 脚本目录\n\n**Agent 执行**：确定本 SKILL.md 所在目录为 `{baseDir}`。发布子命令在 **`{baseDir}/scripts/publish.py`**（项目根执行）。\n\n| 脚本 / 子命令 | 用途 |\n|--------|------|\n| **`article_init.py`** | 初始化或更新本篇 **`article.yaml`**（及可选 **`closing.md`**）。用于总览 **本篇准备**（建目录后）或 **发布前** 补全元数据。仓库根执行：`python {baseDir}/scripts/article_init.py <文章目录> [--title … --author … --digest …]` |\n| **`getdraft.py`** | 独立于 `publish.py`：用于正式文章查询（`published-list` / `published-fields` / `publish-get` / `article-get`，对应 `freepublish/*`），可用于 `embeds.related_articles.manual` 为空时自动补全推荐链接。注意：`freepublish/*` 需要公众号具备对应接口权限。仓库根：`python {baseDir}/scripts/getdraft.py published-fields` |\n| `check-screening` | 校验 **`config.yaml`** 的 **`publish_method`**（**`draft`** / **`published`** / **`none`**） |\n| `check-wechat-env` | 按 **`config.yaml` 槽位**检查 `aws.env` 的 `WECHAT_N_APPID` / `WECHAT_N_APPSECRET` 是否已填（**调用 `publish.py` 前建议跑**） |\n| `check` | 环境检查：`aws.env`、各槽位、依赖、可选探测 token |\n| `accounts` | 列出 **`config.yaml`** 中各微信槽位名称，并标记 `aws.env` 凭证缺项 |\n| `full` / `token` / … | 调微信 API（需 **`aws.env`** 微信凭证） |\n\n## 凭证与 `publish_method` ⛔\n\n### `publish_method`（以仓库 **`config.yaml`** 为准）\n\n| 值 | 含义 | 行为 |\n|----|------|------|\n| **`draft`**（默认） | 只进公众号**草稿箱** | **`full`** 创建草稿后**不**调用 freepublish 提交发布。 |\n| **`published`** | 草稿 + **提交发布** | **`full`** 创建草稿后继续提交发布（异步）。**`full --publish`** 可**单次强制**带发布，即使当前为 **`draft`**。 |\n| **`none`** | 用户明确不填微信 | **`full`** **立即退出**，不调任何微信接口（**`--publish`** 也会被忽略）。其它子命令（`token` 等）仍要凭证。 |\n\n### 多账号时如何选槽位\n\n1. 运行 **`python {baseDir}/scripts/publish.py accounts`**，从 **`config.yaml` 的 `wechat_accounts` + `wechat_N_name`** 向用户展示列表（例如：`您有2个账号：1.\"xiaoming\"，2.\"xiaoz\"`）必须询问用户选择哪个账号发布到草稿箱，然后根据用户选择发布到指定的账号。\n2. 在 **`config.yaml`** 写 **`wechat_publish_slot: <整数>`**，**或**命令行 **`--account <序号或名称>`**（**CLI 优先**，见 [articlescreening-schema.md](../aws-wechat-article-main/references/articlescreening-schema.md)）。\n\n### 全局环境\n\n在仓库根具备 **`aws.env`**（微信密钥）与 **`config.yaml`**（微信槽位数量与名称）。写作/生图见 **`validate_env.py`**（微信未齐仍可先做内容）。**`publish_method: none`** 时 **`full`** 会跳过；**`draft`/`published`** 发布前建议 **`check-wechat-env`**。API 端点优先取 **`WECHAT_N_API_BASE`**，若槽位未配则回退 **`config.yaml.wechat_api_base`**（两者都空时使用官方）。\n\n### 作者名回退\n\n`full` / `create-draft` 若 **`article.yaml` 无 author**，回退 **`config.yaml`** 的 **`default_author`**。\n\n### `publish_completed`（本篇是否已发布完成）\n\n- 字段在**本篇** **`article.yaml`**。**`publish.py` 不读、不改**；由智能体维护。\n- **`false`**：发布流程未闭环。\n- **`true`**：已视为发布完成（草稿已确认 / 或 **`published`** 流程成功且运营确认）。\n\n**本篇发布真正结束后**：将 **`publish_completed: true`** 写回 **`article.yaml`**。\n\n**写回 `true` 的前置门禁（缺啥补啥）**：\n\n1. `article.html` 存在；\n2. 文章目录存在封面图 `cover.(png/jpg/jpeg/webp)`；\n3. `article.md` 与 `article.html` 中均不含 `placeholder`；\n4. 发布命令成功并拿到回执（`media_id` 或 `publish_id`）。\n\n任一不满足：只可标记为“已提交草稿，未闭环”，**不得**写回 `publish_completed: true`。\n\n## 用户仅说「发布」且未明确路径时 ⛔\n\n在用户**未给出** `drafts/…` 路径、仅说「发布文章」「帮我发一下」等时：\n\n1. **确定本篇目录**：列出仓库下 **`drafts/`** 中子目录；若**多篇**，请用户**指定一篇**或选「最新修改」的一篇再读该目录 **`article.yaml`**。**勿**在未确认目录时假定路径。\n2. 读取该目录 **`article.yaml`** 中的 **`publish_completed`**（YAML 布尔：`true` / `false`；**缺省按 `false` 处理**）。\n\n| `publish_completed` | 智能体对用户说明（可略作口语化，勿改含义） |\n|---------------------|---------------------------------------------|\n| **`true`** | 告知：**项目里本篇文档已按记录成功发布**；问：**您是否需要编写新文章？** 若需要 → 转交 [main](../aws-wechat-article-main/SKILL.md) / [writing](../aws-wechat-article-writing/SKILL.md) 从本篇准备或选题起走。 |\n| **`false`** 或缺省 | 读取 **`article.yaml`** 的 **`title`**（若无则用目录名简述），说明：**《{title}》尚未执行完成（发布流程未闭环）**；问：**是否需要继续并完成发布？** 或 **编写新文章？** 若继续本篇 → 再核对 **`config.yaml`** 的 **`publish_method`**、**`check-screening`**、**`check-wechat-env`** 等。 |\n\n## 工作流\n\n```\n发布进度：\n- [ ] 前置：配置检查（见本节「配置检查」）⛔\n- [ ] 第0步：若用户未给路径 → 选本篇目录 → 读 publish_completed → 按上表分流（true/false）\n- [ ] 第1步：读 **`config.yaml`** → **`draft` / `published`**（及是否 **`full --publish`**）\n- [ ] 第2步：读取 **`config.yaml`** 的 `wechat_accounts` + `wechat_N_name` 向用户展示账号列表并询问目标槽位；随后跑 **`check-wechat-env`** 校验 `aws.env` 凭证 → **`wechat_publish_slot` 或 `--account`**\n- [ ] 第3步：发布前检查（checklist + **`check-screening`** + **`check`**）\n- [ ] 第4步：准备文章目录\n- [ ] 第5步：**`full`**（仅草稿或含发布，视上步）\n- [ ] 第6步：确认结果与用户说明\n- [ ] 第7步：成功后写回 **`article.yaml`** 的 **`publish_completed: true`**；按需归档\n```\n\n## 交互顺序（最小提问）\n\n0) **未给路径时**：先按上文 **「用户仅说发布」** 处理 **`publish_completed`**；用户选 **继续本篇** 后再做下列步骤。  \n1) **先看 `config.yaml` 的 `publish_method`**：**`draft`** = 默认只进草稿箱；**`published`** 或 **`full --publish`** = 再提交发布。  \n2) **多槽位**：展示账号列表（来源：`config.yaml` 的 `wechat_accounts` + `wechat_N_name`），**必须请用户选槽位** → **`wechat_publish_slot`** 或 **`--account`**。  \n3) 缺微信字段：运行 **`check-wechat-env`**，补全 **`aws.env`** 后再发。  \n4) **发布失败**（由脚本 stderr / 微信 errcode 判断）：  \n   - **网络类**（超时、连接失败、5xx）：脚本已对单次请求 **自动重试 1 次**；仍失败 → 告知「网络不可用，请稍后重试或检查代理」。  \n   - **凭证/配置类**（如 token 失败带 errcode、缺字段）→ 提示 **第几槽位**、检查 **APPID/SECRET、IP 白名单**，用户改正后再执行 **`full`** / **`publish`**。\n5) **中间产物缺失**（封面缺失 / 存在 `placeholder`）：先补产物再发；若用户坚持先发草稿，必须明确告知“正文配图未完成”，且保持 `publish_completed: false`。\n\n## 命令示例（仓库根）\n\n```bash\npython {baseDir}/scripts/publish.py check-screening\npython {baseDir}/scripts/publish.py check-wechat-env\npython {baseDir}/scripts/publish.py accounts\npython {baseDir}/scripts/publish.py check\npython {baseDir}/scripts/publish.py --account 1 full drafts/YYYYMMDD-标题slug/\npython {baseDir}/scripts/getdraft.py published-fields\n```\n\n详见 [references/usage.md](references/usage.md)、[references/submit-guide.md](references/submit-guide.md)、[references/api-reference.md](references/api-reference.md)。\n\n## 过程文件\n\n| 读取 | 产出 |\n|------|------|\n| `article.html`、`imgs/`、**`article.yaml`**（含 **`publish_completed`** 等）、**`.aws-article/config.yaml`**、**`aws.env`**（微信槽位） | 发布到公众号草稿或提交发布；**成功后**由智能体将 **`publish_completed: true`** 写回 **`article.yaml`**（`publish.py` 不改此键） |\n\nFile v1.0.18:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-publish\",\n  \"version\": \"1.0.18\",\n  \"publishedAt\": 1776873211762\n}\n\nFile v1.0.18:references/api-reference.md\n\n# 微信公众号 API 参考\n\n## 接口一览\n\n| 接口 | 方法 | 路径 | 用途 |\n|------|------|------|------|\n| 获取 token | GET | `/token` | 获取 access_token |\n| 上传永久素材 | POST | `/material/add_material` | 上传封面图，返回 media_id |\n| 上传正文图片 | POST | `/media/uploadimg` | 上传正文内图片，返回 URL |\n| 新增草稿 | POST | `/draft/add` | 创建图文草稿 |\n| 发布草稿 | POST | `/freepublish/submit` | 发布草稿（异步） |\n| 查询发布状态 | POST | `/freepublish/get` | 查询发布结果 |\n\n所有接口基础 URL：`https://api.weixin.qq.com/cgi-bin`\n\n## 获取 access_token\n\n```\nGET /token?grant_type=client_credential&appid={APPID}&secret={APPSECRET}\n```\n\n返回：\n```json\n{\"access_token\": \"...\", \"expires_in\": 7200}\n```\n\n有效期 2 小时，需缓存复用，避免频繁请求。\n\n## 上传封面图（永久素材）\n\n```\nPOST /material/add_material?access_token={TOKEN}&type=image\nContent-Type: multipart/form-data\n```\n\n- 字段名：`media`\n- 限制：10MB，支持 bmp/png/jpeg/jpg/gif\n- 永久素材上限：100,000 张\n\n返回：\n```json\n{\"media_id\": \"...\", \"url\": \"...\"}\n```\n\n`media_id` 用于 `draft/add` 的 `thumb_media_id` 字段。\n\n## 上传正文图片\n\n```\nPOST /media/uploadimg?access_token={TOKEN}\nContent-Type: multipart/form-data\n```\n\n- 字段名：`media`\n- 限制：1MB，支持 jpg/png\n- 不占用素材库配额\n- 返回的 URL 可直接在正文 HTML 中使用\n\n返回：\n```json\n{\"url\": \"https://mmbiz.qpic.cn/...\"}\n```\n\n## 新增草稿\n\n```\nPOST /draft/add?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\n  \"articles\": [{\n    \"title\": \"标题（≤32字）\",\n    \"author\": \"作者（≤16字）\",\n    \"digest\": \"摘要（≤128字，仅单图文）\",\n    \"content\": \"HTML 正文（≤2万字符，图片 URL 必须来自 uploadimg）\",\n    \"thumb_media_id\": \"封面图 media_id\",\n    \"content_source_url\": \"原文链接\",\n    \"need_open_comment\": 1,\n    \"only_fans_can_comment\": 0\n  }]\n}\n```\n\n返回：\n```json\n{\"media_id\": \"...\"}\n```\n\n## 发布草稿\n\n```\nPOST /freepublish/submit?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\"media_id\": \"草稿的 media_id\"}\n```\n\n返回：\n```json\n{\"publish_id\": \"...\", \"msg_data_id\": \"...\"}\n```\n\n**注意**：发布为异步操作，返回成功仅表示任务提交成功。\n\n## 查询发布状态\n\n```\nPOST /freepublish/get?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\"publish_id\": \"...\"}\n```\n\n返回 `publish_status`：\n\n| 值 | 含义 |\n|----|------|\n| 0 | 发布成功 |\n| 1 | 发布中 |\n| 2 | 原创失败 |\n| 3 | 常规失败 |\n| 4 | 平台审核不通过 |\n| 5 | 已删除 |\n| 6 | 已封禁 |\n\n## 常见错误码\n\n| 错误码 | 含义 | 处理 |\n|--------|------|------|\n| 40001 | access_token 无效 | 重新获取 token |\n| 40004 | 不合法的媒体文件类型 | 检查图片格式 |\n| 40009 | 图片大小超限 | 封面 ≤10MB，正文图 ≤1MB |\n| 45009 | API 调用超限 | 等待后重试 |\n| 45028 | 接口无权限 | 检查公众号类型和权限 |\n| 48001 | API 未授权 | 检查公众号开发者设置 |\n\n## 凭证配置\n\n在仓库根 **`aws.env`** 中配置微信槽位（勿提交含真密钥的文件）：\n\n```env\nNUMBER_ACCOUNTS=1\nWECHAT_1_NAME=主号\nWECHAT_1_APPID=你的AppID\nWECHAT_1_APPSECRET=你的AppSecret\nWECHAT_1_API_BASE=\n```\n\n键名与 `skills/aws-wechat-article-main/references/env.example.yaml` 一致。多账号递增 `WECHAT_2_*` 等。\n\n## 权限要求\n\n- 需要已认证的服务号或订阅号\n- AppID 和 AppSecret 在「开发 → 基本配置」获取\n- 调用服务器 IP 需加入白名单\n\n## 官方文档\n\n- [新增草稿](https://developers.weixin.qq.com/doc/subscription/api/draftbox/draftmanage/api_draft_add)\n- [发布草稿](https://developers.weixin.qq.com/doc/subscription/api/public/api_freepublish_submit.html)\n- [上传永久素材](https://developers.weixin.qq.com/doc/subscription/api/material/permanent/api_addmaterial.html)\n- [上传正文图片](https://developers.weixin.qq.com/doc/subscription/en/api/material/permanent/api_uploadimage)\n\nFile v1.0.18:references/pre-publish-checklist.md\n\n# 发布前检查清单\n\n在审稿通过后、实际提交前执行，确保可安全发布。\n\n## 检查项\n\n- [ ] 标题、摘要、作者已最终确认\n- [ ] 正文无未替换的占位符或草稿标记\n- [ ] 敏感词与错别字已在审稿中修正\n- [ ] 封面图已就绪（已上传或路径有效）\n- [ ] 正文内图片齐全，图注格式正确\n- [ ] 原创/转载标注已按配置处理\n- [ ] 文末引导区块已就位\n- [ ] 如需开启评论/仅粉丝可评，已确认设置\n\n全部勾选后执行提交步骤。\n\nFile v1.0.18:references/submit-guide.md\n\n# 提交到公众号后台\n\n## 方式一：API 提交（推荐）\n\n使用 `skills/aws-wechat-article-publish/scripts/publish.py`，通过微信公众号 API 完成发布。\n\n### 前置准备\n\n1. 在仓库根 **`aws.env`** 中填写微信槽位（与 `skills/aws-wechat-article-main/references/env.example.yaml` 键名一致），例如单账号：\n   ```env\n   NUMBER_ACCOUNTS=1\n   WECHAT_1_NAME=主号\n   WECHAT_1_APPID=你的AppID\n   WECHAT_1_APPSECRET=你的AppSecret\n   WECHAT_1_API_BASE=\n   ```\n   多账号递增 `WECHAT_2_*` 等；发布前可运行 `python skills/aws-wechat-article-publish/scripts/publish.py check-wechat-env` 检查缺项。\n\n2. 在公众平台「开发 → 基本配置」中将服务器 IP 加入白名单\n\n3. 准备文章目录：\n   ```\n   article/\n   ├── article.yaml    # 标题、作者、摘要等元信息\n   ├── article.html    # 排版后的正文 HTML\n   ├── cover.jpg       # 封面图\n   └── imgs/           # 正文内图片\n   ```\n\n### 一键发布\n\n```bash\n# 创建草稿（不发布，可在后台预览）\npython skills/aws-wechat-article-publish/scripts/publish.py full article/\n\n# 创建草稿并立即发布\npython skills/aws-wechat-article-publish/scripts/publish.py full article/ --publish\n```\n\n### 分步操作\n\n```bash\n# 获取 token\npython skills/aws-wechat-article-publish/scripts/publish.py token\n\n# 上传封面图\npython skills/aws-wechat-article-publish/scripts/publish.py upload-thumb cover.jpg\n\n# 上传正文图片\npython skills/aws-wechat-article-publish/scripts/publish.py upload-content-image imgs/img1.png\n\n# 创建草稿（需要先准备好 article.yaml）\npython skills/aws-wechat-article-publish/scripts/publish.py create-draft article.yaml\n\n# 发布\npython skills/aws-wechat-article-publish/scripts/publish.py publish <media_id>\n\n# 查询状态\npython skills/aws-wechat-article-publish/scripts/publish.py status <publish_id>\n```\n\n接口详情与错误码：[api-reference.md](api-reference.md)\n\n## 方式二：手动提交\n\n1. 登录微信公众平台（mp.weixin.qq.com）\n2. 进入「素材管理」或「草稿箱」→ 新建图文消息\n3. 填写标题、作者、摘要\n4. 将排版后的正文粘贴到正文编辑区\n5. 上传封面图，设置封面\n6. 逐一上传正文内图片并插入对应位置\n7. 设置评论权限（开启/仅粉丝可评）\n8. 保存为草稿或直接群发\n\nFile v1.0.18:references/usage.md\n\n# 发布脚本用法\n\n脚本路径：**`skills/aws-wechat-article-publish/scripts/publish.py`**（在**仓库根**执行）。\n\n- **微信凭证**来自仓库根 **`aws.env`**：`NUMBER_ACCOUNTS`、`WECHAT_1_NAME`、`WECHAT_1_APPID`、`WECHAT_1_APPSECRET`、`WECHAT_1_API_BASE`（1..N 槽位）。`WECHAT_N_API_BASE` 可空（空则官方 `https://api.weixin.qq.com`）。\n- **`publish_method`** 在 **`config.yaml`**：**`draft`**（默认）= **`full`** 只进**草稿箱**；**`published`** = 再**提交发布**；**`none`** = **`full`** **不调接口**（用户不填微信）。**`full --publish`** 可在 **`draft`** 下单次强制发布（**`none`** 下仍跳过）。\n\n## `publish_method` 检查\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py check-screening\npython skills/aws-wechat-article-publish/scripts/publish.py check-screening --config .aws-article/config.yaml\n```\n\n## 微信槽位检查\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py check-wechat-env\npython skills/aws-wechat-article-publish/scripts/publish.py accounts\n```\n\n## 一键全流程\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py full path/to/article-dir/\n\npython skills/aws-wechat-article-publish/scripts/publish.py full path/to/article-dir/ --publish\n\npython skills/aws-wechat-article-publish/scripts/publish.py --account 2 full path/to/article-dir/\n```\n\n## 正式文章读取（`getdraft.py`）\n\n与 **`publish.py` 独立**，用于 **`freepublish/batchget`** / **`freepublish/get`** / **`freepublish/getarticle`**（仓库根执行）：\n\n```bash\npython skills/aws-wechat-article-publish/scripts/getdraft.py published-fields\npython skills/aws-wechat-article-publish/scripts/getdraft.py publish-get <publish_id>\npython skills/aws-wechat-article-publish/scripts/getdraft.py article-get <article_id>\n```\n\n## 分步操作\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py token\npython skills/aws-wechat-article-publish/scripts/publish.py upload-thumb cover.jpg\npython skills/aws-wechat-article-publish/scripts/publish.py upload-content-image img.png\npython skills/aws-wechat-article-publish/scripts/publish.py create-draft path/to/article.yaml\npython skills/aws-wechat-article-publish/scripts/publish.py publish <media_id>\n```\n\nFile v1.0.18:skill.json\n\n{\n  \"name\": \"aws-wechat-article-publish\",\n  \"version\": \"0.4.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"将文章发布到微信公众号，支持 API 发布和手动提交，含发布前检查。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"publish\", \"api\"],\n  \"permissions\": [\"filesystem\", \"network\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}\n\nArchive v1.0.17: 10 files, 30685 bytes\n\nFiles: references/api-reference.md (4153b), references/pre-publish-checklist.md (536b), references/submit-guide.md (2390b), references/usage.md (2293b), scripts/article_init.py (8262b), scripts/getdraft.py (16559b), scripts/publish.py (42311b), skill.json (494b), SKILL.md (11631b), _meta.json (146b)\n\nFile v1.0.17:SKILL.md\n\n---\nname: aws-wechat-article-publish\ndescription: 公众号发布｜微信公众号发布｜公众号草稿箱｜公众号群发｜公众号推送｜图文推送｜微信 API｜WeChat API｜公众号自动发布｜content publishing｜wechat automation — 公众号 API 发布工具，图文入草稿箱或直接群发，支持封面素材上传、发布前检查与 draft/published 模式切换。面向公众号运营、自动化内容团队、开发者。触发词：「发布」「提交」「群发」「推送」「发出去」「上传到公众号」「发到公众号」「可以发了吗」「发布前检查」。\n---\n\n# 发布\n\n**公众号 API 直连发布** —— 图文入草稿箱或直接群发，素材上传、发布前检查一站式完成。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 前置依赖 ⛔ 套件必须装齐\n\n`aws-wechat-article-*` 一条龙套件的 9 个 skill 互相引用首次引导、环境校验与规则文档。**单独安装任一 skill 无法正常工作**，必须装齐 9 个：\n\n```\naws-wechat-article-main\naws-wechat-article-topics\naws-wechat-article-writing\naws-wechat-article-review\naws-wechat-article-formatting\naws-wechat-article-images\naws-wechat-article-publish\naws-wechat-article-assets\naws-wechat-sticker\n```\n\n**Agent：进入下方工作流前，先检查当前 `skills/` 目录下上述 9 个子目录是否都存在。**\n\n**若任一缺失** → 停止本 skill 工作流，**不得**尝试代替用户跑脚本或继续；按下述话术回复用户：\n\n> 本套件需 9 个 skill 都装齐才能使用。检测到缺少：`<列出缺失项>`。请执行：\n>\n> ```bash\n> # macOS / Linux / Git Bash\n> for slug in aws-wechat-article-main aws-wechat-article-topics aws-wechat-article-writing aws-wechat-article-review aws-wechat-article-formatting aws-wechat-article-images aws-wechat-article-publish aws-wechat-article-assets aws-wechat-sticker; do\n>   clawhub install \"$slug\"\n> done\n> ```\n>\n> ```powershell\n> # Windows PowerShell\n> 'aws-wechat-article-main','aws-wechat-article-topics','aws-wechat-article-writing','aws-wechat-article-review','aws-wechat-article-formatting','aws-wechat-article-images','aws-wechat-article-publish','aws-wechat-article-assets','aws-wechat-sticker' | ForEach-Object { clawhub install $_ }\n> ```\n>\n> 装完再回本 skill 让我继续。\n\n**9 个全部存在** → 按下方工作流继续。\n\n通过微信公众号 API 将排版稿写入**草稿箱**或再**提交发布**（由 **`config.yaml`** 的 **`publish_method`** 与命令行 **`--publish`** 控制）。\n\n## 配置检查 ⛔\n\n任何操作执行前，**必须**按 **[首次引导](../aws-wechat-article-main/references/first-time-setup.md)** 执行其中的 **「检测顺序」**。检测通过后才能进行以下操作（或用户明确书面确认「本次不检查」）：\n\n## 脚本目录\n\n**Agent 执行**：确定本 SKILL.md 所在目录为 `{baseDir}`。发布子命令在 **`{baseDir}/scripts/publish.py`**（项目根执行）。\n\n| 脚本 / 子命令 | 用途 |\n|--------|------|\n| **`article_init.py`** | 初始化或更新本篇 **`article.yaml`**（及可选 **`closing.md`**）。用于总览 **本篇准备**（建目录后）或 **发布前** 补全元数据。仓库根执行：`python {baseDir}/scripts/article_init.py <文章目录> [--title … --author … --digest …]` |\n| **`getdraft.py`** | 独立于 `publish.py`：用于正式文章查询（`published-list` / `published-fields` / `publish-get` / `article-get`，对应 `freepublish/*`），可用于 `embeds.related_articles.manual` 为空时自动补全推荐链接。注意：`freepublish/*` 需要公众号具备对应接口权限。仓库根：`python {baseDir}/scripts/getdraft.py published-fields` |\n| `check-screening` | 校验 **`config.yaml`** 的 **`publish_method`**（**`draft`** / **`published`** / **`none`**） |\n| `check-wechat-env` | 按 **`config.yaml` 槽位**检查 `aws.env` 的 `WECHAT_N_APPID` / `WECHAT_N_APPSECRET` 是否已填（**调用 `publish.py` 前建议跑**） |\n| `check` | 环境检查：`aws.env`、各槽位、依赖、可选探测 token |\n| `accounts` | 列出 **`config.yaml`** 中各微信槽位名称，并标记 `aws.env` 凭证缺项 |\n| `full` / `token` / … | 调微信 API（需 **`aws.env`** 微信凭证） |\n\n## 凭证与 `publish_method` ⛔\n\n### `publish_method`（以仓库 **`config.yaml`** 为准）\n\n| 值 | 含义 | 行为 |\n|----|------|------|\n| **`draft`**（默认） | 只进公众号**草稿箱** | **`full`** 创建草稿后**不**调用 freepublish 提交发布。 |\n| **`published`** | 草稿 + **提交发布** | **`full`** 创建草稿后继续提交发布（异步）。**`full --publish`** 可**单次强制**带发布，即使当前为 **`draft`**。 |\n| **`none`** | 用户明确不填微信 | **`full`** **立即退出**，不调任何微信接口（**`--publish`** 也会被忽略）。其它子命令（`token` 等）仍要凭证。 |\n\n### 多账号时如何选槽位\n\n1. 运行 **`python {baseDir}/scripts/publish.py accounts`**，从 **`config.yaml` 的 `wechat_accounts` + `wechat_N_name`** 向用户展示列表（例如：`您有2个账号：1.\"xiaoming\"，2.\"xiaoz\"`）必须询问用户选择哪个账号发布到草稿箱，然后根据用户选择发布到指定的账号。\n2. 在 **`config.yaml`** 写 **`wechat_publish_slot: <整数>`**，**或**命令行 **`--account <序号或名称>`**（**CLI 优先**，见 [articlescreening-schema.md](../aws-wechat-article-main/references/articlescreening-schema.md)）。\n\n### 全局环境\n\n在仓库根具备 **`aws.env`**（微信密钥）与 **`config.yaml`**（微信槽位数量与名称）。写作/生图见 **`validate_env.py`**（微信未齐仍可先做内容）。**`publish_method: none`** 时 **`full`** 会跳过；**`draft`/`published`** 发布前建议 **`check-wechat-env`**。API 端点优先取 **`WECHAT_N_API_BASE`**，若槽位未配则回退 **`config.yaml.wechat_api_base`**（两者都空时使用官方）。\n\n### 作者名回退\n\n`full` / `create-draft` 若 **`article.yaml` 无 author**，回退 **`config.yaml`** 的 **`default_author`**。\n\n### `publish_completed`（本篇是否已发布完成）\n\n- 字段在**本篇** **`article.yaml`**。**`publish.py` 不读、不改**；由智能体维护。\n- **`false`**：发布流程未闭环。\n- **`true`**：已视为发布完成（草稿已确认 / 或 **`published`** 流程成功且运营确认）。\n\n**本篇发布真正结束后**：将 **`publish_completed: true`** 写回 **`article.yaml`**。\n\n**写回 `true` 的前置门禁（缺啥补啥）**：\n\n1. `article.html` 存在；\n2. 文章目录存在封面图 `cover.(png/jpg/jpeg/webp)`；\n3. `article.md` 与 `article.html` 中均不含 `placeholder`；\n4. 发布命令成功并拿到回执（`media_id` 或 `publish_id`）。\n\n任一不满足：只可标记为“已提交草稿，未闭环”，**不得**写回 `publish_completed: true`。\n\n## 用户仅说「发布」且未明确路径时 ⛔\n\n在用户**未给出** `drafts/…` 路径、仅说「发布文章」「帮我发一下」等时：\n\n1. **确定本篇目录**：列出仓库下 **`drafts/`** 中子目录；若**多篇**，请用户**指定一篇**或选「最新修改」的一篇再读该目录 **`article.yaml`**。**勿**在未确认目录时假定路径。\n2. 读取该目录 **`article.yaml`** 中的 **`publish_completed`**（YAML 布尔：`true` / `false`；**缺省按 `false` 处理**）。\n\n| `publish_completed` | 智能体对用户说明（可略作口语化，勿改含义） |\n|---------------------|---------------------------------------------|\n| **`true`** | 告知：**项目里本篇文档已按记录成功发布**；问：**您是否需要编写新文章？** 若需要 → 转交 [main](../aws-wechat-article-main/SKILL.md) / [writing](../aws-wechat-article-writing/SKILL.md) 从本篇准备或选题起走。 |\n| **`false`** 或缺省 | 读取 **`article.yaml`** 的 **`title`**（若无则用目录名简述），说明：**《{title}》尚未执行完成（发布流程未闭环）**；问：**是否需要继续并完成发布？** 或 **编写新文章？** 若继续本篇 → 再核对 **`config.yaml`** 的 **`publish_method`**、**`check-screening`**、**`check-wechat-env`** 等。 |\n\n## 工作流\n\n```\n发布进度：\n- [ ] 前置：配置检查（见本节「配置检查」）⛔\n- [ ] 第0步：若用户未给路径 → 选本篇目录 → 读 publish_completed → 按上表分流（true/false）\n- [ ] 第1步：读 **`config.yaml`** → **`draft` / `published`**（及是否 **`full --publish`**）\n- [ ] 第2步：读取 **`config.yaml`** 的 `wechat_accounts` + `wechat_N_name` 向用户展示账号列表并询问目标槽位；随后跑 **`check-wechat-env`** 校验 `aws.env` 凭证 → **`wechat_publish_slot` 或 `--account`**\n- [ ] 第3步：发布前检查（checklist + **`check-screening`** + **`check`**）\n- [ ] 第4步：准备文章目录\n- [ ] 第5步：**`full`**（仅草稿或含发布，视上步）\n- [ ] 第6步：确认结果与用户说明\n- [ ] 第7步：成功后写回 **`article.yaml`** 的 **`publish_completed: true`**；按需归档\n```\n\n## 交互顺序（最小提问）\n\n0) **未给路径时**：先按上文 **「用户仅说发布」** 处理 **`publish_completed`**；用户选 **继续本篇** 后再做下列步骤。  \n1) **先看 `config.yaml` 的 `publish_method`**：**`draft`** = 默认只进草稿箱；**`published`** 或 **`full --publish`** = 再提交发布。  \n2) **多槽位**：展示账号列表（来源：`config.yaml` 的 `wechat_accounts` + `wechat_N_name`），**必须请用户选槽位** → **`wechat_publish_slot`** 或 **`--account`**。  \n3) 缺微信字段：运行 **`check-wechat-env`**，补全 **`aws.env`** 后再发。  \n4) **发布失败**（由脚本 stderr / 微信 errcode 判断）：  \n   - **网络类**（超时、连接失败、5xx）：脚本已对单次请求 **自动重试 1 次**；仍失败 → 告知「网络不可用，请稍后重试或检查代理」。  \n   - **凭证/配置类**（如 token 失败带 errcode、缺字段）→ 提示 **第几槽位**、检查 **APPID/SECRET、IP 白名单**，用户改正后再执行 **`full`** / **`publish`**。\n5) **中间产物缺失**（封面缺失 / 存在 `placeholder`）：先补产物再发；若用户坚持先发草稿，必须明确告知“正文配图未完成”，且保持 `publish_completed: false`。\n\n## 命令示例（仓库根）\n\n```bash\npython {baseDir}/scripts/publish.py check-screening\npython {baseDir}/scripts/publish.py check-wechat-env\npython {baseDir}/scripts/publish.py accounts\npython {baseDir}/scripts/publish.py check\npython {baseDir}/scripts/publish.py --account 1 full drafts/YYYYMMDD-标题slug/\npython {baseDir}/scripts/getdraft.py published-fields\n```\n\n详见 [references/usage.md](references/usage.md)、[references/submit-guide.md](references/submit-guide.md)、[references/api-reference.md](references/api-reference.md)。\n\n## 过程文件\n\n| 读取 | 产出 |\n|------|------|\n| `article.html`、`imgs/`、**`article.yaml`**（含 **`publish_completed`** 等）、**`.aws-article/config.yaml`**、**`aws.env`**（微信槽位） | 发布到公众号草稿或提交发布；**成功后**由智能体将 **`publish_completed: true`** 写回 **`article.yaml`**（`publish.py` 不改此键） |\n\nFile v1.0.17:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-publish\",\n  \"version\": \"1.0.17\",\n  \"publishedAt\": 1776847531979\n}\n\nFile v1.0.17:references/api-reference.md\n\n# 微信公众号 API 参考\n\n## 接口一览\n\n| 接口 | 方法 | 路径 | 用途 |\n|------|------|------|------|\n| 获取 token | GET | `/token` | 获取 access_token |\n| 上传永久素材 | POST | `/material/add_material` | 上传封面图，返回 media_id |\n| 上传正文图片 | POST | `/media/uploadimg` | 上传正文内图片，返回 URL |\n| 新增草稿 | POST | `/draft/add` | 创建图文草稿 |\n| 发布草稿 | POST | `/freepublish/submit` | 发布草稿（异步） |\n| 查询发布状态 | POST | `/freepublish/get` | 查询发布结果 |\n\n所有接口基础 URL：`https://api.weixin.qq.com/cgi-bin`\n\n## 获取 access_token\n\n```\nGET /token?grant_type=client_credential&appid={APPID}&secret={APPSECRET}\n```\n\n返回：\n```json\n{\"access_token\": \"...\", \"expires_in\": 7200}\n```\n\n有效期 2 小时，需缓存复用，避免频繁请求。\n\n## 上传封面图（永久素材）\n\n```\nPOST /material/add_material?access_token={TOKEN}&type=image\nContent-Type: multipart/form-data\n```\n\n- 字段名：`media`\n- 限制：10MB，支持 bmp/png/jpeg/jpg/gif\n- 永久素材上限：100,000 张\n\n返回：\n```json\n{\"media_id\": \"...\", \"url\": \"...\"}\n```\n\n`media_id` 用于 `draft/add` 的 `thumb_media_id` 字段。\n\n## 上传正文图片\n\n```\nPOST /media/uploadimg?access_token={TOKEN}\nContent-Type: multipart/form-data\n```\n\n- 字段名：`media`\n- 限制：1MB，支持 jpg/png\n- 不占用素材库配额\n- 返回的 URL 可直接在正文 HTML 中使用\n\n返回：\n```json\n{\"url\": \"https://mmbiz.qpic.cn/...\"}\n```\n\n## 新增草稿\n\n```\nPOST /draft/add?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\n  \"articles\": [{\n    \"title\": \"标题（≤32字）\",\n    \"author\": \"作者（≤16字）\",\n    \"digest\": \"摘要（≤128字，仅单图文）\",\n    \"content\": \"HTML 正文（≤2万字符，图片 URL 必须来自 uploadimg）\",\n    \"thumb_media_id\": \"封面图 media_id\",\n    \"content_source_url\": \"原文链接\",\n    \"need_open_comment\": 1,\n    \"only_fans_can_comment\": 0\n  }]\n}\n```\n\n返回：\n```json\n{\"media_id\": \"...\"}\n```\n\n## 发布草稿\n\n```\nPOST /freepublish/submit?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\"media_id\": \"草稿的 media_id\"}\n```\n\n返回：\n```json\n{\"publish_id\": \"...\", \"msg_data_id\": \"...\"}\n```\n\n**注意**：发布为异步操作，返回成功仅表示任务提交成功。\n\n## 查询发布状态\n\n```\nPOST /freepublish/get?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\"publish_id\": \"...\"}\n```\n\n返回 `publish_status`：\n\n| 值 | 含义 |\n|----|------|\n| 0 | 发布成功 |\n| 1 | 发布中 |\n| 2 | 原创失败 |\n| 3 | 常规失败 |\n| 4 | 平台审核不通过 |\n| 5 | 已删除 |\n| 6 | 已封禁 |\n\n## 常见错误码\n\n| 错误码 | 含义 | 处理 |\n|--------|------|------|\n| 40001 | access_token 无效 | 重新获取 token |\n| 40004 | 不合法的媒体文件类型 | 检查图片格式 |\n| 40009 | 图片大小超限 | 封面 ≤10MB，正文图 ≤1MB |\n| 45009 | API 调用超限 | 等待后重试 |\n| 45028 | 接口无权限 | 检查公众号类型和权限 |\n| 48001 | API 未授权 | 检查公众号开发者设置 |\n\n## 凭证配置\n\n在仓库根 **`aws.env`** 中配置微信槽位（勿提交含真密钥的文件）：\n\n```env\nNUMBER_ACCOUNTS=1\nWECHAT_1_NAME=主号\nWECHAT_1_APPID=你的AppID\nWECHAT_1_APPSECRET=你的AppSecret\nWECHAT_1_API_BASE=\n```\n\n键名与 `skills/aws-wechat-article-main/references/env.example.yaml` 一致。多账号递增 `WECHAT_2_*` 等。\n\n## 权限要求\n\n- 需要已认证的服务号或订阅号\n- AppID 和 AppSecret 在「开发 → 基本配置」获取\n- 调用服务器 IP 需加入白名单\n\n## 官方文档\n\n- [新增草稿](https://developers.weixin.qq.com/doc/subscription/api/draftbox/draftmanage/api_draft_add)\n- [发布草稿](https://developers.weixin.qq.com/doc/subscription/api/public/api_freepublish_submit.html)\n- [上传永久素材](https://developers.weixin.qq.com/doc/subscription/api/material/permanent/api_addmaterial.html)\n- [上传正文图片](https://developers.weixin.qq.com/doc/subscription/en/api/material/permanent/api_uploadimage)\n\nFile v1.0.17:references/pre-publish-checklist.md\n\n# 发布前检查清单\n\n在审稿通过后、实际提交前执行，确保可安全发布。\n\n## 检查项\n\n- [ ] 标题、摘要、作者已最终确认\n- [ ] 正文无未替换的占位符或草稿标记\n- [ ] 敏感词与错别字已在审稿中修正\n- [ ] 封面图已就绪（已上传或路径有效）\n- [ ] 正文内图片齐全，图注格式正确\n- [ ] 原创/转载标注已按配置处理\n- [ ] 文末引导区块已就位\n- [ ] 如需开启评论/仅粉丝可评，已确认设置\n\n全部勾选后执行提交步骤。\n\nFile v1.0.17:references/submit-guide.md\n\n# 提交到公众号后台\n\n## 方式一：API 提交（推荐）\n\n使用 `skills/aws-wechat-article-publish/scripts/publish.py`，通过微信公众号 API 完成发布。\n\n### 前置准备\n\n1. 在仓库根 **`aws.env`** 中填写微信槽位（与 `skills/aws-wechat-article-main/references/env.example.yaml` 键名一致），例如单账号：\n   ```env\n   NUMBER_ACCOUNTS=1\n   WECHAT_1_NAME=主号\n   WECHAT_1_APPID=你的AppID\n   WECHAT_1_APPSECRET=你的AppSecret\n   WECHAT_1_API_BASE=\n   ```\n   多账号递增 `WECHAT_2_*` 等；发布前可运行 `python skills/aws-wechat-article-publish/scripts/publish.py check-wechat-env` 检查缺项。\n\n2. 在公众平台「开发 → 基本配置」中将服务器 IP 加入白名单\n\n3. 准备文章目录：\n   ```\n   article/\n   ├── article.yaml    # 标题、作者、摘要等元信息\n   ├── article.html    # 排版后的正文 HTML\n   ├── cover.jpg       # 封面图\n   └── imgs/           # 正文内图片\n   ```\n\n### 一键发布\n\n```bash\n# 创建草稿（不发布，可在后台预览）\npython skills/aws-wechat-article-publish/scripts/publish.py full article/\n\n# 创建草稿并立即发布\npython skills/aws-wechat-article-publish/scripts/publish.py full article/ --publish\n```\n\n### 分步操作\n\n```bash\n# 获取 token\npython skills/aws-wechat-article-publish/scripts/publish.py token\n\n# 上传封面图\npython skills/aws-wechat-article-publish/scripts/publish.py upload-thumb cover.jpg\n\n# 上传正文图片\npython skills/aws-wechat-article-publish/scripts/publish.py upload-content-image imgs/img1.png\n\n# 创建草稿（需要先准备好 article.yaml）\npython skills/aws-wechat-article-publish/scripts/publish.py create-draft article.yaml\n\n# 发布\npython skills/aws-wechat-article-publish/scripts/publish.py publish <media_id>\n\n# 查询状态\npython skills/aws-wechat-article-publish/scripts/publish.py status <publish_id>\n```\n\n接口详情与错误码：[api-reference.md](api-reference.md)\n\n## 方式二：手动提交\n\n1. 登录微信公众平台（mp.weixin.qq.com）\n2. 进入「素材管理」或「草稿箱」→ 新建图文消息\n3. 填写标题、作者、摘要\n4. 将排版后的正文粘贴到正文编辑区\n5. 上传封面图，设置封面\n6. 逐一上传正文内图片并插入对应位置\n7. 设置评论权限（开启/仅粉丝可评）\n8. 保存为草稿或直接群发\n\nFile v1.0.17:references/usage.md\n\n# 发布脚本用法\n\n脚本路径：**`skills/aws-wechat-article-publish/scripts/publish.py`**（在**仓库根**执行）。\n\n- **微信凭证**来自仓库根 **`aws.env`**：`NUMBER_ACCOUNTS`、`WECHAT_1_NAME`、`WECHAT_1_APPID`、`WECHAT_1_APPSECRET`、`WECHAT_1_API_BASE`（1..N 槽位）。`WECHAT_N_API_BASE` 可空（空则官方 `https://api.weixin.qq.com`）。\n- **`publish_method`** 在 **`config.yaml`**：**`draft`**（默认）= **`full`** 只进**草稿箱**；**`published`** = 再**提交发布**；**`none`** = **`full`** **不调接口**（用户不填微信）。**`full --publish`** 可在 **`draft`** 下单次强制发布（**`none`** 下仍跳过）。\n\n## `publish_method` 检查\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py check-screening\npython skills/aws-wechat-article-publish/scripts/publish.py check-screening --config .aws-article/config.yaml\n```\n\n## 微信槽位检查\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py check-wechat-env\npython skills/aws-wechat-article-publish/scripts/publish.py accounts\n```\n\n## 一键全流程\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py full path/to/article-dir/\n\npython skills/aws-wechat-article-publish/scripts/publish.py full path/to/article-dir/ --publish\n\npython skills/aws-wechat-article-publish/scripts/publish.py --account 2 full path/to/article-dir/\n```\n\n## 正式文章读取（`getdraft.py`）\n\n与 **`publish.py` 独立**，用于 **`freepublish/batchget`** / **`freepublish/get`** / **`freepublish/getarticle`**（仓库根执行）：\n\n```bash\npython skills/aws-wechat-article-publish/scripts/getdraft.py published-fields\npython skills/aws-wechat-article-publish/scripts/getdraft.py publish-get <publish_id>\npython skills/aws-wechat-article-publish/scripts/getdraft.py article-get <article_id>\n```\n\n## 分步操作\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py token\npython skills/aws-wechat-article-publish/scripts/publish.py upload-thumb cover.jpg\npython skills/aws-wechat-article-publish/scripts/publish.py upload-content-image img.png\npython skills/aws-wechat-article-publish/scripts/publish.py create-draft path/to/article.yaml\npython skills/aws-wechat-article-publish/scripts/publish.py publish <media_id>\n```\n\nFile v1.0.17:skill.json\n\n{\n  \"name\": \"aws-wechat-article-publish\",\n  \"version\": \"0.4.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"将文章发布到微信公众号，支持 API 发布和手动提交，含发布前检查。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"publish\", \"api\"],\n  \"permissions\": [\"filesystem\", \"network\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}\n\nArchive v1.0.16: 10 files, 30142 bytes\n\nFiles: references/api-reference.md (4153b), references/pre-publish-checklist.md (536b), references/submit-guide.md (2390b), references/usage.md (2293b), scripts/article_init.py (8262b), scripts/getdraft.py (16559b), scripts/publish.py (42311b), skill.json (494b), SKILL.md (10048b), _meta.json (146b)\n\nFile v1.0.16:SKILL.md\n\n---\nname: aws-wechat-article-publish\ndescription: 公众号发布｜微信公众号发布｜公众号草稿箱｜公众号群发｜公众号推送｜图文推送｜微信 API｜WeChat API｜公众号自动发布｜content publishing｜wechat automation — 公众号 API 发布工具，图文入草稿箱或直接群发，支持封面素材上传、发布前检查与 draft/published 模式切换。面向公众号运营、自动化内容团队、开发者。触发词：「发布」「提交」「群发」「推送」「发出去」「上传到公众号」「发到公众号」「可以发了吗」「发布前检查」。\n---\n\n# 发布\n\n**公众号 API 直连发布** —— 图文入草稿箱或直接群发，素材上传、发布前检查一站式完成。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n通过微信公众号 API 将排版稿写入**草稿箱**或再**提交发布**（由 **`config.yaml`** 的 **`publish_method`** 与命令行 **`--publish`** 控制）。\n\n## 配置检查 ⛔\n\n任何操作执行前，**必须**按 **[首次引导](../aws-wechat-article-main/references/first-time-setup.md)** 执行其中的 **「检测顺序」**。检测通过后才能进行以下操作（或用户明确书面确认「本次不检查」）：\n\n## 脚本目录\n\n**Agent 执行**：确定本 SKILL.md 所在目录为 `{baseDir}`。发布子命令在 **`{baseDir}/scripts/publish.py`**（项目根执行）。\n\n| 脚本 / 子命令 | 用途 |\n|--------|------|\n| **`article_init.py`** | 初始化或更新本篇 **`article.yaml`**（及可选 **`closing.md`**）。用于总览 **本篇准备**（建目录后）或 **发布前** 补全元数据。仓库根执行：`python {baseDir}/scripts/article_init.py <文章目录> [--title … --author … --digest …]` |\n| **`getdraft.py`** | 独立于 `publish.py`：用于正式文章查询（`published-list` / `published-fields` / `publish-get` / `article-get`，对应 `freepublish/*`），可用于 `embeds.related_articles.manual` 为空时自动补全推荐链接。注意：`freepublish/*` 需要公众号具备对应接口权限。仓库根：`python {baseDir}/scripts/getdraft.py published-fields` |\n| `check-screening` | 校验 **`config.yaml`** 的 **`publish_method`**（**`draft`** / **`published`** / **`none`**） |\n| `check-wechat-env` | 按 **`config.yaml` 槽位**检查 `aws.env` 的 `WECHAT_N_APPID` / `WECHAT_N_APPSECRET` 是否已填（**调用 `publish.py` 前建议跑**） |\n| `check` | 环境检查：`aws.env`、各槽位、依赖、可选探测 token |\n| `accounts` | 列出 **`config.yaml`** 中各微信槽位名称，并标记 `aws.env` 凭证缺项 |\n| `full` / `token` / … | 调微信 API（需 **`aws.env`** 微信凭证） |\n\n## 凭证与 `publish_method` ⛔\n\n### `publish_method`（以仓库 **`config.yaml`** 为准）\n\n| 值 | 含义 | 行为 |\n|----|------|------|\n| **`draft`**（默认） | 只进公众号**草稿箱** | **`full`** 创建草稿后**不**调用 freepublish 提交发布。 |\n| **`published`** | 草稿 + **提交发布** | **`full`** 创建草稿后继续提交发布（异步）。**`full --publish`** 可**单次强制**带发布，即使当前为 **`draft`**。 |\n| **`none`** | 用户明确不填微信 | **`full`** **立即退出**，不调任何微信接口（**`--publish`** 也会被忽略）。其它子命令（`token` 等）仍要凭证。 |\n\n### 多账号时如何选槽位\n\n1. 运行 **`python {baseDir}/scripts/publish.py accounts`**，从 **`config.yaml` 的 `wechat_accounts` + `wechat_N_name`** 向用户展示列表（例如：`您有2个账号：1.\"xiaoming\"，2.\"xiaoz\"`）必须询问用户选择哪个账号发布到草稿箱，然后根据用户选择发布到指定的账号。\n2. 在 **`config.yaml`** 写 **`wechat_publish_slot: <整数>`**，**或**命令行 **`--account <序号或名称>`**（**CLI 优先**，见 [articlescreening-schema.md](../aws-wechat-article-main/references/articlescreening-schema.md)）。\n\n### 全局环境\n\n在仓库根具备 **`aws.env`**（微信密钥）与 **`config.yaml`**（微信槽位数量与名称）。写作/生图见 **`validate_env.py`**（微信未齐仍可先做内容）。**`publish_method: none`** 时 **`full`** 会跳过；**`draft`/`published`** 发布前建议 **`check-wechat-env`**。API 端点优先取 **`WECHAT_N_API_BASE`**，若槽位未配则回退 **`config.yaml.wechat_api_base`**（两者都空时使用官方）。\n\n### 作者名回退\n\n`full` / `create-draft` 若 **`article.yaml` 无 author**，回退 **`config.yaml`** 的 **`default_author`**。\n\n### `publish_completed`（本篇是否已发布完成）\n\n- 字段在**本篇** **`article.yaml`**。**`publish.py` 不读、不改**；由智能体维护。\n- **`false`**：发布流程未闭环。\n- **`true`**：已视为发布完成（草稿已确认 / 或 **`published`** 流程成功且运营确认）。\n\n**本篇发布真正结束后**：将 **`publish_completed: true`** 写回 **`article.yaml`**。\n\n**写回 `true` 的前置门禁（缺啥补啥）**：\n\n1. `article.html` 存在；\n2. 文章目录存在封面图 `cover.(png/jpg/jpeg/webp)`；\n3. `article.md` 与 `article.html` 中均不含 `placeholder`；\n4. 发布命令成功并拿到回执（`media_id` 或 `publish_id`）。\n\n任一不满足：只可标记为“已提交草稿，未闭环”，**不得**写回 `publish_completed: true`。\n\n## 用户仅说「发布」且未明确路径时 ⛔\n\n在用户**未给出** `drafts/…` 路径、仅说「发布文章」「帮我发一下」等时：\n\n1. **确定本篇目录**：列出仓库下 **`drafts/`** 中子目录；若**多篇**，请用户**指定一篇**或选「最新修改」的一篇再读该目录 **`article.yaml`**。**勿**在未确认目录时假定路径。\n2. 读取该目录 **`article.yaml`** 中的 **`publish_completed`**（YAML 布尔：`true` / `false`；**缺省按 `false` 处理**）。\n\n| `publish_completed` | 智能体对用户说明（可略作口语化，勿改含义） |\n|---------------------|---------------------------------------------|\n| **`true`** | 告知：**项目里本篇文档已按记录成功发布**；问：**您是否需要编写新文章？** 若需要 → 转交 [main](../aws-wechat-article-main/SKILL.md) / [writing](../aws-wechat-article-writing/SKILL.md) 从本篇准备或选题起走。 |\n| **`false`** 或缺省 | 读取 **`article.yaml`** 的 **`title`**（若无则用目录名简述），说明：**《{title}》尚未执行完成（发布流程未闭环）**；问：**是否需要继续并完成发布？** 或 **编写新文章？** 若继续本篇 → 再核对 **`config.yaml`** 的 **`publish_method`**、**`check-screening`**、**`check-wechat-env`** 等。 |\n\n## 工作流\n\n```\n发布进度：\n- [ ] 前置：配置检查（见本节「配置检查」）⛔\n- [ ] 第0步：若用户未给路径 → 选本篇目录 → 读 publish_completed → 按上表分流（true/false）\n- [ ] 第1步：读 **`config.yaml`** → **`draft` / `published`**（及是否 **`full --publish`**）\n- [ ] 第2步：读取 **`config.yaml`** 的 `wechat_accounts` + `wechat_N_name` 向用户展示账号列表并询问目标槽位；随后跑 **`check-wechat-env`** 校验 `aws.env` 凭证 → **`wechat_publish_slot` 或 `--account`**\n- [ ] 第3步：发布前检查（checklist + **`check-screening`** + **`check`**）\n- [ ] 第4步：准备文章目录\n- [ ] 第5步：**`full`**（仅草稿或含发布，视上步）\n- [ ] 第6步：确认结果与用户说明\n- [ ] 第7步：成功后写回 **`article.yaml`** 的 **`publish_completed: true`**；按需归档\n```\n\n## 交互顺序（最小提问）\n\n0) **未给路径时**：先按上文 **「用户仅说发布」** 处理 **`publish_completed`**；用户选 **继续本篇** 后再做下列步骤。  \n1) **先看 `config.yaml` 的 `publish_method`**：**`draft`** = 默认只进草稿箱；**`published`** 或 **`full --publish`** = 再提交发布。  \n2) **多槽位**：展示账号列表（来源：`config.yaml` 的 `wechat_accounts` + `wechat_N_name`），**必须请用户选槽位** → **`wechat_publish_slot`** 或 **`--account`**。  \n3) 缺微信字段：运行 **`check-wechat-env`**，补全 **`aws.env`** 后再发。  \n4) **发布失败**（由脚本 stderr / 微信 errcode 判断）：  \n   - **网络类**（超时、连接失败、5xx）：脚本已对单次请求 **自动重试 1 次**；仍失败 → 告知「网络不可用，请稍后重试或检查代理」。  \n   - **凭证/配置类**（如 token 失败带 errcode、缺字段）→ 提示 **第几槽位**、检查 **APPID/SECRET、IP 白名单**，用户改正后再执行 **`full`** / **`publish`**。\n5) **中间产物缺失**（封面缺失 / 存在 `placeholder`）：先补产物再发；若用户坚持先发草稿，必须明确告知“正文配图未完成”，且保持 `publish_completed: false`。\n\n## 命令示例（仓库根）\n\n```bash\npython {baseDir}/scripts/publish.py check-screening\npython {baseDir}/scripts/publish.py check-wechat-env\npython {baseDir}/scripts/publish.py accounts\npython {baseDir}/scripts/publish.py check\npython {baseDir}/scripts/publish.py --account 1 full drafts/YYYYMMDD-标题slug/\npython {baseDir}/scripts/getdraft.py published-fields\n```\n\n详见 [references/usage.md](references/usage.md)、[references/submit-guide.md](references/submit-guide.md)、[references/api-reference.md](references/api-reference.md)。\n\n## 过程文件\n\n| 读取 | 产出 |\n|------|------|\n| `article.html`、`imgs/`、**`article.yaml`**（含 **`publish_completed`** 等）、**`.aws-article/config.yaml`**、**`aws.env`**（微信槽位） | 发布到公众号草稿或提交发布；**成功后**由智能体将 **`publish_completed: true`** 写回 **`article.yaml`**（`publish.py` 不改此键） |\n\nFile v1.0.16:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-publish\",\n  \"version\": \"1.0.16\",\n  \"publishedAt\": 1776834817887\n}\n\nFile v1.0.16:references/api-reference.md\n\n# 微信公众号 API 参考\n\n## 接口一览\n\n| 接口 | 方法 | 路径 | 用途 |\n|------|------|------|------|\n| 获取 token | GET | `/token` | 获取 access_token |\n| 上传永久素材 | POST | `/material/add_material` | 上传封面图，返回 media_id |\n| 上传正文图片 | POST | `/media/uploadimg` | 上传正文内图片，返回 URL |\n| 新增草稿 | POST | `/draft/add` | 创建图文草稿 |\n| 发布草稿 | POST | `/freepublish/submit` | 发布草稿（异步） |\n| 查询发布状态 | POST | `/freepublish/get` | 查询发布结果 |\n\n所有接口基础 URL：`https://api.weixin.qq.com/cgi-bin`\n\n## 获取 access_token\n\n```\nGET /token?grant_type=client_credential&appid={APPID}&secret={APPSECRET}\n```\n\n返回：\n```json\n{\"access_token\": \"...\", \"expires_in\": 7200}\n```\n\n有效期 2 小时，需缓存复用，避免频繁请求。\n\n## 上传封面图（永久素材）\n\n```\nPOST /material/add_material?access_token={TOKEN}&type=image\nContent-Type: multipart/form-data\n```\n\n- 字段名：`media`\n- 限制：10MB，支持 bmp/png/jpeg/jpg/gif\n- 永久素材上限：100,000 张\n\n返回：\n```json\n{\"media_id\": \"...\", \"url\": \"...\"}\n```\n\n`media_id` 用于 `draft/add` 的 `thumb_media_id` 字段。\n\n## 上传正文图片\n\n```\nPOST /media/uploadimg?access_token={TOKEN}\nContent-Type: multipart/form-data\n```\n\n- 字段名：`media`\n- 限制：1MB，支持 jpg/png\n- 不占用素材库配额\n- 返回的 URL 可直接在正文 HTML 中使用\n\n返回：\n```json\n{\"url\": \"https://mmbiz.qpic.cn/...\"}\n```\n\n## 新增草稿\n\n```\nPOST /draft/add?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\n  \"articles\": [{\n    \"title\": \"标题（≤32字）\",\n    \"author\": \"作者（≤16字）\",\n    \"digest\": \"摘要（≤128字，仅单图文）\",\n    \"content\": \"HTML 正文（≤2万字符，图片 URL 必须来自 uploadimg）\",\n    \"thumb_media_id\": \"封面图 media_id\",\n    \"content_source_url\": \"原文链接\",\n    \"need_open_comment\": 1,\n    \"only_fans_can_comment\": 0\n  }]\n}\n```\n\n返回：\n```json\n{\"media_id\": \"...\"}\n```\n\n## 发布草稿\n\n```\nPOST /freepublish/submit?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\"media_id\": \"草稿的 media_id\"}\n```\n\n返回：\n```json\n{\"publish_id\": \"...\", \"msg_data_id\": \"...\"}\n```\n\n**注意**：发布为异步操作，返回成功仅表示任务提交成功。\n\n## 查询发布状态\n\n```\nPOST /freepublish/get?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\"publish_id\": \"...\"}\n```\n\n返回 `publish_status`：\n\n| 值 | 含义 |\n|----|------|\n| 0 | 发布成功 |\n| 1 | 发布中 |\n| 2 | 原创失败 |\n| 3 | 常规失败 |\n| 4 | 平台审核不通过 |\n| 5 | 已删除 |\n| 6 | 已封禁 |\n\n## 常见错误码\n\n| 错误码 | 含义 | 处理 |\n|--------|------|------|\n| 40001 | access_token 无效 | 重新获取 token |\n| 40004 | 不合法的媒体文件类型 | 检查图片格式 |\n| 40009 | 图片大小超限 | 封面 ≤10MB，正文图 ≤1MB |\n| 45009 | API 调用超限 | 等待后重试 |\n| 45028 | 接口无权限 | 检查公众号类型和权限 |\n| 48001 | API 未授权 | 检查公众号开发者设置 |\n\n## 凭证配置\n\n在仓库根 **`aws.env`** 中配置微信槽位（勿提交含真密钥的文件）：\n\n```env\nNUMBER_ACCOUNTS=1\nWECHAT_1_NAME=主号\nWECHAT_1_APPID=你的AppID\nWECHAT_1_APPSECRET=你的AppSecret\nWECHAT_1_API_BASE=\n```\n\n键名与 `skills/aws-wechat-article-main/references/env.example.yaml` 一致。多账号递增 `WECHAT_2_*` 等。\n\n## 权限要求\n\n- 需要已认证的服务号或订阅号\n- AppID 和 AppSecret 在「开发 → 基本配置」获取\n- 调用服务器 IP 需加入白名单\n\n## 官方文档\n\n- [新增草稿](https://developers.weixin.qq.com/doc/subscription/api/draftbox/draftmanage/api_draft_add)\n- [发布草稿](https://developers.weixin.qq.com/doc/subscription/api/public/api_freepublish_submit.html)\n- [上传永久素材](https://developers.weixin.qq.com/doc/subscription/api/material/permanent/api_addmaterial.html)\n- [上传正文图片](https://developers.weixin.qq.com/doc/subscription/en/api/material/permanent/api_uploadimage)\n\nFile v1.0.16:references/pre-publish-checklist.md\n\n# 发布前检查清单\n\n在审稿通过后、实际提交前执行，确保可安全发布。\n\n## 检查项\n\n- [ ] 标题、摘要、作者已最终确认\n- [ ] 正文无未替换的占位符或草稿标记\n- [ ] 敏感词与错别字已在审稿中修正\n- [ ] 封面图已就绪（已上传或路径有效）\n- [ ] 正文内图片齐全，图注格式正确\n- [ ] 原创/转载标注已按配置处理\n- [ ] 文末引导区块已就位\n- [ ] 如需开启评论/仅粉丝可评，已确认设置\n\n全部勾选后执行提交步骤。\n\nFile v1.0.16:references/submit-guide.md\n\n# 提交到公众号后台\n\n## 方式一：API 提交（推荐）\n\n使用 `skills/aws-wechat-article-publish/scripts/publish.py`，通过微信公众号 API 完成发布。\n\n### 前置准备\n\n1. 在仓库根 **`aws.env`** 中填写微信槽位（与 `skills/aws-wechat-article-main/references/env.example.yaml` 键名一致），例如单账号：\n   ```env\n   NUMBER_ACCOUNTS=1\n   WECHAT_1_NAME=主号\n   WECHAT_1_APPID=你的AppID\n   WECHAT_1_APPSECRET=你的AppSecret\n   WECHAT_1_API_BASE=\n   ```\n   多账号递增 `WECHAT_2_*` 等；发布前可运行 `python skills/aws-wechat-article-publish/scripts/publish.py check-wechat-env` 检查缺项。\n\n2. 在公众平台「开发 → 基本配置」中将服务器 IP 加入白名单\n\n3. 准备文章目录：\n   ```\n   article/\n   ├── article.yaml    # 标题、作者、摘要等元信息\n   ├── article.html    # 排版后的正文 HTML\n   ├── cover.jpg       # 封面图\n   └── imgs/           # 正文内图片\n   ```\n\n### 一键发布\n\n```bash\n# 创建草稿（不发布，可在后台预览）\npython skills/aws-wechat-article-publish/scripts/publish.py full article/\n\n# 创建草稿并立即发布\npython skills/aws-wechat-article-publish/scripts/publish.py full article/ --publish\n```\n\n### 分步操作\n\n```bash\n# 获取 token\npython skills/aws-wechat-article-publish/scripts/publish.py token\n\n# 上传封面图\npython skills/aws-wechat-article-publish/scripts/publish.py upload-thumb cover.jpg\n\n# 上传正文图片\npython skills/aws-wechat-article-publish/scripts/publish.py upload-content-image imgs/img1.png\n\n# 创建草稿（需要先准备好 article.yaml）\npython skills/aws-wechat-article-publish/scripts/publish.py create-draft article.yaml\n\n# 发布\npython skills/aws-wechat-article-publish/scripts/publish.py publish <media_id>\n\n# 查询状态\npython skills/aws-wechat-article-publish/scripts/publish.py status <publish_id>\n```\n\n接口详情与错误码：[api-reference.md](api-reference.md)\n\n## 方式二：手动提交\n\n1. 登录微信公众平台（mp.weixin.qq.com）\n2. 进入「素材管理」或「草稿箱」→ 新建图文消息\n3. 填写标题、作者、摘要\n4. 将排版后的正文粘贴到正文编辑区\n5. 上传封面图，设置封面\n6. 逐一上传正文内图片并插入对应位置\n7. 设置评论权限（开启/仅粉丝可评）\n8. 保存为草稿或直接群发\n\nFile v1.0.16:references/usage.md\n\n# 发布脚本用法\n\n脚本路径：**`skills/aws-wechat-article-publish/scripts/publish.py`**（在**仓库根**执行）。\n\n- **微信凭证**来自仓库根 **`aws.env`**：`NUMBER_ACCOUNTS`、`WECHAT_1_NAME`、`WECHAT_1_APPID`、`WECHAT_1_APPSECRET`、`WECHAT_1_API_BASE`（1..N 槽位）。`WECHAT_N_API_BASE` 可空（空则官方 `https://api.weixin.qq.com`）。\n- **`publish_method`** 在 **`config.yaml`**：**`draft`**（默认）= **`full`** 只进**草稿箱**；**`published`** = 再**提交发布**；**`none`** = **`full`** **不调接口**（用户不填微信）。**`full --publish`** 可在 **`draft`** 下单次强制发布（**`none`** 下仍跳过）。\n\n## `publish_method` 检查\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py check-screening\npython skills/aws-wechat-article-publish/scripts/publish.py check-screening --config .aws-article/config.yaml\n```\n\n## 微信槽位检查\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py check-wechat-env\npython skills/aws-wechat-article-publish/scripts/publish.py accounts\n```\n\n## 一键全流程\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py full path/to/article-dir/\n\npython skills/aws-wechat-article-publish/scripts/publish.py full path/to/article-dir/ --publish\n\npython skills/aws-wechat-article-publish/scripts/publish.py --account 2 full path/to/article-dir/\n```\n\n## 正式文章读取（`getdraft.py`）\n\n与 **`publish.py` 独立**，用于 **`freepublish/batchget`** / **`freepublish/get`** / **`freepublish/getarticle`**（仓库根执行）：\n\n```bash\npython skills/aws-wechat-article-publish/scripts/getdraft.py published-fields\npython skills/aws-wechat-article-publish/scripts/getdraft.py publish-get <publish_id>\npython skills/aws-wechat-article-publish/scripts/getdraft.py article-get <article_id>\n```\n\n## 分步操作\n\n```bash\npython skills/aws-wechat-article-publish/scripts/publish.py token\npython skills/aws-wechat-article-publish/scripts/publish.py upload-thumb cover.jpg\npython skills/aws-wechat-article-publish/scripts/publish.py upload-content-image img.png\npython skills/aws-wechat-article-publish/scripts/publish.py create-draft path/to/article.yaml\npython skills/aws-wechat-article-publish/scripts/publish.py publish <media_id>\n```\n\nFile v1.0.16:skill.json\n\n{\n  \"name\": \"aws-wechat-article-publish\",\n  \"version\": \"0.4.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"将文章发布到微信公众号，支持 API 发布和手动提交，含发布前检查。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"publish\", \"api\"],\n  \"permissions\": [\"filesystem\", \"network\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}\n\nArchive v1.0.15: 10 files, 30176 bytes\n\nFiles: references/api-reference.md (4153b), references/pre-publish-checklist.md (536b), references/submit-guide.md (2390b), references/usage.md (2293b), scripts/article_init.py (8262b), scripts/getdraft.py (16559b), scripts/publish.py (42311b), skill.json (494b), SKILL.md (10107b), _meta.json (146b)\n\nFile v1.0.15:SKILL.md\n\n---\nname: aws-wechat-article-publish\ndescription: 微信公众号 API 发布工具：把排版后的图文写入公众号草稿箱或直接群发，支持封面素材上传、发布前检查与 publish_method（draft/published）切换。面向公众号运营、自动化内容团队、开发者。关键词：公众号发布 / 微信 API / WeChat API / 草稿箱 / 群发 / content publishing / automation。将文章发布到微信公众号（API 写入草稿箱或提交发布），含发布前检查。当用户提到「发布」「提交」「群发」「推送」「发出去」「上传到公众号」「发到公众号」「可以发了吗」「发布前检查」时使用。\n---\n\n# 发布\n\n**公众号 API 直连发布** —— 图文入草稿箱或直接群发，素材上传、发布前检查一站式完成。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n通过微信公众号 API 将排版稿写入**草稿箱**或再**提交发布**（由 **`config.yaml`** 的 **`publish_method`** 与命令行 **`--publish`** 控制）。\n\n## 配置检查 ⛔\n\n任何操作执行前，**必须**按 **[首次引导](../aws-wechat-article-main/references/first-time-setup.md)** 执行其中的 **「检测顺序」**。检测通过后才能进行以下操作（或用户明确书面确认「本次不检查」）：\n\n## 脚本目录\n\n**Agent 执行**：确定本 SKILL.md 所在目录为 `{baseDir}`。发布子命令在 **`{baseDir}/scripts/publish.py`**（项目根执行）。\n\n| 脚本 / 子命令 | 用途 |\n|--------|------|\n| **`article_init.py`** | 初始化或更新本篇 **`article.yaml`**（及可选 **`closing.md`**）。用于总览 **本篇准备**（建目录后）或 **发布前** 补全元数据。仓库根执行：`python {baseDir}/scripts/article_init.py <文章目录> [--title … --author … --digest …]` |\n| **`getdraft.py`** | 独立于 `publish.py`：用于正式文章查询（`published-list` / `published-fields` / `publish-get` / `article-get`，对应 `freepublish/*`），可用于 `embeds.related_articles.manual` 为空时自动补全推荐链接。注意：`freepublish/*` 需要公众号具备对应接口权限。仓库根：`python {baseDir}/scripts/getdraft.py published-fields` |\n| `check-screening` | 校验 **`config.yaml`** 的 **`publish_method`**（**`draft`** / **`published`** / **`none`**） |\n| `check-wechat-env` | 按 **`config.yaml` 槽位**检查 `aws.env` 的 `WECHAT_N_APPID` / `WECHAT_N_APPSECRET` 是否已填（**调用 `publish.py` 前建议跑**） |\n| `check` | 环境检查：`aws.env`、各槽位、依赖、可选探测 token |\n| `accounts` | 列出 **`config.yaml`** 中各微信槽位名称，并标记 `aws.env` 凭证缺项 |\n| `full` / `token` / … | 调微信 API（需 **`aws.env`** 微信凭证） |\n\n## 凭证与 `publish_method` ⛔\n\n### `publish_method`（以仓库 **`config.yaml`** 为准）\n\n| 值 | 含义 | 行为 |\n|----|------|------|\n| **`draft`**（默认） | 只进公众号**草稿箱** | **`full`** 创建草稿后**不**调用 freepublish 提交发布。 |\n| **`published`** | 草稿 + **提交发布** | **`full`** 创建草稿后继续提交发布（异步）。**`full --publish`** 可**单次强制**带发布，即使当前为 **`draft`**。 |\n| **`none`** | 用户明确不填微信 | **`full`** **立即退出**，不调任何微信接口（**`--publish`** 也会被忽略）。其它子命令（`token` 等）仍要凭证。 |\n\n### 多账号时如何选槽位\n\n1. 运行 **`python {baseDir}/scripts/publish.py accounts`**，从 **`config.yaml` 的 `wechat_accounts` + `wechat_N_name`** 向用户展示列表（例如：`您有2个账号：1.\"xiaoming\"，2.\"xiaoz\"`）必须询问用户选择哪个账号发布到草稿箱，然后根据用户选择发布到指定的账号。\n2. 在 **`config.yaml`** 写 **`wechat_publish_slot: <整数>`**，**或**命令行 **`--account <序号或名称>`**（**CLI 优先**，见 [articlescreening-schema.md](../aws-wechat-article-main/references/articlescreening-schema.md)）。\n\n### 全局环境\n\n在仓库根具备 **`aws.env`**（微信密钥）与 **`config.yaml`**（微信槽位数量与名称）。写作/生图见 **`validate_env.py`**（微信未齐仍可先做内容）。**`publish_method: none`** 时 **`full`** 会跳过；**`draft`/`published`** 发布前建议 **`check-wechat-env`**。API 端点优先取 **`WECHAT_N_API_BASE`**，若槽位未配则回退 **`config.yaml.wechat_api_base`**（两者都空时使用官方）。\n\n### 作者名回退\n\n`full` / `create-draft` 若 **`article.yaml` 无 author**，回退 **`config.yaml`** 的 **`default_author`**。\n\n### `publish_completed`（本篇是否已发布完成）\n\n- 字段在**本篇** **`article.yaml`**。**`publish.py` 不读、不改**；由智能体维护。\n- **`false`**：发布流程未闭环。\n- **`true`**：已视为发布完成（草稿已确认 / 或 **`published`** 流程成功且运营确认）。\n\n**本篇发布真正结束后**：将 **`publish_completed: true`** 写回 **`article.yaml`**。\n\n**写回 `true` 的前置门禁（缺啥补啥）**：\n\n1. `article.html` 存在；\n2. 文章目录存在封面图 `cover.(png/jpg/jpeg/webp)`；\n3. `article.md` 与 `article.html` 中均不含 `placeholder`；\n4. 发布命令成功并拿到回执（`media_id` 或 `publish_id`）。\n\n任一不满足：只可标记为“已提交草稿，未闭环”，**不得**写回 `publish_completed: true`。\n\n## 用户仅说「发布」且未明确路径时 ⛔\n\n在用户**未给出** `drafts/…` 路径、仅说「发布文章」「帮我发一下」等时：\n\n1. **确定本篇目录**：列出仓库下 **`drafts/`** 中子目录；若**多篇**，请用户**指定一篇**或选「最新修改」的一篇再读该目录 **`article.yaml`**。**勿**在未确认目录时假定路径。\n2. 读取该目录 **`article.yaml`** 中的 **`publish_completed`**（YAML 布尔：`true` / `false`；**缺省按 `false` 处理**）。\n\n| `publish_completed` | 智能体对用户说明（可略作口语化，勿改含义） |\n|---------------------|---------------------------------------------|\n| **`true`** | 告知：**项目里本篇文档已按记录成功发布**；问：**您是否需要编写新文章？** 若需要 → 转交 [main](../aws-wechat-article-main/SKILL.md) / [writing](../aws-wechat-article-writing/SKILL.md) 从本篇准备或选题起走。 |\n| **`false`** 或缺省 | 读取 **`article.yaml`** 的 **`title`**（若无则用目录名简述），说明：**《{title}》尚未执行完成（发布流程未闭环）**；问：**是否需要继续并完成发布？** 或 **编写新文章？** 若继续本篇 → 再核对 **`config.yaml`** 的 **`publish_method`**、**`check-screening`**、**`check-wechat-env`** 等。 |\n\n## 工作流\n\n```\n发布进度：\n- [ ] 前置：配置检查（见本节「配置检查」）⛔\n- [ ] 第0步：若用户未给路径 → 选本篇目录 → 读 publish_completed → 按上表分流（true/false）\n- [ ] 第1步：读 **`config.yaml`** → **`draft` / `published`**（及是否 **`full --publish`**）\n- [ ] 第2步：读取 **`config.yaml`** 的 `wechat_accounts` + `wechat_N_name` 向用户展示账号列表并询问目标槽位；随后跑 **`check-wechat-env`** 校验 `aws.env` 凭证 → **`wechat_publish_slot` 或 `--account`**\n- [ ] 第3步：发布前检查（checklist + **`check-screening`** + **`check`**）\n- [ ] 第4步：准备文章目录\n- [ ] 第5步：**`full`**（仅草稿或含发布，视上步）\n- [ ] 第6步：确认结果与用户说明\n- [ ] 第7步：成功后写回 **`article.yaml`** 的 **`publish_completed: true`**；按需归档\n```\n\n## 交互顺序（最小提问）\n\n0) **未给路径时**：先按上文 **「用户仅说发布」** 处理 **`publish_completed`**；用户选 **继续本篇** 后再做下列步骤。  \n1) **先看 `config.yaml` 的 `publish_method`**：**`draft`** = 默认只进草稿箱；**`published`** 或 **`full --publish`** = 再提交发布。  \n2) **多槽位**：展示账号列表（来源：`config.yaml` 的 `wechat_accounts` + `wechat_N_name`），**必须请用户选槽位** → **`wechat_publish_slot`** 或 **`--account`**。  \n3) 缺微信字段：运行 **`check-wechat-env`**，补全 **`aws.env`** 后再发。  \n4) **发布失败**（由脚本 stderr / 微信 errcode 判断）：  \n   - **网络类**（超时、连接失败、5xx）：脚本已对单次请求 **自动重试 1 次**；仍失败 → 告知「网络不可用，请稍后重试或检查代理」。  \n   - **凭证/配置类**（如 token 失败带 errcode、缺字段）→ 提示 **第几槽位**、检查 **APPID/\n\nArchive v1.0.14: 10 files, 29940 bytes\n\nFiles: references/api-reference.md (4153b), references/pre-publish-checklist.md (536b), references/submit-guide.md (2390b), references/usage.md (2293b), scripts/article_init.py (8262b), scripts/getdraft.py (16559b), scripts/publish.py (42311b), skill.json (494b), SKILL.md (9560b), _meta.json (146b)","readmeExcerpt":"Skill: aws-wechat-article-publish Owner: aiworkskills Summary: 公众号发布｜公众号草稿箱｜公众号群发｜图文推送｜微信 API｜wechat automation｜WeChat API automation｜auto publish｜scheduled publish — 公众号 API 发布工具，图文入草稿箱或直接群发，支持封面素材上传、发布前检查与 draft/published 模式切换。面向公众号运营、自动化内容团队、开发者。触发词：「发布」「提交」「群发」「推送」「发出去」「上传到公众号」「发到公众号」「可以发了吗」「发布前检查」。需要多环节串联（写+审+排+配图+发）请走 aws-wechat-article-main。 Tags: api:1.0.17, automation:1.0.17, chinese:1.0.17, claude-code:1.0.","codeSnippets":[],"executableExamples":[{"language":"text","snippet":"发布进度：\n- [ ] 前置：配置检查（见本节「配置检查」）⛔\n- [ ] 第0步：若用户未给路径 → 选本篇目录 → 读 publish_completed → 按上表分流（true/false）\n- [ ] 第1步：读 **`config.yaml`** → **`draft` / `published`**（及是否 **`full --publish`**）\n- [ ] 第2步：读取 **`config.yaml`** 的 `wechat_accounts` + `wechat_N_name` 向用户展示账号列表并询问目标槽位；随后跑 **`check-wechat-env`** 校验 `aws.env` 凭证 → **`wechat_publish_slot` 或 `--account`**\n- [ ] 第3步：发布前检查（checklist + **`check-screening`** + **`check`**）\n- [ ] 第4步：准备文章目录\n- [ ] 第5步：**`full`**（仅草稿或含发布，视上步）\n- [ ] 第6步：确认结果与用户说明\n- [ ] 第7步：成功后写回 **`article.yaml`** 的 **`publish_completed: true`**；按需归档"},{"language":"bash","snippet":"{python} {baseDir}/scripts/publish.py check-screening\n{python} {baseDir}/scripts/publish.py check-wechat-env\n{python} {baseDir}/scripts/publish.py accounts\n{python} {baseDir}/scripts/publish.py check\n{python} {baseDir}/scripts/publish.py --account 1 full drafts/YYYYMMDD-标题slug/\n{python} {baseDir}/scripts/getdraft.py published-fields"},{"language":"text","snippet":"GET /token?grant_type=client_credential&appid={APPID}&secret={APPSECRET}"},{"language":"json","snippet":"{\"access_token\": \"...\", \"expires_in\": 7200}"},{"language":"text","snippet":"POST /material/add_material?access_token={TOKEN}&type=image\nContent-Type: multipart/form-data"},{"language":"json","snippet":"{\"media_id\": \"...\", \"url\": \"...\"}"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: aws-wechat-article-publish\ndescription: 公众号发布｜公众号草稿箱｜公众号群发｜图文推送｜微信 API｜wechat automation｜WeChat API automation｜auto publish｜scheduled publish — 公众号 API 发布工具，图文入草稿箱或直接群发，支持封面素材上传、发布前检查与 draft/published 模式切换。面向公众号运营、自动化内容团队、开发者。触发词：「发布」「提交」「群发」「推送」「发出去」「上传到公众号」「发到公众号」「可以发了吗」「发布前检查」。需要多环节串联（写+审+排+配图+发）请走 aws-wechat-article-main。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env:\n        - WECHAT_1_APPID\n        - WECHAT_1_APPSECRET\n      bins:\n        - python3\n    primaryEnv: aws.env\n---\n\n# 发布\n\n**公众号 API 直连发布** —— 图文入草稿箱或直接群发，素材上传、发布前检查一站式完成。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 调 `publish.py` **直连微信公众号官方 API** 发布图文。**会把本篇 `article.html` 与 `imgs/*` 文件作为 POST body 上传到微信服务器。** 具体行为：\n\n- **凭证读取**：`aws.env` 的 `WECHAT_{N}_APPID` / `WECHAT_{N}_APPSECRET`（多槽位支持 N≥1）\n- **凭证外发**：`APPID` / `APPSECRET` 以 query string 形式发给 `api.weixin.qq.com/cgi-bin/token` 换 `access_token`；后续请求带 `access_token` query string。微信返回的 `access_token` 在进程内存短期缓存，**不落盘**\n- **内容外发**：本篇封面、正文插图以 multipart upload 发给 `material/add_material`；`article.html` 正文与标题/摘要以 JSON POST 发给 `draft/add`、`freepublish/submit`\n- **网络目标**：默认 `api.weixin.qq.com`；用户可在 `WECHAT_{N}_API_BASE` / `config.yaml.wechat_api_base` 自配反代\n- **文件读**：仓库内 `.aws-article/config.yaml`、`aws.env`、本篇 `article.yaml`、`article.html`、`imgs/*`\n- **文件写**：仅本篇 `article.yaml` 的状态字段（`media_id`、`publish_id`、`publish_completed`）\n- **shell**：仅 `{python} {baseDir}/scripts/publish.py`、`getdraft.py`、`article_init.py`（`{python}` = 本机 Python 3 解释器，见 [main SKILL 第 0 步](../aws-wechat-article-main/SKILL.md)：Windows 用 `py -3 -X utf8`，macOS / Linux 用 `python3`）\n\n**建议**：首次运行用 `publish_method: draft` 只入草稿箱确认效果，再切 `published` 真正群发。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的**发布环节**（入口 `aws-wechat-article-main`）。工作流中的若干步骤会读取同级 `../aws-wechat-article-main/references/*.md` 等共享文档（首次引导、articlescreening schema、env/config 示例等）。\n\n- **套件完整装齐到同一 `skills/` 根目录**时，跨 skill 引用都能读到。\n- **单独安装本 skill** 时，跨 skill 引用的步骤会在读取阶段遇到 `file not found`；但 `publish.py`、`getdraft.py`、`article_init.py` 这几个脚本本身可独立运行（只要 `aws.env` 与 `.aws-article/config.yaml` 就绪）。\n\n完整 9 slug 清单见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n通过微信公众号 API 将排版稿写入**草稿箱**或再**提交发布**（由 **`config.yaml`** 的 **`publish_method`** 与命令行 **`--publish`** 控制）。\n\n## 配置检查 ⛔\n\n任何操作执行前，**必须**按 **[首次引导](../aws-wechat-article-main/references/first-time-setup.md)** 执行其中的 **「检测顺序」**。检测通过后才能进行以下操作（或用户明确书面确认「本次不检查」）：\n\n## 脚本目录\n\n**Agent 执行**：确定本 SKILL.md 所在目录为 `{baseDir}`。发布子命令在 **`{baseDir}/scripts/publish.py`**（项目根执行）。\n\n| 脚本 / 子命令 | 用途 |\n|--------|------|\n| **`article_init.py`** | 初始化或更新本篇 **`article.yaml`**（及可选 **`closing.md`**）。用于总览 **本篇准备**（建目录后）或 **发布前** 补全元数据。仓库根执行：`{python} {baseDir}/scr"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-publish\",\n  \"version\": \"1.0.24\",\n  \"publishedAt\": 1788797242027\n}"},{"path":"references/api-reference.md","content":"# 微信公众号 API 参考\n\n## 接口一览\n\n| 接口 | 方法 | 路径 | 用途 |\n|------|------|------|------|\n| 获取 token | GET | `/token` | 获取 access_token |\n| 上传永久素材 | POST | `/material/add_material` | 上传封面图，返回 media_id |\n| 上传正文图片 | POST | `/media/uploadimg` | 上传正文内图片，返回 URL |\n| 新增草稿 | POST | `/draft/add` | 创建图文草稿 |\n| 发布草稿 | POST | `/freepublish/submit` | 发布草稿（异步） |\n| 查询发布状态 | POST | `/freepublish/get` | 查询发布结果 |\n\n所有接口基础 URL：`https://api.weixin.qq.com/cgi-bin`\n\n## 获取 access_token\n\n```\nGET /token?grant_type=client_credential&appid={APPID}&secret={APPSECRET}\n```\n\n返回：\n```json\n{\"access_token\": \"...\", \"expires_in\": 7200}\n```\n\n有效期 2 小时，需缓存复用，避免频繁请求。\n\n## 上传封面图（永久素材）\n\n```\nPOST /material/add_material?access_token={TOKEN}&type=image\nContent-Type: multipart/form-data\n```\n\n- 字段名：`media`\n- 限制：10MB，支持 bmp/png/jpeg/jpg/gif\n- 永久素材上限：100,000 张\n\n返回：\n```json\n{\"media_id\": \"...\", \"url\": \"...\"}\n```\n\n`media_id` 用于 `draft/add` 的 `thumb_media_id` 字段。\n\n## 上传正文图片\n\n```\nPOST /media/uploadimg?access_token={TOKEN}\nContent-Type: multipart/form-data\n```\n\n- 字段名：`media`\n- 限制：1MB，支持 jpg/png\n- 不占用素材库配额\n- 返回的 URL 可直接在正文 HTML 中使用\n\n返回：\n```json\n{\"url\": \"https://mmbiz.qpic.cn/...\"}\n```\n\n## 新增草稿\n\n```\nPOST /draft/add?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\n  \"articles\": [{\n    \"title\": \"标题（≤32字）\",\n    \"author\": \"作者（≤16字）\",\n    \"digest\": \"摘要（≤128字，仅单图文）\",\n    \"content\": \"HTML 正文（≤2万字符，图片 URL 必须来自 uploadimg）\",\n    \"thumb_media_id\": \"封面图 media_id\",\n    \"content_source_url\": \"原文链接\",\n    \"need_open_comment\": 1,\n    \"only_fans_can_comment\": 0\n  }]\n}\n```\n\n返回：\n```json\n{\"media_id\": \"...\"}\n```\n\n## 发布草稿\n\n```\nPOST /freepublish/submit?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\"media_id\": \"草稿的 media_id\"}\n```\n\n返回：\n```json\n{\"publish_id\": \"...\", \"msg_data_id\": \"...\"}\n```\n\n**注意**：发布为异步操作，返回成功仅表示任务提交成功。\n\n## 查询发布状态\n\n```\nPOST /freepublish/get?access_token={TOKEN}\nContent-Type: application/json\n```\n\n请求体：\n```json\n{\"publish_id\": \"...\"}\n```\n\n返回 `publish_status`：\n\n| 值 | 含义 |\n|----|------|\n| 0 | 发布成功 |\n| 1 | 发布中 |\n| 2 | 原创失败 |\n| 3 | 常规失败 |\n| 4 | 平台审核不通过 |\n| 5 | 已删除 |\n| 6 | 已封禁 |\n\n## 常见错误码\n\n| 错误码 | 含义 | 处理 |\n|--------|------|------|\n| 40001 | access_token 无效 | 重新获取 token |\n| 40004 | 不合法的媒体文件类型 | 检查图片格式 |\n| 40009 | 图片大小超限 | 封面 ≤10MB，正文图 ≤1MB |\n| 45009 | API 调用超限 | 等待后重试 |\n| 45028 | 接口无权限 | 检查公众号类型和权限 |\n| 48001 | API 未授权 | 检查公众号开发者设置 |\n\n## 凭证配置\n\n在仓库根 **`aws.env`** 中配置微信槽位（勿提交含真密钥的文件）：\n\n```env\nNUMBER_ACCOUNTS=1\nWECHAT_1_NAME=主号\nWECHAT_1_APPID=你的AppID\nWECHAT_1_APPSECRET=你的AppSecret\nWECHAT_1_API_BASE=\n```\n\n键名与 `skills/aws-wechat-article-main/references/env.example.yaml` 一致。多账号递增 `WECHAT_2_*` 等。\n\n## 权限要求\n\n- 需要已认证的服务号或订阅号\n- AppID 和 AppSecret 在「开发 → 基本配置」获取\n- 调用服务器 IP 需加入白名单\n\n## 官方文档\n\n- [新增草稿](https://developers.weixin.qq.com/doc/subscription/api/draftbox/draftmanage/api_draft_add)\n- [发布草稿](https://developers.weixin.qq.com/doc/subscription/api/public/api_freepublish_submit.html)\n- [上传永久素材](https://developers.weixin.qq.com/doc/subscription/api/material/permanent/api_addmaterial.html)\n- [上传正文图片](ht"},{"path":"references/pre-publish-checklist.md","content":"# 发布前检查清单\n\n在审稿通过后、实际提交前执行，确保可安全发布。\n\n## 检查项\n\n- [ ] 标题、摘要、作者已最终确认\n- [ ] 正文无未替换的占位符或草稿标记\n- [ ] 敏感词与错别字已在审稿中修正\n- [ ] 封面图已就绪（已上传或路径有效）\n- [ ] 正文内图片齐全，图注格式正确\n- [ ] 原创/转载标注已按配置处理\n- [ ] 文末引导区块已就位\n- [ ] 如需开启评论/仅粉丝可评，已确认设置\n\n全部勾选后执行提交步骤。"},{"path":"references/submit-guide.md","content":"# 提交到公众号后台\n\n## 方式一：API 提交（推荐）\n\n使用 `skills/aws-wechat-article-publish/scripts/publish.py`，通过微信公众号 API 完成发布。\n\n### 前置准备\n\n1. 在仓库根 **`aws.env`** 中填写微信槽位（与 `skills/aws-wechat-article-main/references/env.example.yaml` 键名一致），例如单账号：\n   ```env\n   NUMBER_ACCOUNTS=1\n   WECHAT_1_NAME=主号\n   WECHAT_1_APPID=你的AppID\n   WECHAT_1_APPSECRET=你的AppSecret\n   WECHAT_1_API_BASE=\n   ```\n   多账号递增 `WECHAT_2_*` 等；发布前可运行 `{python} skills/aws-wechat-article-publish/scripts/publish.py check-wechat-env` 检查缺项。\n\n2. 在公众平台「开发 → 基本配置」中将服务器 IP 加入白名单\n\n3. 准备文章目录：\n   ```\n   article/\n   ├── article.yaml    # 标题、作者、摘要等元信息\n   ├── article.html    # 排版后的正文 HTML\n   ├── cover.jpg       # 封面图\n   └── imgs/           # 正文内图片\n   ```\n\n### 一键发布\n\n```bash\n# 创建草稿（不发布，可在后台预览）\n{python} skills/aws-wechat-article-publish/scripts/publish.py full article/\n\n# 创建草稿并立即发布\n{python} skills/aws-wechat-article-publish/scripts/publish.py full article/ --publish\n```\n\n### 分步操作\n\n```bash\n# 获取 token\n{python} skills/aws-wechat-article-publish/scripts/publish.py token\n\n# 上传封面图\n{python} skills/aws-wechat-article-publish/scripts/publish.py upload-thumb cover.jpg\n\n# 上传正文图片\n{python} skills/aws-wechat-article-publish/scripts/publish.py upload-content-image imgs/img1.png\n\n# 创建草稿（需要先准备好 article.yaml）\n{python} skills/aws-wechat-article-publish/scripts/publish.py create-draft article.yaml\n\n# 发布\n{python} skills/aws-wechat-article-publish/scripts/publish.py publish <media_id>\n\n# 查询状态\n{python} skills/aws-wechat-article-publish/scripts/publish.py status <publish_id>\n```\n\n接口详情与错误码：[api-reference.md](api-reference.md)\n\n## 方式二：手动提交\n\n1. 登录微信公众平台（mp.weixin.qq.com）\n2. 进入「素材管理」或「草稿箱」→ 新建图文消息\n3. 填写标题、作者、摘要\n4. 将排版后的正文粘贴到正文编辑区\n5. 上传封面图，设置封面\n6. 逐一上传正文内图片并插入对应位置\n7. 设置评论权限（开启/仅粉丝可评）\n8. 保存为草稿或直接群发"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"公众号发布｜公众号草稿箱｜公众号群发｜图文推送｜微信 API｜wechat automation｜WeChat API automation｜auto publish｜scheduled publish — 公众号 API 发布工具，图文入草稿箱或直接群发，支持封面素材上传、发布前检查与 draft/published 模式切换。面向公众号运营、自动化内容团队、开发者。触发词：「发布」「提交」「群发」「推送」「发出去」「上传到公众号」「发到公众号」「可以发了吗」「发布前检查」。需要多环节串联（写+审+排+配图+发）请走 aws-wechat-article-main。 Skill: aws-wechat-article-publish Owner: aiworkskills Summary: 公众号发布｜公众号草稿箱｜公众号群发｜图文推送｜微信 API｜wechat automation｜WeChat API automation｜auto publish｜scheduled publish — 公众号 API 发布工具，图文入草稿箱或直接群发，支持封面素材上传、发布前检查与 draft/published 模式切换。面向公众号运营、自动化内容团队、开发者。触发词：「发布」「提交」「群发」「推送」「发出去」「上传到公众号」「发到公众号」「可以发了吗」「发布前检查」。需要多环节串联（写+审+排+配图+发）请走 aws-wechat-article-main。 Tags: api:1.0.17, automation:1.0.17, chinese:1.0.17, claude-code:1.0.","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":778,"uniquenessScore":47,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T13:12:22.739Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-10T13:12:22.739Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T15:53:05.803Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}