defineLogicFunction
Logikfunktionen und deren Trigger definieren
defineLogicFunction
Logikfunktionen und deren Trigger definieren
Jede Funktionsdatei verwendet Verfügbare Trigger-Typen:Der Typ Greifen Sie in Ihrem Handler wie folgt auf die weitergeleiteten Header zu:Aus Sicherheitsgründen sind Antwort-Header auf eine Allowlist beschränkt. Jeder Header, der nicht auf der Liste steht (z. B. Der Endpoint ist erreichbar unter:Der Bezeichner ist der Resolver-Vertrag. Der Die Nutzlast umfasst:Beispiel für ein Created-Ereignis:Beispiel für ein Updated-Ereignis:Nur bei E-Mail-Aktualisierungen auslösen:Beispiel für ein Destroyed-Ereignis:Hauptpunkte:Um Ihre Parameter einmal zu deklarieren und beide Oberflächen zu bedienen, definieren Sie ein einziges JSON Schema (Sobald die App installiert ist, erscheint Enrich Company im Aktionswähler des Workflow-Builders. Der Builder rendert
defineLogicFunction(), um eine Konfiguration mit einem Handler und optionalen Triggern zu exportieren.src/logic-functions/createPostCard.logic-function.ts
- httpRoute: Stellt Ihre Funktion über einen HTTP-Pfad und eine Methode bereit. Im Anwendungscode den Routenpfad bei Verwendung von
RestApiClientmit dem Präfix/s/versehen; die bereitgestellte URL verwendet als Basis die injizierteTWENTY_FUNCTIONS_URL(oder\<server-url>/s, wenn diese nicht gesetzt ist).
Um eine routenausgelöste Logikfunktion von einer (headless) Front-Komponente aus aufzurufen, siehe Aufrufen einer Logikfunktion.
- cron: Führt Ihre Funktion nach Zeitplan mithilfe eines CRON-Ausdrucks aus.
- databaseEvent: Wird bei Lebenszyklusereignissen von Workspace-Objekten ausgeführt. Wenn die Ereignisoperation
updatedist, können bestimmte zu überwachende Felder im ArrayupdatedFieldsangegeben werden. Wenn das Array undefiniert oder leer ist, löst jede Aktualisierung die Funktion aus.
z. B.person.updated,*.created,company.*
- serverRoute: Stellt eine einzelne, registrierungsbezogene HTTP-Route bereit. Eine Resolver-Funktion (deklariert mit
serverRouteTriggerSettings) läuft im Owner-Workspace und gibt entweder eine synchroneResponsezurück oder den Ziel-Workspace UND die Ziel-Logikfunktion, die in die Queue eingereiht werden soll; auf dem Enqueue-Pfad bestätigt die Plattform mit202und führt dieses Ziel in der Worker-Queue aus. Siehe Server-Route-Trigger.
Sie können eine Funktion auch manuell über die CLI ausführen:Sie können Protokolle mit folgendem Befehl ansehen:
Routen-Trigger-Payload
Wenn ein Route-Trigger Ihre Logikfunktion aufruft, erhält sie einRoutePayload-Objekt, das dem AWS-HTTP-API-v2-Format folgt.
Importieren Sie den Typ RoutePayload aus twenty-sdk/logic-function:RoutePayload hat die folgende Struktur:forwardedRequestHeaders
Standardmäßig werden HTTP-Header von eingehenden Anfragen aus Sicherheitsgründen nicht an Ihre Logikfunktion weitergegeben. Um auf bestimmte Header zuzugreifen, listen Sie diese im ArrayforwardedRequestHeaders auf:Header-Namen werden in Kleinbuchstaben normalisiert. Greifen Sie mit Schlüsseln in Kleinbuchstaben darauf zu (z. B.
event.headers['content-type']).Benutzerdefinierte HTTP-Antwort
Standardmäßig sendet das Zurückgeben eines einfachen Werts aus Ihrem Handler diesen als200-Antwort zurück (JSON für Objekte, text/plain für Zeichenketten). Um den Statuscode und die Antwort-Header zu steuern, geben Sie eine Response aus twenty-sdk/logic-function zurück:Set-Cookie, CORS-Header wie Access-Control-Allow-Origin oder benutzerdefinierte X-*-Header), wird stillschweigend verworfen, bevor die Antwort gesendet wird. Die erlaubten Antwort-Header sind:content-typecontent-languagecontent-dispositioncache-controlretry-after
Der Statuscode muss ein gültiger HTTP-Statuscode sein (zwischen 100 und 599). Antwort-Header-Namen werden ohne Beachtung der Groß-/Kleinschreibung verglichen.
Server-Route-Trigger
httpRouteTriggerSettings stellt eine Funktion unter /s/ bereit und ermittelt den Workspace aus dem Host der Anfrage — was funktioniert, wenn jeder Workspace seine eigene Domain hat. Drittanbieter hingegen liefern die Ereignisse jedes Mandanten an eine URL. Für diesen Fall verwende serverRouteTriggerSettings.Der Trigger besteht aus zwei Teilen:-
Eine Resolver-Logikfunktion – deklariert mit
serverRouteTriggerSettings– läuft in deinem Owner-Workspace (dem Workspace, dem die Anwendungsregistrierung gehört). Sie inspiziert die eingehende Anfrage und gibt entweder Folgendes zurück:{ workspaceId, targetLogicFunctionUniversalIdentifier, payload? }— die Plattform reiht dieses Ziel im aufgelösten Workspace in die Queue ein und bestätigt mit202 { queued: true }, oder- eine
Responsevontwenty-sdk/logic-function— die Plattform gibt diese HTTP-Response synchron zurück und reiht kein Ziel in die Queue ein (verwende dies für Challenge-Handshakes wie Slackurl_verification).
rawBodyund weitergeleitete Header und kann ablehnen, ohne jemals das Ziel zu berühren. - Eine Target-Logikfunktion – eine reguläre, Workspace-spezifische Logikfunktion – läuft dann im aufgelösten Workspace mit dem Payload, der vom Resolver zurückgegeben wurde (oder dem ursprünglichen Anfrage-Payload, falls der Resolver ihn nicht transformiert hat). Sein Rückgabewert wird vom HTTP-Aufrufer nicht beobachtet, wenn der Resolver den Enqueue-Pfad gewählt hat.
src/logic-functions/resolve-server-route.logic-function.ts
src/logic-functions/handle-invoice-paid.logic-function.ts
universalIdentifier des Resolvers aus deinem Manifest. Registriere diese URL beim Provider.Die Anwendung muss beansprucht und im Arbeitsbereich ihres Besitzers installiert werden. Da der Resolver im Owner-Arbeitsbereich ausgeführt wird (dem Arbeitsbereich, der die Anwendungsregistrierung besitzt), funktioniert ein Server-Route-Trigger nur, wenn die Anwendung beansprucht wurde – d. h. sie einen Owner-Arbeitsbereich hat – und diese Anwendung im Owner-Arbeitsbereich installiert ist. Solange beides nicht zutrifft, hat der Resolver keinen Ausführungsort, sodass die Route nicht ausgeführt werden kann. Eine Anwendung, die eine
serverRouteTriggerSettings-Logikfunktion bereitstellt, kann daher nicht im Marketplace aufgeführt werden, bevor sie beansprucht und im Owner-Arbeitsbereich installiert wurde.LogicFunctionConfig-Typ des SDK erzwingt dies zur Compile-Zeit: Sobald du serverRouteTriggerSettings setzt, ist dein Handler darauf beschränkt, entweder eine Response oder { workspaceId: string; targetLogicFunctionUniversalIdentifier: string; payload?: object } zurückzugeben (oder ein Promise von einem der beiden). Auf dem Dispatch-Pfad muss die workspaceId auf einen Workspace verweisen, in dem die Zielfunktion installiert ist, andernfalls wird die Anfrage mit 404 abgelehnt. Ein Ergebnis, das keiner der beiden Formen entspricht – einschließlich eines Ergebnisses, dessen Bezeichner keine UUIDs sind – wird mit 502 abgelehnt.Für Anfragesignaturen signieren die meisten Provider mit HMAC-SHA256; die Teile, die sich unterscheiden, sind der Header-Name, die Digest-Codierung und der signierte Payload-String. Einige Beispiele:
Das obige Resolver-Beispiel zeigt bereits den GitHub-HMAC-SHA256-Flow – passe den Header-Namen, die Digest-Codierung und den signierten Payload-String entsprechend dem Provider an, den du integrierst.
Wenn der Resolver ein Dispatch-Objekt zurückgibt, antwortet die Route mit
202 { queued: true } und das Ziel wird in der Worker-Queue ausgeführt – der Aufrufer bekommt weder die Latenz, noch das Ergebnis oder Fehler des Ziels mit (diese werden in den Ausführungsprotokollen aufgezeichnet). Dadurch wird verhindert, dass erneute Zustellungen des Senders Verarbeitungsverzögerungen verstärken – genau das ist bei der Erfassung von Webhooks erwünscht.Wenn der Aufrufer den Response-Body in derselben Anfrage lesen muss (Challenge-Handshakes, interaktive Bestätigungen), gib stattdessen eine Response aus dem Resolver zurück. Die Plattform gibt sie synchron zurück und überspringt die Queue; ihre Header durchlaufen dieselbe Allow-Liste wie HTTP-Routen-Antworten. Halten Sie den Resolver schnell – einige Provider (z. B. Slack) laufen nach wenigen Sekunden in ein Timeout. Da der Resolver als öffentlicher Endpoint erreichbar ist, schütze ihn mit Rate-Limiting an deinem Edge.Datenbank-Event-Trigger-Payload
Wenn ein Datenbank-Event-Trigger Ihre Logic Function aufruft, erhält sie eineDatabaseEventPayload pro geändertem Datensatz. Die Payload kombiniert Metadaten über den Quell-Workspace und das Objekt mit dem Ereignis auf Datensatzebene.Bei Soft Deletes folgt
.deleted der Aktualisierungsstruktur, da sich das Feld deletedAt des Datensatzes ändert.
Für dauerhafte Löschvorgänge verwende .destroyed.databaseEventTriggerSettings.updatedFields filtert, welche Aktualisierungsereignisse die Funktion auslösen.
event.properties.updatedFields gibt an, welche Felder beim aktuellen Ereignis tatsächlich geändert wurden.Eine Funktion als KI-Tool oder Workflow-Aktion verfügbar machen
Logikfunktionen können auf zwei Oberflächen verfügbar gemacht werden, jeweils mit eigenem Trigger:toolTriggerSettings— macht die Funktion über die KI-Funktionen von Twenty (Chat, MCP, Funktionsaufrufe) auffindbar. Verwendet das standardmäßige JSON Schema, das Format, das LLMs nativ verstehen.workflowActionTriggerSettings— lässt die Funktion als Schritt im visuellen Workflow-Builder erscheinen. Verwendet das umfangreicheInputSchemavon Twenty, sodass der Builder geeignete Feldeditoren, Variablenauswahlen und Beschriftungen rendern kann.
cronTriggerSettings, databaseEventTriggerSettings und httpRouteTriggerSettings — gleiches Muster, gleiche Struktur.Beziehung zur Code-Aktion im Workflow. Die integrierte Code-Aktion im Workflow-Builder ist selbst eine Logikfunktion – Twenty erstellt für jeden Code-Schritt eine Logikfunktion und stellt deren Editor inline bereit.
workflowActionTriggerSettings ist die Art und Weise, wie Sie diesen einmaligen Inline-Code in eine wiederverwendbare Aktion verwandeln: Definieren Sie die Funktion einmal in Ihrer App, und sie wird in jedem Workflow auswählbar, anstatt in jeden Code-Schritt kopiert zu werden. Siehe die Code-Aktion im Benutzerhandbuch für die Endbenutzeransicht.src/logic-functions/enrich-company.logic-function.ts
- Eine Funktion kann Oberflächen mischen — deklarieren Sie sowohl
toolTriggerSettingsals auchworkflowActionTriggerSettings, um sie im Chat UND im Workflow-Builder bereitzustellen. toolTriggerSettings.inputSchemaundworkflowActionTriggerSettings.inputSchemasind beide optional. Wenn sie weggelassen werden, leitet der Manifest-Builder sie aus dem Handler-Quellcode ab (JSON Schema für das KI-Tool, dasInputSchemavon Twenty für die Workflow-Aktion). Geben Sie eines explizit an, wenn Sie eine reichere Typisierung wünschen — zum Beispiel mitFieldMetadataType-fähigen Feldern wieCURRENCYoderRELATIONfür den Workflow-Builder oder mitdescription-Feldern, die der KI-Agent lesen kann:
InputJsonSchema) und konvertieren Sie es für die Workflow-Aktion mit jsonSchemaToInputSchema aus twenty-sdk/logic-function. toolTriggerSettings.inputSchema nimmt das JSON Schema direkt, während workflowActionTriggerSettings.inputSchema das InputSchema von Twenty erwartet:Ein vollständiges Beispiel für eine Workflow-Aktion
workflowActionTriggerSettings akzeptiert vier Felder:Alles zusammen – eine Funktion, die als Workflow-Aktion bereitgestellt wird, mit einer deklarierten Ausgabe, damit spätere Schritte auf
taskId verweisen können:src/logic-functions/enrich-company.logic-function.ts
companyName und domain als Eingabefelder (die jeweils Werte aus vorherigen Schritten beziehen können), und nachgelagerte Schritte können auf die taskId- und enriched-Ausgaben des Schritts verweisen.Schreiben Sie eine gute
description. KI-Agenten verlassen sich auf das description-Feld der Funktion, um zu entscheiden, wann das Tool verwendet werden soll. Seien Sie konkret darin, was das Tool tut und wann es aufgerufen werden soll.Runtime-Hilfsfunktionen.
twenty-sdk/utils exportiert kleine Runtime-Hilfsfunktionen erneut, sodass Handler niemals direkt aus twenty-shared importieren. Zum Beispiel gibt isDefined(value) sowohl für null als auch für undefined den Wert false zurück – verwenden Sie es, um optionale Handler-Eingaben sicher einzugrenzen, die zur Laufzeit als null ankommen können, selbst wenn sie als T | undefined typisiert sind:Installations-Hooks – Vorinstallations-, Nachinstallations- und Deinstallations-Handler – teilen sich diese Laufzeit, werden aber mit ihren eigenen define-Funktionen deklariert und verwenden keine Trigger-Einstellungen. Siehe Installations-Hooks für
definePreInstallLogicFunction, definePostInstallLogicFunction und defineUninstallLogicFunction.Typisierte API-Clients (twenty-client-sdk)
Das Pakettwenty-client-sdk stellt zwei typisierte GraphQL-Clients bereit, um aus Ihren Logikfunktionen und Frontend-Komponenten mit der Twenty-API zu interagieren.
CoreApiClient
Arbeitsbereichsdaten (Datensätze, Objekte) abfragen und ändern
CoreApiClient
Arbeitsbereichsdaten (Datensätze, Objekte) abfragen und ändern
Der Der Client verwendet eine Selection-Set-Syntax: Übergeben Sie
CoreApiClient ist der Haupt-Client zum Abfragen und Ändern von Arbeitsbereichsdaten. Er wird während yarn twenty dev oder yarn twenty dev:build aus Ihrem Arbeitsbereichsschema generiert und ist daher vollständig typisiert, passend zu Ihren Objekten und Feldern.true, um ein Feld einzuschließen, verwenden Sie __args für Argumente, und verschachteln Sie Objekte für Relationen. Sie erhalten vollständige Autovervollständigung und Typprüfung basierend auf Ihrem Arbeitsbereichsschema.Der CoreApiClient wird zur Entwicklungs-/Build-Zeit generiert. Wenn Sie ihn verwenden, ohne zuvor
yarn twenty dev oder yarn twenty dev:build ausgeführt zu haben, wird ein Fehler ausgelöst. Die Generierung erfolgt automatisch — die CLI inspiziert das GraphQL-Schema Ihres Arbeitsbereichs und erzeugt mit @genql/cli einen typisierten Client.Verwendung von CoreSchema für Typannotationen
CoreSchema stellt TypeScript-Typen bereit, die Ihren Arbeitsbereichsobjekten entsprechen — nützlich zum Typisieren von Komponentenzustand oder Funktionsparametern:MetadataApiClient
Konfiguration des Arbeitsbereichs, Anwendungen und Dateiuploads
MetadataApiClient
Konfiguration des Arbeitsbereichs, Anwendungen und Dateiuploads
MetadataApiClient ist im SDK bereits vorgefertigt enthalten (keine Generierung erforderlich). Er fragt den Endpunkt /metadata nach Arbeitsbereichskonfiguration, Anwendungen und Datei-Uploads ab.Dateien hochladen
DerMetadataApiClient enthält eine Methode uploadFile, um Dateien an Felder des Typs Datei anzuhängen:Hauptpunkte:
- Sie verwendet den
universalIdentifierdes Feldes (nicht dessen arbeitsbereichsspezifische ID), sodass Ihr Upload-Code in jedem Arbeitsbereich funktioniert, in dem Ihre App installiert ist. - Die zurückgegebene
urlist eine signierte URL, mit der Sie auf die hochgeladene Datei zugreifen können.
Wenn Ihr Code auf Twenty ausgeführt wird (Logikfunktionen oder Frontend-Komponenten), injiziert die Plattform Anmeldedaten als Umgebungsvariablen:
TWENTY_API_URL— Basis-URL der Twenty-APITWENTY_APP_ACCESS_TOKEN— Kurzlebiger Schlüssel, der auf die Standard-Funktionsrolle Ihrer Anwendung begrenzt ist
process.env. Die Berechtigungen des API-Schlüssels werden durch die Rolle bestimmt, die mit defineApplicationRole() deklariert wird (oder über defaultRoleUniversalIdentifier in application-config.ts referenziert wird).