defineLogicFunction
ロジック関数とそのトリガーを定義
defineLogicFunction
ロジック関数とそのトリガーを定義
各関数ファイルは、ハンドラーと任意のトリガーを含む設定を 利用可能なトリガーの種類:ハンドラー内では、転送されたヘッダーに次のようにアクセスします:セキュリティ上の理由から、レスポンスヘッダーは許可リストに限定されています。 リストに含まれていないヘッダー(例: エンドポイントには次の URL でアクセスできます:識別子は、マニフェストに記載されている resolver の Resolver の契約。 SDK の ペイロードには次のものが含まれます:作成イベントの例:更新イベントの例:メール更新時のみトリガーする例:削除イベントの例:主なポイント:パラメーターを一度だけ宣言して両方のサーフェスで利用できるようにするには、単一の JSON Schema(アプリがインストールされると、ワークフロービルダーのアクションピッカーに Enrich Company が表示されます。 ビルダーは
defineLogicFunction() でエクスポートします。src/logic-functions/createPostCard.logic-function.ts
- httpRoute:HTTP のパスとメソッドで関数を公開します。 アプリのコードでは、
RestApiClientを使用する際、ルートパスの先頭に/s/を付けてください。デプロイ後の URL では、TWENTY_FUNCTIONS_URLで注入されたベース URL が使用され、未設定の場合は\<server-url>/sが使用されます。
(ヘッドレスの)フロントコンポーネントからルートトリガー型ロジック関数を呼び出す方法については、ロジック関数を呼び出すを参照してください。
- cron: CRON 式を使用してスケジュールで関数を実行します。
- databaseEvent: ワークスペースのオブジェクトのライフサイクルイベントで実行されます。 イベント操作が
updatedの場合、監視する特定のフィールドをupdatedFields配列で指定できます。 未定義または空のままにすると、任意の更新でも関数がトリガーされます。
例:person.updated、*.created、company.*
- serverRoute: 1 つの登録スコープの HTTP ルートを公開します。 resolver 関数(
serverRouteTriggerSettingsで宣言)は、オーナーワークスペースで実行され、同期的なResponseを返すか、ターゲットワークスペースとエンキューする対象のロジック関数を返します。エンキュールートでは、プラットフォームは202で ACK し、その target をワーカーキュー上で実行します。 サーバールートトリガー を参照してください。
CLI を使用して、関数を手動で実行することもできます:ログは次のコマンドで監視できます:
ルートトリガーのペイロード
ルートトリガーがロジック関数を呼び出すと、 AWS HTTP API v2 形式 に従うRoutePayload オブジェクトを受け取ります。
RoutePayload 型を twenty-sdk/logic-function からインポートします:RoutePayload 型は次の構造になっています:forwardedRequestHeaders
デフォルトでは、セキュリティ上の理由から、受信リクエストの HTTP ヘッダーはロジック関数に渡されません。 特定のヘッダーにアクセスするには、forwardedRequestHeaders 配列に明示的に列挙してください:ヘッダー名は小文字に正規化されます。 小文字のキーを使用してアクセスしてください(例:
event.headers['content-type'])。カスタム HTTP レスポンス
デフォルトでは、ハンドラーからプレーンな値を返すと、それが200 レスポンスとして送信されます(オブジェクトの場合は JSON、文字列の場合は text/plain)。 ステータスコードとレスポンスヘッダーを制御するには、twenty-sdk/logic-function から Response を返します。Set-Cookie、Access-Control-Allow-Origin などの CORS ヘッダー、カスタム X-* ヘッダー)は、レスポンスが送信される前に暗黙的に削除されます。 許可されているレスポンスヘッダーは次のとおりです。content-typecontent-languagecontent-dispositioncache-controlretry-after
ステータスコードは、有効な HTTP ステータスコード(100 から 599 の間)でなければなりません。 レスポンスヘッダー名は、大文字と小文字を区別せずに照合されます。
プラットフォームのエラー応答
ハンドラー自身のレスポンス以外に、いくつかの状況ではプラットフォームがルート呼び出しに直接応答します。ルートまたは関数が存在しない場合は404、アプリケーションが停止している場合は 403、実行レート制限に達した場合は 429、アプリケーションの本番用 dependencies が大きすぎてインストールできない場合は 422 が返されます。詳しくは dependencies size limits を参照してください。サーバールートトリガー
httpRouteTriggerSettings は /s/ 配下に関数を公開し、リクエストホストからワークスペースを特定します。これは、各ワークスペースが独自ドメインを持つ場合に機能します。 しかし、サードパーティプロバイダーは、すべてのテナントのイベントを 1 つの URL に配信します。 その場合は、serverRouteTriggerSettings を使用します。トリガーには 2 つの構成要素があります:-
resolver ロジック関数 —
serverRouteTriggerSettingsで宣言される — は、オーナーワークスペース(アプリケーション登録を所有するワークスペース)で実行されます。 この関数は受信リクエストを検査し、次のいずれかを返します。{ workspaceId, targetLogicFunctionUniversalIdentifier, payload? }— プラットフォームは解決済みワークスペースでその target をキューに入れ、202 { queued: true }で ACK します、またはtwenty-sdk/logic-functionからのResponse— プラットフォームはその HTTP レスポンスを同期的にエコーし、ターゲットをキューに入れることはありません(Slack のurl_verificationのようなチャレンジハンドシェイクに使用します)。
rawBodyと転送されたヘッダーにアクセスでき、ターゲットに一切触れずにリクエストを拒否できます。 - target ロジック関数 — 通常のワークスペース単位のロジック関数 — は、その後、resolver によって解決されたワークスペースで、resolver が返したペイロード(resolver が変換しなかった場合は元のリクエストペイロード)を使って実行されます。 resolver が enqueue パスを選択した場合、その戻り値は HTTP 呼び出し元からは観測されません。
src/logic-functions/resolve-server-route.logic-function.ts
src/logic-functions/handle-invoice-paid.logic-function.ts
universalIdentifier です。 その URL をプロバイダーに登録します。アプリケーションは所有者ワークスペースでクレームされ、インストールされている必要があります。 リゾルバーは 所有者ワークスペース(アプリケーション登録を所有しているワークスペース)上で実行されるため、サーバールートトリガーが動作するのは、アプリケーションがクレームされている、つまり所有者ワークスペースを持っていること かつ そのアプリケーションが 所有者ワークスペースにインストールされている 場合のみです。 この2つの条件がどちらも満たされるまでは、リゾルバーを実行する場所が存在しないため、ルートをディスパッチできません。 したがって、
serverRouteTriggerSettings ロジック関数を公開するアプリケーションは、所有者ワークスペースでクレームされインストールされるまで、マーケットプレイスに掲載することはできません。LogicFunctionConfig 型はコンパイル時にこれを強制します。serverRouteTriggerSettings を設定するとすぐに、ハンドラーは Response か、{ workspaceId: string; targetLogicFunctionUniversalIdentifier: string; payload?: object }(またはそのいずれかの Promise)を返すように制約されます。 dispatch パスでは、workspaceId は target 関数がインストールされているワークスペースである必要があります。そうでない場合、リクエストは 404 で拒否されます。 どちらの形にも一致しない結果(識別子が UUID でないものを含む)は、502 で拒否されます。リクエスト署名については、ほとんどのプロバイダーが HMAC-SHA256 で署名します。異なるのはヘッダー名、ダイジェストのエンコーディング、および署名対象となるペイロード文字列です。 いくつかの例を示します。
上記の resolver の例では、すでに GitHub の HMAC-SHA256 フローを示しています。連携するプロバイダーに合わせて、ヘッダー名、ダイジェストのエンコーディング、および署名対象となるペイロード文字列を調整してください。
resolver が dispatch オブジェクトを返すと、ルートは
202 { queued: true } を返し、target はワーカーキュー上で実行されます。呼び出し元は target のレイテンシ、結果、失敗を一切観測しません(それらは実行ログに記録されます)。 これにより、送信側の再配信によって処理の遅延が増幅されるのを防げます。これは、Webhook 取り込みにおいて望ましい動作です。呼び出し元が同じリクエストでレスポンスボディを読み取る必要がある場合(チャレンジハンドシェイク、対話的な受領確認など)、代わりに resolver から Response を返してください。 プラットフォームはそれを同期的にエコーし、キューをスキップします。そのヘッダーは HTTP ルートレスポンスと同じ許可リストを通過します。 resolver は高速に保ってください。Slack など一部のプロバイダーは数秒でタイムアウトします。 resolver はパブリックエンドポイントとして到達可能であるため、エッジでレート制限をかけて保護してください。データベースイベントトリガーのペイロード
データベースイベントトリガーがロジック関数を呼び出すと、変更されたレコードごとに 1 つのDatabaseEventPayload を受け取ります。 このペイロードは、ソースワークスペースとオブジェクトに関するメタデータを、レコードレベルのイベントと組み合わせたものです。ソフトデリートの場合、レコードの
deletedAt フィールドが変化するため、.deleted はアップデート時と同じ形式になります。
完全な削除の場合は .destroyed を使用します。databaseEventTriggerSettings.updatedFields は、どの更新イベントで関数をトリガーするかをフィルタリングします。
event.properties.updatedFields は、現在のイベントで実際にどのフィールドが変更されたかを示します。関数を AI ツールまたはワークフロー アクションとして公開する
ロジック関数は 2 つのサーフェス上で公開でき、それぞれに固有のトリガーがあります:toolTriggerSettings— Twenty の AI 機能(チャット、MCP、関数呼び出し)からその関数を見つけられるようにします。 標準的な JSON Schema を使用します。これは LLM がネイティブに理解する形式です。workflowActionTriggerSettings— ビジュアル ワークフロー ビルダー内のステップとして関数を表示します。 ビルダーが適切なフィールドエディタ、変数ピッカー、ラベルをレンダリングできるよう、Twenty の充実したInputSchemaを使用します。
cronTriggerSettings、databaseEventTriggerSettings、httpRouteTriggerSettings と並列に存在します — 同じパターン、同じ形です。ワークフローの Code アクションとの関係。 ワークフロービルダーに組み込まれている Code アクション自体もロジック関数です。Twenty は Code ステップごとに 1 つ作成し、そのエディタをインラインで表示します。
workflowActionTriggerSettings を使うことで、その使い捨てのインラインコードを再利用可能なアクションに変換できます。アプリ内でその関数を 1 度定義すれば、各 Code ステップにコードをコピーペーストする代わりに、任意のワークフローで選択できるようになります。 エンドユーザー側の表示については、ユーザーガイドの Code action を参照してください。src/logic-functions/enrich-company.logic-function.ts
- 関数はサーフェスを混在させることができます —
toolTriggerSettingsとworkflowActionTriggerSettingsの両方を宣言して、チャットおよびワークフロー ビルダーの両方に公開します。 toolTriggerSettings.inputSchemaとworkflowActionTriggerSettings.inputSchemaはいずれも任意です。 省略された場合、マニフェストビルダーはハンドラーのソースコードからそれらを推論します(AI ツールには JSON Schema、ワークフロー アクションには Twenty のInputSchema)。 より豊富な型付けが必要な場合は、明示的に指定してください — たとえば、ワークフロー ビルダー向けにCURRENCYやRELATIONといったFieldMetadataTypeに対応したフィールド、または AI エージェントが読み取れるdescriptionフィールドを使用する場合など:
InputJsonSchema)を定義し、twenty-sdk/logic-function の jsonSchemaToInputSchema を使ってワークフローアクション用に変換します。 toolTriggerSettings.inputSchema は JSON Schema を直接受け取りますが、workflowActionTriggerSettings.inputSchema には Twenty の InputSchema が必要です。ワークフローアクションの完全な例
workflowActionTriggerSettings は 4 つのフィールドを受け取ります:これらを組み合わせると、ワークフローアクションとして公開される関数になり、
taskId を後続ステップから参照できるように出力を宣言できます。src/logic-functions/enrich-company.logic-function.ts
companyName と domain を入力フィールドとしてレンダリングします(それぞれが前のステップから値を取得可能)、さらに下流のステップでは、そのステップの taskId と enriched の出力を参照できます。良い
description を記述してください。 AI エージェントは、ツールをいつ使用するかを判断するために関数の description フィールドに依存します。 ツールが何を行い、いつ呼び出すべきかを具体的に記述してください。ランタイムヘルパー。
twenty-sdk/utils は、小さなランタイムヘルパーを再エクスポートすることで、ハンドラーが直接 twenty-shared からインポートする必要がないようにします。 たとえば、isDefined(value) は null と undefined の両方に対して false を返します。これを使うと、オプショナルなハンドラー入力を安全に絞り込めます。こうした入力は、型としては T | undefined であっても、実行時には null として渡される場合があります。インストールフック — pre-install、post-install、uninstall の各ハンドラー — はこのランタイムを共有しますが、それぞれ独自の define 関数で宣言され、トリガー設定は受け取りません。
definePreInstallLogicFunction、definePostInstallLogicFunction、defineUninstallLogicFunction については、インストールフック を参照してください。型付き API クライアント(twenty-client-sdk)
twenty-client-sdk パッケージは、ロジック関数やフロントコンポーネントから Twenty API とやり取りするための、型付き GraphQL クライアントを 2 つ提供します。
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 メソッドが含まれています:主なポイント:
- フィールドの
universalIdentifier(ワークスペース固有の ID ではありません)を使用するため、アップロードコードはアプリがインストールされている任意のワークスペースで動作します。 - 返される
urlは、アップロード済みファイルにアクセスするために使用できる署名付き URL です。
コードが Twenty 上で実行される際(ロジック関数やフロントコンポーネント)、プラットフォームは認証情報を環境変数として注入します:
TWENTY_API_URL— Twenty API のベース URLTWENTY_APP_ACCESS_TOKEN— アプリケーションのデフォルト関数ロールにスコープされた短命のキー
process.env から読み取ります。 API キーの権限は、defineApplicationRole() で宣言されたロール(または application-config.ts の defaultRoleUniversalIdentifier で参照されるロール)によって決まります。