Install
openclaw skills install @shinchen6/wechat-draft-publisher-cloud基于微信云托管 relay 的公众号草稿发布器:把现成的 markdown 文章 + 封面图推送到微信公众号草稿箱,本地无需 appid/secret、免 IP 白名单。触发:「推草稿」「发公众号草稿箱」「wechat draft publish」「send to wechat draft」。不触发:写文章、trending、邮件。默认 dry-run,加 --real 才真发;relay 地址与密钥通过环境变量或 config.json 注入(不硬编码)。
openclaw skills install @shinchen6/wechat-draft-publisher-cloud一个动作:article.md + cover.png + 标题 → relay → 公众号草稿箱。
默认 dry-run(不真发,只本地转 HTML + 跑流程 + 写 mock media_id)。真发必须显式加 --real——防止自动化测试时误推到用户草稿箱。
用:用户说"推草稿"、"发公众号草稿箱",或上游流水线 Step 7 调用。 不用:写文章 / trending / 邮件 / 纯本机保存。
relay 是部署在 微信云托管 上的开源草稿代理服务端,利用官方「开放接口服务(云调用)」免鉴权调用公众号接口,本地脚本无需固定 IP、无需公众号 appid/secret。本 skill 是客户端,负责写稿、把 Markdown 转成微信图文 HTML、处理图片,再把内容交给 relay。
relay 只做三件事(纯代理,不解析 Markdown):
POST /material:接收图片 base64,上传到微信素材库,返回 media_id + urlPOST /draft:接收标题 + 已转好的 HTML + 封面 thumb_media_id,创建草稿POST /draft-delete:接收 {"media_id": ...},删除草稿(需先在云调用「微信令牌」权限中加 /cgi-bin/draft/delete)在本 skill 本地完成(scripts/md2wechat.py,零依赖纯标准库实现)。relay 不碰 Markdown。
这样 relay 保持极简、零三方依赖;所有内容加工都在你本地可控。
relay 跑在云托管,默认公网地址是平台生成的默认域名(谁都能访问),所以必须靠「访问密钥」保护。本 skill 按以下优先级解析 访问地址(URL) 与 访问密钥(KEY):
--cloud-url / --cloud-keyWECHAT_DRAFT_RELAY_URL / WECHAT_DRAFT_RELAY_KEYDRAFT_CLOUD_URL / DRAFT_API_KEYscripts/ 目录下,已被 .gitignore 忽略,不进仓库):
{ "relay_url": "https://<你的服务名>.<地域>.run.tcloudbase.com", "relay_key": "你的 RELAY_API_KEY" }
发布版不硬编码任何个人地址 / 密钥——安装后由用户自己注入,符合开源安全要求。
| 参数 | 必填 | 说明 |
|---|---|---|
article_path cover_path | ✓ | markdown + PNG |
titles_md_path | title_path | 二选一 | 候选标题文件 / 已选标题文件 |
--real | 选 | 加这个才真发,否则 dry-run |
--cloud-url --cloud-key | 选 | 覆盖注入的 relay 地址/密钥 |
covered_md_path covered_line | 选 | 成功后追加去重 |
feishu_chat_id | 选 | 真发成功后才发飞书(best-effort) |
| 正文插图 | 自动 | 脚本扫描 article.md 里的 ,本地转 HTML 时把每张图经 relay /material 上传素材库换回 mmbiz 链接。无需额外参数 |
$run_dir/publish_result.json){success, media_id, chosen_title, chosen_title_bytes, cloud_url, body_images, html_len, covered_appended, feishu_sent, error_code, error_msg, elapsed_sec}
# 1) dry-run(默认,本地转 HTML + 校验,不发任何请求)
python scripts/publish_script.py --article X.md --cover Y.png --titles-md T.md
# 2) 真发(推荐先 1) 验证后再 2))
python scripts/publish_script.py --real --article X.md --cover Y.png --titles-md T.md
正文插图怎么写:在 article.md 正常用 markdown 图片语法,脚本自动扫描、本地转 HTML、经 relay 上传。
## 一段说明

- 要点一
- 要点二
草稿箱会累积(每次 --real 都新增一篇、不覆盖)。清理旧草稿:
# 单个删除(默认 dry-run 只列出,--real 才真删)
python scripts/publish_script.py --delete <media_id> --real
# 批量删除(文件每行一个 media_id,# 开头为注释)
python scripts/publish_script.py --delete-batch ids.txt --real
底层走 relay POST /draft-delete,密钥/地址解析规则与发布一致(--cloud-url/--cloud-key > 环境变量 > config.json > 默认值)。需先在云调用「微信令牌」权限中加 /cgi-bin/draft/delete 并重建版本,否则报 48001。
 —— 脚本本地转 HTML 时经 relay /material 上传素材库后替换成 mmbiz 链接。publish_result.json 里 body_images 字段报告本次扫描到的本地插图数量,html_len 报告生成 HTML 长度,dry-run 即可验证。article / cover / titles_md|title_file 文件存在;run_dir 自动 makedirs1. / 1、 / 1) 候选;或直读 title.txtrun-dir/title.txtmd2wechat.convert(md, url_map)(dry-run 也跑,验证转换不崩)/material → 换回 mmbiz url,写入 url_map/material → 拿到 thumb_media_idthumb_media_id POST relay /draft → 返回 media_id| 码 / 现象 | 含义 | 修复 |
|---|---|---|
41001 missing access_token | 云调用网关未注入凭证 | relay 部署侧:开启「开放接口服务」开关并重建版本 |
48001 / 85107 接口未授权 | 云调用「微信令牌」权限缺 /cgi-bin/material/add_material + /cgi-bin/draft/add | 控制台补接口路径 |
40164 IP 不在白名单 | 非云托管部署、token 模式 | 把出口 IP 加公众号后台白名单(云托管免此步) |
invalid api key | 缺 / 错 X-API-Key 头 | 检查注入的 relay 密钥 |
NETWORK(本 skill 定义) | 域名不可达 / 超时 / 非 JSON / urllib 连接或 HTTP 错误 / 503 网关冷启动 | 503 自动 retry 1 次(8s 退避);其它检查 relay 地址是否失效 |
失败不删 article.md / cover.png,留人重试。
len(s.encode('utf-8')),中文每字 3 字节MOCK_MEDIA_ID_dryrun,外部副作用全跳过(不真发、不发飞书、不动 covered)。真发必须 --realurllib + base64(JSON 协议);Markdown->HTML 用 scripts/md2wechat.py(纯标准库)。无需 requests / curl / mistunedo_publish_with_retry 风格逻辑:识别 "503" + err_code=NETWORK 时 sleep(8) 后自动重试 1 次--real 都新增 1 篇,不会自动覆盖前一篇