Automatisch 集成 Appwrite 触发器详解:New documents 轮询机制的配置与实现原理
【免费下载链接】automatischThe open source Zapier alternative. Build workflow automation without spending time and money.项目地址: https://gitcode.com/GitHub_Trending/au/automatisch
导读
本文聚焦开源工作流自动化平台 Automatisch 中 Appwrite 集成唯一的内置触发器New documents(新文档),讲解其在 Automatisch 编辑器中的配置方式、底层轮询实现机制与去重原理,并结合仓库源码剖析触发器的动态数据源、请求构造与认证流程。读完本文,你将能熟练配置该触发器监听 Appwrite 指定集合的新增文档,并理解其基于游标分页与internalId去重的工作方式,为搭建"数据库变更驱动"的自动化流程打下基础。
触发器总览:文档定义的骨架
在 Automatisch 官方文档中,Appwrite 应用的触发器定义位于 packages/docs/pages/apps/appwrite/triggers.md,其核心内容是一个触发器条目:
| 字段 | 值 |
|---|---|
| name | New documents |
| desc | Triggers when a new document is created.(当新文档被创建时触发) |
文档通过CustomListing组件将触发器条目渲染到应用详情页中,对应的元数据声明了该应用的 favicon 为/favicons/appwrite.svg。也就是说,Appwrite 集成对外暴露的触发器只有 New documents 一个,这从源码 triggers/index.js 中也可以得到印证——该文件导出的数组只包含newDocuments一个触发器。
认识触发器的核心配置参数
当你在 Automatisch 流程编辑器中选择 Appwrite 应用的New documents触发器后,需要配置两个必填参数,它们共同决定了"监听哪个位置的新文档":
Database(数据库)
- label:Database
- key:
databaseId - type:
dropdown(下拉选择) - required:true(必填)
- source:
getDynamicData动态数据源,key 为listDatabases
该下拉框的选项由动态数据源listDatabases实时拉取,不需要手动填写数据库 ID。
Collection(集合)
- label:Collection
- key:
collectionId - type:
dropdown(下拉选择) - required:true(必填)
- dependsOn:
['parameters.databaseId'](依赖已选的数据库) - source:
getDynamicData动态数据源,key 为listCollections,并携带parameters.databaseId参数
该下拉框依赖上一步选择的 Database,只有先选定数据库后,Automatisch 才会拉取该数据库下的集合列表供你选择。两个参数都开启了variables: true,意味着你可以在参数值中引用流程中的动态变量(如上一个步骤的输出)。
完整的参数定义见 triggers/new-documents/index.js。
动态数据源:下拉选项从哪里来
两个下拉框的选项并非静态写死,而是由 Appwrite 应用的dynamic-data模块在运行时查询真实数据:
listDatabases:列出所有数据库
list-databases/index.js 的实现会调用 Appwrite 的GET /v1/databases接口,并携带两条查询:
orderAsc(按name属性升序排列);limit100(最多返回 100 个)。
随后将每个数据库映射为{ value: $id, name }结构返回,其中$id作为下拉框提交的值。
listCollections:按数据库列出集合
list-collections/index.js 会先读取当前步骤参数$.step.parameters.databaseId,如果尚未选择数据库则直接返回空列表;否则调用GET /v1/databases/${databaseId}/collections,同样使用orderAsc(按name排序)和limit100 的查询,返回集合的$id与name映射。
这种"先查数据库、再按数据库查集合"的两级联动动态数据源,保证了用户在下拉框中看到的永远是与自己 Appwrite 项目实时同步的有效 ID,避免了手动输入拼写错误导致流程失败。
New documents 轮询机制源码解析
New documents 是一个轮询(polling)型触发器,而不是 Webhook。其定义位于 triggers/new-documents/index.js,核心字段pollInterval: 15表示 Automatisch 每15 秒向 Appwrite 发起一次轮询请求。这一点也受 helpers/define-trigger.js 的约束——defineTrigger会校验触发器必须带有pollInterval或是 webhook 类型,否则直接抛出异常。
轮询请求的构造
每次轮询,触发器读取步骤参数中的databaseId与collectionId,向 Appwrite 发起:
GET /v1/databases/{databaseId}/collections/{collectionId}/documents并携带一组 JSON 序列化的查询参数:
{ method: 'orderDesc', attribute: '$createdAt' }——按创建时间$createdAt降序,保证最新创建的文档排在最前;{ method: 'limit', values: [1] }——每批只取 1 条;- 当存在上次游标时追加
{ method: 'cursorAfter', values: [lastDocumentId] }——用上一次最后一条文档的$id作为游标继续向后翻页。
其中cursorAfter有一个细节:代码注释明确写着"An invalid cursor shouldn't be sent"(不应发送无效游标),因此在没有lastDocumentId时该查询会被过滤掉(.filter(Boolean)),避免向 API 发送非法游标。
分页与去重机制
触发器通过do...while循环实现游标分页:
- 每次请求后记录
documentCount(本批返回条数)与lastDocumentId(本批最后一条文档的$id); - 当本批返回条数等于
limit(即 1)时继续翻页,直到某批返回空为止,确保一次轮询能完整扫完所有新增文档; - 若某批返回为空,直接
return结束本轮。
对于每条文档,调用$.pushTriggerItem推入触发事件:
$.pushTriggerItem({ raw: document, meta: { internalId: document.$id, }, });这里的关键是meta.internalId = document.$id。Automatisch 引擎以internalId作为去重依据:同一份文档在一次轮询中被发现后会被记录,后续轮询即使再次读到该文档,也不会重复触发执行。这保证了"每个新文档只触发一次流程",且天然免疫网络抖动、重复请求带来的重复执行问题。在流程执行记录中,raw字段则完整承载了该文档的全部数据,供后续步骤(如发送通知、写回数据)使用。
认证与请求头
轮询请求之所以能成功,依赖于 Appwrite 连接(Connection)中保存的认证信息。Appwrite 应用在 index.js 中注册了两个beforeRequest钩子:
- setBaseUrl(common/set-base-url.js):如果连接中填写了自定义
instanceUrl,则将其作为请求baseURL(适配自托管 Appwrite);否则回退到应用的apiBaseUrl,即https://cloud.appwrite.io(Appwrite Cloud)。 - addAuthHeader(common/add-auth-header.js):为请求设置
Content-Type: application/json,并从连接数据中读取projectId、apiKey与host,分别写入X-Appwrite-Project、X-Appwrite-Key与Host请求头——这正是 Appwrite REST API 的认证方式。
连接凭证字段与校验
要使用 New documents 触发器,你需要在 Automatisch 中先为 Appwrite 创建连接。认证字段定义见 auth/index.js:
| 字段 key | label | 必填 | 说明 |
|---|---|---|---|
| screenName | Screen Name | 是 | 连接在 UI 中显示的名称 |
| projectId | Project ID | 是 | Appwrite 项目的 ID |
| apiKey | API Key | 是 | Appwrite 项目的 API Key |
| instanceUrl | Appwrite instance URL | 否 | 自托管实例地址;留空则默认使用https://cloud.appwrite.io |
| host | Host Name | 是 | Appwrite 项目的 Host 名 |
创建连接时,verify-credentials.js 会通过一次GET /v1/users请求校验凭证有效性——如果该请求返回非 2xx,则连接创建失败,从源头保证后续触发器不会因无效凭证而反复报错。
实战场景与构建建议
结合以上机制,New documents 触发器适合以下自动化场景:
- 数据变更通知:Appwrite 集合中新增一条订单/工单文档后,自动通过 Slack、邮件或 Telegram 通知相关人员;
- 数据同步:新文档写入后,调用其他应用(如 Google Sheets、Airtable)同步记录;
- 后续处理流水线:新文档触发后,经过过滤/格式化步骤,调用 HTTP Request 或 AI 应用对内容做进一步加工。
实际构建时注意三点:其一,触发器采用 15 秒固定轮询间隔,对实时性要求极高的场景需评估延迟可接受度;其二,Database 与 Collection 下拉框由动态数据源实时填充,请确认连接凭证对应的账号对目标数据库、集合具备读取权限;其三,internalId去重基于文档$id,若业务上需要"同一文档被更新后再触发",则需要结合其他应用(如 Webhook 或定时触发器)设计增量方案,因为 New documents 仅面向新增文档。
参考文件索引
- 官方文档定义:packages/docs/pages/apps/appwrite/triggers.md
- 触发器实现:packages/backend/src/apps/appwrite/triggers/new-documents/index.js
- 触发器注册:packages/backend/src/apps/appwrite/triggers/index.js
- App 应用定义:packages/backend/src/apps/appwrite/index.js
- 连接认证字段与校验:packages/backend/src/apps/appwrite/auth/index.js、packages/backend/src/apps/appwrite/auth/verify-credentials.js
- 请求钩子:packages/backend/src/apps/appwrite/common/set-base-url.js、packages/backend/src/apps/appwrite/common/add-auth-header.js
- 动态数据源:packages/backend/src/apps/appwrite/dynamic-data/list-databases/index.js、packages/backend/src/apps/appwrite/dynamic-data/list-collections/index.js
- 触发器定义校验:packages/backend/src/helpers/define-trigger.js
【免费下载链接】automatischThe open source Zapier alternative. Build workflow automation without spending time and money.项目地址: https://gitcode.com/GitHub_Trending/au/automatisch
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考