📦 Ghost Publisher — Ghost发布器
v1.0.0将Markdown文章发布到任何Ghost 5 CMS网站的发布器。Publisher Interface v1的首个参考实现,提供完整的发布流程支持(创建、转换、上传图片、发布),支持自托管Ghost和Ghost Pro。
详细分析 ▾
运行时依赖
版本
初始发布 — Ghost CMS的Publisher Interface v1参考实现
安装命令
点击复制技能文档
将Markdown文章发布到任何Ghost 5 CMS网站。Publisher Interface v1的首个参考实现——一种与CMS无关的编辑工作流合约,使"更换CMS"成为配置决策而非重写。
配套技能(均实现相同接口,分别发布):
ghost-publisher— 本技能wordpress-publisher— 计划中substack-publisher— 计划中medium-publisher— 计划中
关于接口
本技能完整实现了Publisher Interface v1。接口规范——标准帖子对象模式和七个必需方法——位于技能根目录的INTERFACE.md中。如果您正在构建调用代理或另一个适配器技能,请阅读该文件。本节以下是Ghost特定用法。
简而言之:您的代码(或编辑工作流编排器)调用publisher.createPost(post)、publisher.publishPost(id, opts)等。适配器将标准帖子对象转换为Ghost格式的payload,处理JWT,将markdown转换为Ghost Lexical,将作者ID映射到Ghost工作人员,并上传图片。这些都不会泄露到调用者代码中。
设置
必需环境变量
GHOST_URL— 您的Ghost站点URL,例如https://yoursite.com或https://yourpub.ghost.ioGHOST_ADMIN_API_KEY— 来自Ghost自定义集成的Admin API密钥。格式::
获取Admin API密钥
- 进入Ghost Admin -> Settings -> Integrations
- 点击"Add custom integration"
- 命名(例如"OpenClaw Publisher")
- 复制Admin API密钥 — 它是一个24字符的key_id,一个冒号,和一个64字符的十六进制密钥(格式:
XXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX)
可选配置文件(GHOST_PUBLISHER_CONFIG)
对于非机密设置(默认作者、代理到工作人员的映射、简报ID、最大图片大小),将GHOST_PUBLISHER_CONFIG指向一个JSON文件:
{
"default_author_id": "ghost_staff_id",
"agent_author_map": {
"staff_1": "ghost_staff_id_1",
"staff_2": "ghost_staff_id_2"
},
"newsletter_id": "ghost_newsletter_id",
"max_image_size_mb": 2
}
agent_author_map允许调用者传递{"author": "staff_1"},让适配器将其解析为正确的Ghost工作人员,而无需调用者了解内部Ghost ID。省略该映射时,一切都会回退到default_author_id,或者如果该值也未设置,则回退到集成的默认值。如果此文件包含您不希望公开的ID,请将其保持在版本控制之外。机密密钥不应放在此文件中——密钥来自环境变量。
用法
作为Python模块(推荐用于代理)
from publisher import GhostPublisherpub = GhostPublisher() # 读取环境变量
post_id = pub.createPost({ "title": "A quiet argument about obsolescence", "excerpt": "Things that still run but no longer serve a purpose.", "body_md": open("article.md").read(), "tags": ["culture", "criticism"], "author": "staff_1", })
hosted = pub.uploadImage("https://cdn.example.com/hero.jpg", alt="Booth interior") pub.updatePost(post_id, {"featured_image_url": hosted, "image_alt_text": "Booth interior"})
url = pub.publishPost(post_id, {"send_newsletter": True}) print(f"Live at: {url}")
所有七个Publisher Interface v1方法都可在GhostPublisher实例上使用:createPost、updatePost、publishPost、schedulePost、deletePost、uploadImage、getPost。
作为CLI
完整流程(最常见)
python3 publisher.py create-publish article.md \
--title "Your Article Title" \
--excerpt "A 1-2 sentence summary for SEO and previews" \
--tags "ai,economics,analysis" \
--image-url "https://cdn.example.com/header.jpg" \
--image-alt "Description of the image" \
--upload-image \
--newsletter
移除--newsletter可在不邮件通知订阅者的情况下发布。如果图片URL已经在您信任的CDN上且不需要Ghost的媒体库托管,移除--upload-image。
分步操作
# 1. 创建草稿(返回post_id) python3 publisher.py create-draft --title "Title" --excerpt "Summary" --tags "tag1,tag2"# 2. 注入markdown正文 python3 publisher.py update-content article.md
# 3. 上传并附加特色图片 python3 publisher.py set-image https://cdn.example.com/hero.jpg --alt "Hero image" --upload
# 4. 定时发布,或立即发布 python3 publisher.py schedule 2026-05-01T09:00:00Z python3 publisher.py publish --newsletter
# 其他接口方法 python3 publisher.py get python3 publisher.py delete python3 publisher.py upload-image ./local.jpg --alt "alt text"
工作示例
您正在向具有名为"OpenClaw Publisher"的自定义集成的Ghost Pro站点发布一篇短文。
1. 环境
export GHOST_URL="https://yourpub.ghost.io"
export GHOST_ADMIN_API_KEY=":"
2. 编写article.md
# A quiet argument about obsolescenceSome machines keep running long after they stop serving anyone. The projector still warms up. The booth still smells of amber lamp and dust. There is no reel threaded. There is no audience.
What this piece is about
A meditation on continuity without function -- why certain systems outlive the problem they were built to solve.
3. 运行流程
python3 publisher.py create-publish article.md \
--title "A quiet argument about obsolescence" \
--excerpt "What certain systems look like after their purpose has gone." \
--tags "culture,essay" \
--image-url "https://cdn.example.com/booth.jpg" \
--image-alt "Close-up of a projector booth interior, no reel loaded" \
--upload-image
4. 输出
[ok] Draft created: 69d12a34ec4a400445c217ce
[ok] Image uploaded: https://yourpub.ghost.io/content/images/2026/04/booth.jpg
[ok] Feature image set
[ok] Published: https://yourpub.ghost.io/quiet-argument-about-obsolescence/
这是完整流程。针对任何Publisher Interface v1适配器从编辑工作流代理调用的相同序列将在任何CMS上产生相同结果。
支持的Markdown格式
- 标题:
# H1到#### H4 - 粗体、斜体、粗体+斜体
行内代码- 链接
- 无序列表(
-、*、+) - 有序列表(
1.、2.) - 引用块(
>) - 分隔线(
---)
该技能在内部将markdown转换为Ghost 5 Lexical JSON。您无需直接处理Lexical格式。Ghost将文章标题与正文分开存储。如果您的markdown文件以# Title行开头,它会在注入前自动剥离——您通过--title传递的标题(或createPost调用中的title字段)才是最终使用的。
编辑标准
Ghost乐观并发。每次写入都会先获取updated_at并将其传回Ghost。如果另一位编写者在您的读取和写入之间修改了帖子,Ghost会拒绝写入。适配器会显示底层错误——请勿盲目重试。
JWT过期。JWT为每次API调用新鲜生成,过期时间为5分钟。长时间运行的批量操作无需管理令牌。
图片大小限制。uploadImage在联系Ghost之前会拒绝超过配置的max_image_size_mb(默认2MB)的文件。Ghost Pro也有自己的限制;如果您的图片通过此检查但Ghost拒绝它,请向Ghost Pro支持提交工单或先压缩图片。
标签。将标签作为纯字符串传递。适配器会请求Ghost创建任何尚不存在的标签。Ghost会自动为其创建slug。
作者映射。如果配置了agent_author_map,请将调用者端标识符(例如"staff_1")作为author传递。如果未配置,适配器会回退到default_author_id,然后回退到集成的默认作者。未知的author不会报错——它会静默回退。如果发布后需要审核署名,请设计您的工作流以进行审核。
本技能不是什么
- 不是无头CMS。Ghost是CMS;本技能是将内容导入其中的管道。
- 不是markdown渲染器。它将markdown转换为Ghost Lexical,以便Ghost可以渲染。输出存在于Ghost中,而非这里。
- 不兼容Ghost 4.x。Ghost 4使用Mobiledoc;本技能针对Ghost 5的Lexical格式。
- 不是编辑工作流。选择图片、撰写文案、安排发布节奏——这属于调用代理或工作流。本技能只做发布步骤,并且做得很好。
许可证
MIT-0(MIT No Attribution)。使用、修改、再分发、商业发货。无需署名。请参阅LICENSE。