| name | agent-publisher |
| description | 微信公众号 AI 内容工作台:支持 AI 自动生成文章(基于热点/Agent)、多风格变体、演示文稿生成、按公众号发布到微信草稿箱、素材库管理。文章排版渲染由前端 doocs/md 编辑器完成;CLI 仅接受预渲染的 HTML 内容上传。 |
| metadata | {"openclaw":{"emoji":"📰","requires":{"bins":["uv"]},"primaryEnv":"AP_EMAIL"}} |
Agent Publisher — 微信公众号发布工具
通过 CLI 上传预渲染好的 HTML 内容,发布到微信公众号草稿箱。
架构约定(重要)
- 排版渲染由前端 doocs/md 编辑器统一完成——所有
html_content 都来自 doocs/md,没有第二条 HTML 生产链路
- CLI 仅接受
.html / .htm 文件。Markdown 文件会被拒绝
- AI 生成的文章 入库时只有 markdown 源,必须先在 web 编辑器中打开(doocs/md 自动渲染)才能发布
前置条件
- Agent Publisher 后端运行中(默认
http://localhost:9099)
- 邮箱已加入白名单
- 已安装
uv
环境变量
| 变量 | 说明 | 默认值 |
|---|
AP_URL | 后端地址 | http://localhost:9099 |
AP_EMAIL | 认证邮箱 | — |
内容来源:如何得到可上传的 HTML
CLI 不渲染 markdown。要上传一篇文章,先在以下任一工具中生成 HTML:
- 公司部署的 doocs/md 编辑器(推荐)——
https://<your-host>/editor 中编辑后复制 HTML 或导出
- 本地 doocs/md——
npx @doocs/md-cli(端口 8800),编辑后导出 HTML
- 任何能产出"内联样式 + 微信兼容"HTML 的工具——见下方"微信 HTML 规范约束"
微信 HTML 规范约束
如果要让 AI 直接生成可上传的 HTML,请在 prompt 中约束:
- 所有样式必须 inline
style="..."(微信不支持 <style> / <link> / class / id 选择器)
- 禁用
position、float、flex、grid、transform、@media
- 标题使用
<h1>~<h3>,正文 <p>,加粗 <strong>,斜体 <em>
- 列表用
<ul>/<ol>/<li>;表格须带 inline border 样式
- 图片用
<img src="..." style="max-width:100%;" />,不要用外链图片(微信会过滤),先下载到本地或用素材库
- 代码块需预先做语法高亮(颜色 inline 写入),不依赖 CSS class
最常见场景:上传 → 预览 → 发布
uv run {baseDir}/scripts/agent_publisher.py create-article \
--account-id 1 --title "标题" --content-file ./article.html
uv run {baseDir}/scripts/agent_publisher.py export-html 42 -o preview.html
uv run {baseDir}/scripts/agent_publisher.py edit-article 42 --content-file ./article.html
uv run {baseDir}/scripts/agent_publisher.py generate-cover 42
uv run {baseDir}/scripts/agent_publisher.py publish 42
HTML 中的本地 <img src="./local.png"> 会被自动上传到素材库并改写为可发布链接。
决策规则(AI Agent 必读)
调用任何命令前,按以下规则判断:
- 首次使用:先
auth,再 create-account(或确认已有 account)
- 上传文章选择参数:
- 用户指定了 Agent → 用
--agent-id
- 用户只提到公众号 → 用
--account-id(系统自动处理 Agent 绑定)
- 不可同时传两个
- 文件类型:必须是
.html 或 .htm。.md 会被拒绝。如果用户给的是 markdown,请先帮 ta 在本地用 doocs/md 渲染(npx @doocs/md-cli)或建议在 web 编辑器中打开
- 发布文章:
publish <article_id> 即可,默认发布到文章归属 Agent 的公众号
- 只有明确要求"发到另一个公众号"才加
--target-account-id
- AI 生成路径:
- 用户说"自动生成 / 写一篇" → 用
generate 或 write-from-hotspot
- 生成完成后必须提示用户在 web 编辑器中打开 —— doocs/md 会渲染 markdown 为 HTML 并自动保存。然后才能
publish
- 异步任务:
generate 和 slideshow 是异步,返回 task_id,需用 task <id> 轮询直到 success/failed
- 何时使用热点功能:
- 用户说"写一篇文章"但没提供具体内容 →
hotspots 查热点 → 展示给用户选择
- 用户说"今天有什么可写" →
hotspots --limit 5
- 用户说"关于 XX 有什么热点" →
hotspots --topic "XX"
- 用户说"自动帮我选一个热点写" →
hotspots → 选质量分最高的 → write-from-hotspot <id>
- 用户想看多个热点的综合分析 →
creative-brief <id1> <id2>
- 热点列表为空或太旧 →
collect <agent_id> 刷新数据源
- 不要调用热点的情况:
- 用户已提供明确的写作内容/文件 → 直接
create-article
- 用户在做发布操作
- 用户在管理账号/素材
错误处理
| 错误信息 | 原因 | 解决方案 |
|---|
No token. Run "auth" first | 未认证 | auth --email <email> |
agent_id or account_id is required | 缺少归属 | 加 --agent-id 或 --account-id |
Provide either agent_id or account_id, not both | 两个都传了 | 只保留一个 |
CLI no longer accepts Markdown files | 传了 .md | 在 doocs/md 编辑器中渲染为 HTML 后再上传 |
Article has no rendered HTML | AI 生成的文章未在编辑器中打开过 | 在 web 编辑器中打开该文章并保存 |
Account not found | account_id 不存在 | 用 accounts 查看可用 ID |
No thumb_media_id available | 发布时没有封面图 | 先 generate-cover 或 edit-article --cover |
Cannot connect to ... | 后端未启动 | 确认 AP_URL 指向正确地址 |
核心工作流
1. 认证
uv run {baseDir}/scripts/agent_publisher.py auth --email "you@example.com"
2. 绑定公众号(首次使用)
uv run {baseDir}/scripts/agent_publisher.py create-account --name "我的公众号" --appid wx123 --appsecret sec456
获取 AppID/AppSecret:登录 https://mp.weixin.qq.com → 设置与开发 → 基本配置。
3. 上传文章
规则:必须传 --agent-id 或 --account-id 其中一个(不可同时传)。
--account-id:推荐大多数场景使用。只需知道公众号 ID,系统自动处理 Agent 绑定
--agent-id:仅当用户明确指定了某个 Agent 时使用
当使用 --account-id 时,系统会自动选择该公众号下已有的 Agent;若不存在则自动创建一个"手动发布"Agent。无需用户手动操作。
uv run {baseDir}/scripts/agent_publisher.py create-article \
--account-id 1 --title "文章标题" --content-file ./article.html
uv run {baseDir}/scripts/agent_publisher.py create-article \
--account-id 1 --title "标题" --content-file ./article.html --cover media:5
uv run {baseDir}/scripts/agent_publisher.py create-article \
--account-id 1 --title "标题" --content-file ./article.html --cover "https://example.com/cover.jpg"
HTML 中所有 <img src="./local.png"> 这样的本地路径会自动上传到素材库并改写为 /api/media/<id>/download。http(s):// 外链和已经是 /api/media/... 的图片不会被改动。
4. AI 自动生成(无需手动写内容)
Agent 可以基于配置的数据源自动生成文章:
uv run {baseDir}/scripts/agent_publisher.py generate <agent_id>
uv run {baseDir}/scripts/agent_publisher.py generate <agent_id> --style-id tech
查看生成任务状态:
uv run {baseDir}/scripts/agent_publisher.py task <task_id>
关键:AI 生成的文章入库时 html_content 为空(只有 markdown 源)。必须先在 web 编辑器中打开 —— doocs/md 会自动渲染并通过 postMessage 把 HTML 保存回去。然后才能 publish。
如果你只能用 CLI 处理这种文章,可以:
article <id> 查看 markdown 源
- 用本地 doocs/md(
npx @doocs/md-cli)渲染为 HTML
edit-article <id> --content-file rendered.html 上传
5. 风格变体
为同一篇文章生成多种写作风格的版本:
uv run {baseDir}/scripts/agent_publisher.py style-presets
uv run {baseDir}/scripts/agent_publisher.py variants <article_id> --styles tech uncle clickbait
变体也是 LLM 输出 markdown 存到 content,需要在编辑器中打开后才能发布。
6. 演示文稿
从文章内容自动生成 Reveal.js 演示文稿:
uv run {baseDir}/scripts/agent_publisher.py slideshow <article_id>
uv run {baseDir}/scripts/agent_publisher.py task <task_id>
7. 发布到微信
最简调用:
uv run {baseDir}/scripts/agent_publisher.py publish <article_id>
发布规则:
- 不传
--target-account-id → 自动发布到文章归属公众号(通过 Agent 绑定确定)
- 传
--target-account-id → 发到指定公众号(可多次传发到多个号)
uv run {baseDir}/scripts/agent_publisher.py publish <article_id> --target-account-id 1
uv run {baseDir}/scripts/agent_publisher.py publish <article_id> --target-account-id 1 --target-account-id 2
发布后文章进入微信草稿箱,需在微信后台确认群发。
发布前确保 html_content 非空且有封面图,否则会报错。
如果没有封面图:
uv run {baseDir}/scripts/agent_publisher.py generate-cover <article_id>
uv run {baseDir}/scripts/agent_publisher.py edit-article <article_id> --cover "https://example.com/cover.jpg"
封面图生成逻辑:如果配置了 AI 文生图服务(MiniMax),会用 AI 生成精美插画;如未配置,自动用 HTML 模板截图生成(基于文章标题和 Agent 风格)。发布时若文章无封面图,系统也会自动 HTML 截图兜底。
编辑后重新同步到草稿箱:
uv run {baseDir}/scripts/agent_publisher.py edit-article <article_id> --content-file ./updated.html
uv run {baseDir}/scripts/agent_publisher.py sync-article <article_id>
命令速查
以下省略前缀 uv run {baseDir}/scripts/agent_publisher.py。
认证
| 命令 | 说明 |
|---|
auth --email <email> | 邮箱认证 |
whoami | 查看当前身份 |
公众号
| 命令 | 说明 |
|---|
accounts | 列出我的公众号 |
create-account --name <名称> --appid <ID> --appsecret <Secret> | 绑定公众号 |
Agent 管理
| 命令 | 说明 |
|---|
agents | 列出我的 Agent |
create-agent --name <名称> [--topic <主题>] [--style-id <风格>] [--account-id <ID>] | 创建 Agent |
delete-agent <agent_id> | 删除 Agent |
generate <agent_id> [--style-id <风格>] | 触发 AI 自动生成文章 |
task <task_id> | 查看生成任务状态 |
文章(核心)
| 命令 | 说明 |
|---|
create-article (--agent-id <ID> | --account-id <ID>) --title <标题> --content-file <file.html> | 上传 HTML 文章 |
edit-article <ID> [--title] [--content-file <file.html>] [--cover] | 编辑文章 |
article <ID> | 查看文章详情 |
articles [--status draft] | 列出文章 |
export-html <ID> [-o preview.html] | 导出存档的 HTML 到本地预览 |
热点 & 选题
| 命令 | 说明 |
|---|
hotspots [--topic "AI"] [--platform weibo] [--limit 10] | 查看当前热点话题 |
collect <agent_id> | 触发热点采集 |
write-from-hotspot <hotspot_id> | 从热点一键生成文章(生成后需在编辑器中打开) |
creative-brief <id1> [id2] [--topic "聚焦方向"] | 多热点综合创意简报 |
封面图
| 命令 | 说明 |
|---|
generate-cover <ID> | 生成封面图(AI 文生图 或 HTML 截图自动降级) |
风格与变体
| 命令 | 说明 |
|---|
style-presets | 列出可用风格预设 |
variants <article_id> [--styles tech uncle clickbait] | 生成多风格变体 |
演示文稿
| 命令 | 说明 |
|---|
slideshow <article_id> | 从文章生成演示文稿 |
发布
| 命令 | 说明 |
|---|
publish <article_id> [--target-account-id <ID> ...] | 发布到微信草稿箱 |
sync-article <article_id> [--target-account-id <ID> ...] | 同步编辑到草稿箱 |
batch-publish <id1> <id2> ... [--target-account-id <ID> ...] | 批量发布(管理员) |
素材库
| 命令 | 说明 |
|---|
media | 列出素材 |
upload-media <文件路径> | 上传图片 |
数据
| 命令 | 说明 |
|---|
followers <account_id> | 粉丝趋势 |
article-stats <account_id> | 阅读数据 |
注意事项
- Token 有效期 30 天,过期重新
auth
create-article / edit-article 必须传 .html 或 .htm 文件,传 .md 会被拒绝
--agent-id 和 --account-id 二选一
- 若只想"上传文章并发布到某公众号",优先用
--account-id + publish --target-account-id
- AI 生成(
generate / write-from-hotspot / variants)的文章需要先在 web 编辑器中打开才能发布
- HTML 中的本地图片路径会在上传时自动入库并改写
- 封面图支持
media:<id>(素材库 ID)或 http(s):// URL
- AppSecret 敏感信息不会被打印