Automatisch 中 Ghost 触发器实战:New Post Published 的接入原理与流程配置
2026/9/15 0:59:20 网站建设 项目流程

Automatisch 中 Ghost 触发器实战:New Post Published 的接入原理与流程配置

【免费下载链接】automatischThe open source Zapier alternative. Build workflow automation without spending time and money.项目地址: https://gitcode.com/GitHub_Trending/au/automatisch

本文围绕 Automatisch 对 Ghost(开源博客平台)的官方触发器「New post published」展开,讲解该 Webhook 触发器的能力边界、连接配置、底层实现原理,以及如何在一个自动化流程中订阅「新文章发布」事件并消费其数据负载。读完本文,你将掌握在 Automatisch 中为 Ghost 创建连接、配置流程、启用/停用该触发器的完整方法,并理解其背后基于 Ghost Admin API Webhook 的事件订阅机制。

Ghost 触发器一览:当前版本只有一个事件

在 Automatisch 的 Ghost 应用中,官方目前提供的触发器记录在 packages/docs/pages/apps/ghost/triggers.md 中,内容非常聚焦——当前仅有一个:

触发器名称触发条件
New post published当一篇新文章(post)发布时触发

该触发器的类型为webhook(而非轮询),意味着 Automatisch 不会定时去抓取 Ghost 的接口,而是由 Ghost 在文章发布事件发生时主动把数据推送到 Automatisch 生成的 Webhook 地址上。这在事件及时性、请求开销两方面都优于轮询方案。

在源码层面,触发器注册于 packages/backend/src/apps/ghost/triggers/index.js:

import newPostPublished from './new-post-published/index.js'; export default [newPostPublished];

而应用(app)本身的声明位于 packages/backend/src/apps/ghost/index.js:

export default defineApp({ name: 'Ghost', key: 'ghost', baseUrl: 'https://ghost.org', apiBaseUrl: '', iconUrl: '{BASE_URL}/apps/ghost/assets/favicon.svg', authDocUrl: '{DOCS_URL}/apps/ghost/connection', primaryColor: '#15171A', supportsConnections: true, beforeRequest: [setBaseUrl, addAuthHeader], auth, triggers, });

从这里可以看到 Ghost 应用的几个关键事实:它通过supportsConnections: true支持连接(凭据)管理;所有出站请求都会经过setBaseUrladdAuthHeader两个前置钩子统一处理 URL 与鉴权头。

前置条件:先建立 Ghost 连接

在使用「New post published」触发器之前,必须先在 Automatisch 中创建一条 Ghost 连接。官方操作指引记录在 packages/docs/pages/apps/ghost/connection.md,步骤如下:

  1. 登录你的 Ghost 后台(Ghost Admin panel)。
  2. 点击Integrations(集成)按钮。
  3. 点击Add custom integration(添加自定义集成),创建一个 Admin API Key(管理 API 密钥)。
  4. 在 Automatisch 的Admin API Key字段中填入该密钥。
  5. 在 Automatisch 的Instance URL(实例地址)字段中填入你的 Ghost API URL(例如https://your-blog.example.com)。
  6. 点击Submit提交。
  7. 连接建立成功后,即可在流程中开始使用该连接。

两个必填字段的源码视角

连接表单定义在 packages/backend/src/apps/ghost/auth/index.js,包含两个required: true的字段:

  • Instance URLinstanceUrl,string):你的 Ghost 站点地址;
  • Admin API KeyapiKey,string):由 Ghost 自定义集成生成的 Admin API 密钥。

这两个字段的实际作用在请求钩子中体现得淋漓尽致。

Instance URL 如何变成 API 地址

packages/backend/src/apps/ghost/common/set-base-url.js 会在每次请求发出前拼接基础 URL:

const setBaseUrl = ($, requestConfig) => { const instanceUrl = $.auth.data.instanceUrl; if (instanceUrl) { requestConfig.baseURL = `${instanceUrl}/ghost/api`; } return requestConfig; };

即最终所有 API 请求都会被定向到<instanceUrl>/ghost/api之下,配合后续的/admin/webhooks//admin/site/等路径使用。

Admin API Key 如何完成鉴权

Ghost 的 Admin API Key 形如{id}:{secret}。鉴权逻辑位于 packages/backend/src/apps/ghost/common/add-auth-header.js:

const addAuthHeader = ($, requestConfig) => { const key = $.auth.data?.apiKey; if (key) { const [id, secret] = key.split(':'); const token = jwt.sign({}, Buffer.from(secret, 'hex'), { keyid: id, algorithm: 'HS256', expiresIn: '1h', audience: `/admin/`, }); requestConfig.headers.Authorization = `Ghost ${token}`; } return requestConfig; };

可以看到,Automatisch 用:切分密钥的idsecret,以 HS256 算法签发一个1 小时有效audience/admin/的 JWT,并以Authorization: Ghost <token>的形式附加到请求头。这完全遵循 Ghost Admin API 的官方鉴权规范,因此任何符合该规范的 Ghost 实例(包括自托管 Ghost)都能接入。

连接验证的底层逻辑

提交连接时,Automatisch 会调用 packages/backend/src/apps/ghost/auth/verify-credentials.js 做连通性校验:

const verifyCredentials = async ($) => { const site = await $.http.get('/admin/site/'); const screenName = [site.data.site.title, site.data.site.url] .filter(Boolean) .join(' @ '); await $.auth.set({ screenName }); await $.http.get('/admin/pages/'); };

它会请求/admin/site/读取站点标题与地址,拼成连接的显示名称(screenName),再请求/admin/pages/确认管理接口可用。两个请求都成功,连接才会被判定为有效;之后每次校验(is-still-verified.js)会重跑同一套验证。

New Post Published 触发器的实现拆解

该触发器的完整实现在 packages/backend/src/apps/ghost/triggers/new-post-published/index.js,通过defineTrigger声明,核心信息如下:

export default defineTrigger({ name: 'New post published', key: 'newPostPublished', type: 'webhook', description: 'Triggers when a new post is published.', ... });
  • name:界面展示名「New post published」;
  • key:内部唯一标识newPostPublished
  • typewebhook,说明该触发器由外部事件驱动;
  • description:与文档一致——当一篇新文章发布时触发。

registerHook:如何订阅 Ghost 的 post.published 事件

Webhook 类型触发器的关键步骤是「注册回调」。当你在 Automatisch 中为一个流程启用该触发器时,会执行registerHook

async registerHook($) { const payload = { webhooks: [ { event: 'post.published', target_url: $.webhookUrl, name: `Flow ID: ${$.flow.id}`, }, ], }; const response = await $.http.post('/admin/webhooks/', payload); const id = response.data.webhooks[0].id; await $.flow.setRemoteWebhookId(id); }

其工作流程是:

  1. 向 Ghost Admin API 的/admin/webhooks/端点 POST 一条 webhook 订阅;
  2. 订阅的eventpost.published(文章发布事件);
  3. target_url指向 Automatisch 为该流程动态生成的$.webhookUrl
  4. Flow ID: <流程ID>作为 webhook 名称,便于在 Ghost 后台识别来源;
  5. 将 Ghost 返回的 webhook 记录 ID 保存为remoteWebhookId,供后续注销时使用。

run:收到事件后如何产出数据

当 Ghost 命中post.published并回调 Webhook 地址时,触发器的run方法会被执行:

async run($) { const dataItem = { raw: $.request.body, meta: { internalId: Crypto.randomUUID(), }, }; $.pushTriggerItem(dataItem); }

它把 Ghost 推送的请求体($.request.body,即新文章的结构化数据)包装成一条触发数据项,并生成一个随机的internalId用于执行记录去重/追踪,随后通过$.pushTriggerItem推入流程引擎。后续所有步骤(例如把新文章标题同步到其他应用)都可以引用这批输出数据。

testRun:无事件时如何测试

为了在没有真实新文章时也能验证流程,testRun会复用最近一次执行步骤的数据:

async testRun($) { const lastExecutionStep = await $.getLastExecutionStep(); if (!isEmpty(lastExecutionStep?.dataOut)) { $.pushTriggerItem({ raw: lastExecutionStep.dataOut, meta: { internalId: '' }, }); } }

也就是说,只要流程此前成功跑过一次,测试运行就能直接取用上次的dataOut作为模拟输入;若从未执行过,则测试不会产生数据项。

unregisterHook:停用流程时的清理

当你停用或删除该流程时,unregisterHook会调用 Ghost 删除对应的远端 webhook:

async unregisterHook($) { await $.http.delete(`/admin/webhooks/${$.flow.remoteWebhookId}/`); }

这一对「注册/注销」保证了远程订阅与流程生命周期严格同步,避免 Ghost 后台残留失效的 webhook。

在 Automatisch 中配置使用该触发器

把以上原理落到实际操作上,推荐步骤如下:

  1. 进入 Automatisch 的Flows页面,创建一个新流程;
  2. 在「Choose an app and event」中选择Ghost
  3. 事件(event)列表中选择New post published
  4. 在连接(connection)下拉中选择之前创建的 Ghost 连接;若尚未创建,可在该步骤内直接跳转创建;
  5. 保存并启用流程——启用时 Automatisch 会向你的 Ghost 实例注册post.published的 webhook;
  6. 到 Ghost 后台发布一篇文章,返回 Automatisch 的Executions页面查看本次执行,触发器的输出即为该文章的数据负载;
  7. 可以再串联任意后续步骤(如发送通知、写入其他应用),并在流程中使用触发器输出的字段。

需要留意:触发器的输出结构直接取决于 Ghost 推送的post.published事件负载(包括文章标题、URL、作者等元数据),具体字段以你的 Ghost 版本实际返回为准。若你的流程曾执行成功,也可以在编辑器中点击测试(test run)来复用最近一次数据预览输出结构。

常见问题与排查方向

  • 连接验证失败:确认Instance URL是站点根地址(不要带上/ghost/api),且Admin API Key是完整的{id}:{secret}形式;验证逻辑会依次请求/admin/site//admin/pages/,任一失败都会导致校验不通过。
  • 发布文章后流程未触发:进入 Ghost 后台的Integrations → 对应自定义集成,检查是否存在名为Flow ID: xxx的 webhook,并核对target_url是否与 Automatisch 为该流程生成的回调地址一致;若不一致,尝试停用再重新启用流程,强制重新注册。
  • 停用流程后 Ghost 后台仍有残留 webhook:正常停用流程会调用unregisterHook删除远端记录;若发现残留,通常是流程被强制中断所致,可在 Ghost 后台手动删除该 webhook,或重新启用再停用一次以触发清理逻辑。
  • 鉴权相关报错(401):Admin API Key 生成的 JWT 有效期为 1 小时且audience固定为/admin/,若你的 Ghost 实例版本较旧或开启了自定义鉴权策略,需要确认其与 HS256/JWT 方案兼容。

小结

Automatisch 的 Ghost 应用虽小,却是一个结构非常完整的 Webhook 触发器示例:通过setBaseUrl/addAuthHeader两个钩子完成 API 地址与 JWT 鉴权,通过registerHook订阅post.published事件,再由run消费回调负载、unregisterHook做生命周期清理。掌握「New post published」这一个触发器的接入与排查,也就同时理解了 Automatisch 中所有 Webhook 类触发器(如各类「当新内容发布/创建时」场景)的统一工作模型。

如果你想深入了解触发器的通用定义规范,可以继续阅读 define-trigger.js 与 define-app.js;而 Ghost 应用的连接接入细节,可回看 connection.md 与 auth/index.js。

【免费下载链接】automatischThe open source Zapier alternative. Build workflow automation without spending time and money.项目地址: https://gitcode.com/GitHub_Trending/au/automatisch

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询