defineLogicFunction
定义逻辑函数及其触发器
defineLogicFunction
定义逻辑函数及其触发器
每个函数文件都使用 可用的触发器类型:
在你的处理程序中,可以这样访问被转发的请求头:出于安全原因,响应头被限制在一个允许列表中。 任何不在该列表中的响应头(例如 有效负载包括:
对于软删除,创建事件示例:更新事件示例:仅在 email 更新时触发:销毁事件示例:关键点:
defineLogicFunction() 导出包含处理程序和可选触发器的配置。src/logic-functions/createPostCard.logic-function.ts
- httpRoute:在
/s/端点下通过 HTTP 路径和方法公开你的函数:
例如path: '/post-card/create'可在https://your-twenty-server.com/s/post-card/create调用
要从(无头)前端组件调用由路由触发的逻辑函数,请参见调用逻辑函数。
- cron:使用 CRON 表达式按计划运行你的函数。
- databaseEvent:在工作区对象生命周期事件上运行。 当事件操作为
updated时,可以在updatedFields数组中指定要监听的特定字段。 如果未定义或为空,任何更新都会触发该函数。
例如person.updated、*.created、company.*
你也可以使用 CLI 手动执行函数:你可以通过以下方式查看日志:
路由触发器负载
当路由触发器调用你的逻辑函数时,它会接收一个遵循 AWS HTTP API v2 格式的RoutePayload 对象。
从 twenty-sdk/logic-function 导入 RoutePayload 类型:RoutePayload 类型具有以下结构:| 属性 | 类型 | 描述 | 示例 |
|---|---|---|---|
headers | Record\<string, string | undefined> | HTTP 请求头(仅限 forwardedRequestHeaders 中列出的那些) | 见下文 |
queryStringParameters | Record\<string, string | undefined> | 查询字符串参数(多个值以逗号连接) | /users?ids=1&ids=2&ids=3&name=Alice -> { ids: '1,2,3', name: 'Alice' } |
pathParameters | Record\<string, string | undefined> | 从路由模式中提取的路径参数 | /users/:id,/users/123 -> { id: '123' } |
body | object | null | 已解析的请求体(JSON) | { id: 1 } -> { id: 1 } |
rawBody | string | undefined | 在 JSON 解析之前的原始 UTF-8 请求体。 用于验证 HMAC 风格的 Webhook 签名(例如 GitHub 的 X-Hub-Signature-256、Stripe)。 当运行时未保留它时为 undefined。 | |
isBase64Encoded | boolean | 请求体是否为 base64 编码 | |
requestContext.http.method | string | HTTP 方法(GET、POST、PUT、PATCH、DELETE) | |
requestContext.http.path | string | 原始请求路径 |
forwardedRequestHeaders
出于安全原因,默认不会将传入请求的 HTTP 请求头传递给你的逻辑函数。 如需访问特定请求头,请在forwardedRequestHeaders 数组中显式列出:请求头名称会被规范化为小写。 请使用小写键访问它们(例如,
event.headers['content-type'])。自定义 HTTP 响应
默认情况下,从处理程序返回一个普通值会以200 响应返回该值(对象为 JSON,字符串为 text/plain)。 要控制状态码和响应头,请从 twenty-sdk/logic-function 返回一个 Response:Set-Cookie、CORS 响应头(如 Access-Control-Allow-Origin),或自定义的 X-* 响应头)都会在发送响应之前被静默丢弃。 允许的响应头包括:content-typecontent-languagecontent-dispositioncache-controlretry-after
状态码必须是有效的 HTTP 状态码(介于 100 和 599 之间)。 响应头名称的匹配不区分大小写。
数据库事件触发器有效负载
当数据库事件触发器调用你的逻辑函数时,每条被更改的记录都会对应一个DatabaseEventPayload。 该负载将关于源工作区和对象的元数据与记录级事件组合在一起。| 属性 | 描述 |
|---|---|
name | 事件名称,例如 person.updated。 |
workspaceId | 事件发生的工作区。 |
objectMetadata | 已更改对象的元数据。 |
recordId | 已更改记录的 ID。 |
userId, userWorkspaceId, workspaceMemberId | 当事件由工作区用户触发时的操作者字段。 |
properties | 事件的记录数据,根据操作不同,包含 before、after、diff 和 updatedFields。 |
| 事件 | 记录数据 |
|---|---|
person.created | event.properties.after |
person.updated | event.properties.before, event.properties.after, event.properties.diff, event.properties.updatedFields |
person.destroyed | event.properties.before |
.deleted 遵循更新样式的结构,因为记录的 deletedAt 字段发生了变化。
对于永久删除,请使用 .destroyed。databaseEventTriggerSettings.updatedFields 会筛选出哪些更新事件会触发该函数。
event.properties.updatedFields 告诉你在当前事件中哪些字段实际发生了变化。将函数公开为 AI 工具或工作流操作
逻辑函数可以在两个入口对外公开,每个入口都有各自的触发器:toolTriggerSettings— 使该函数可被 Twenty 的 AI 功能(chat、MCP、function calling)发现。 使用标准 JSON Schema,LLM 能够原生理解的格式。workflowActionTriggerSettings— 使该函数在可视化工作流构建器中显示为一个步骤。 使用 Twenty 丰富的InputSchema,以便构建器可以呈现合适的字段编辑器、变量选择器和标签。
cronTriggerSettings、databaseEventTriggerSettings 和 httpRouteTriggerSettings 并列 — 相同的模式、相同的结构。src/logic-functions/enrich-company.logic-function.ts
- 函数可以混用这些入口 — 同时声明
toolTriggerSettings和workflowActionTriggerSettings,即可在 chat 和工作流构建器中同时公开它。 toolTriggerSettings.inputSchema和workflowActionTriggerSettings.inputSchema均为可选。 如果省略,清单构建器会根据处理器源代码进行推断(AI 工具使用 JSON Schema,工作流操作使用 Twenty 的InputSchema)。 当你需要更丰富的类型时,可显式提供一个 — 例如,在工作流构建器中使用对FieldMetadataType友好的字段(如CURRENCY或RELATION),或提供 AI 智能体可读取的description字段:
写一个好的
description。 AI 智能体会依赖该函数的 description 字段来决定何时使用该工具。 明确说明该工具的作用以及应在何时调用。安装 hooks——预安装和后安装处理程序——共享此运行时,但使用它们自己的 define 函数进行声明,并且不接受触发器设置。 有关
definePreInstallLogicFunction 和 definePostInstallLogicFunction,请参阅 Install Hooks。类型化 API 客户端(twenty-client-sdk)
twenty-client-sdk 包提供了两个类型化的 GraphQL 客户端,供你的逻辑函数和前端组件与 Twenty API 交互。
| 客户端 | 导入 | 端点 | 是否生成? |
|---|---|---|---|
CoreApiClient | twenty-client-sdk/core | /graphql——工作区数据(记录、对象) | 是,在开发/构建时 |
MetadataApiClient | twenty-client-sdk/metadata | /metadata——工作区配置、文件上传 | 否,已预构建提供 |
CoreApiClient
查询和变更工作区数据(记录、对象)
CoreApiClient
查询和变更工作区数据(记录、对象)
CoreApiClient 是用于查询和变更工作区数据的主要客户端。 它会在执行 yarn twenty dev 或 yarn twenty dev:build 时根据你的工作区架构生成,因此具有完整的类型定义以匹配你的对象和字段。true 以包含某字段,使用 __args 传递参数,并通过嵌套对象表示关系。 你将基于工作区架构获得完整的自动补全和类型检查。CoreApiClient 在开发/构建时生成。 如果在未先运行
yarn twenty dev 或 yarn twenty dev:build 的情况下尝试使用它,将会抛出错误。 该生成过程是自动完成的——CLI 会自省你的工作区 GraphQL 架构,并使用 @genql/cli 生成类型化客户端。使用 CoreSchema 进行类型标注
CoreSchema 提供与工作区对象相匹配的 TypeScript 类型,可用于为组件状态或函数参数进行类型标注:MetadataApiClient
工作区配置、应用和文件上传
MetadataApiClient
工作区配置、应用和文件上传
MetadataApiClient 随 SDK 一并提供,已预构建(无需生成)。 它会查询 /metadata 端点以获取工作区配置、应用和文件上传。上传文件
MetadataApiClient 包含一个 uploadFile 方法,用于将文件附加到文件类型字段:| 参数 | 类型 | 描述 |
|---|---|---|
fileBuffer | Buffer | 原始文件内容 |
filename | string | 文件名称(用于存储和显示) |
contentType | string | MIME 类型(如果省略,默认为 application/octet-stream) |
fieldMetadataUniversalIdentifier | string | 你的对象上文件类型字段的 universalIdentifier |
- 使用字段的
universalIdentifier(而不是其工作区特定的 ID),因此你的上传代码可在安装了你的应用的任何工作区中运行。 - 返回的
url是一个签名 URL,你可以用它来访问已上传的文件。
当你的代码在 Twenty 上运行(逻辑函数或前端组件)时,平台会以环境变量的形式注入凭据:
TWENTY_API_URL——Twenty API 的基础 URLTWENTY_APP_ACCESS_TOKEN——作用域限定为你的应用默认函数角色的短期密钥
process.env 读取。 API 密钥的权限由使用 defineApplicationRole() 声明的角色(或在 application-config.ts 中通过 defaultRoleUniversalIdentifier 引用的角色)决定。