Zum Hauptinhalt springen
Logic functions are server-side TypeScript functions that run on the Twenty platform. They can be triggered by HTTP requests, cron schedules, or database events — and can also be exposed as tools for AI agents.
Jede Funktionsdatei verwendet defineLogicFunction(), um eine Konfiguration mit einem Handler und optionalen Triggern zu exportieren.
src/logic-functions/createPostCard.logic-function.ts
import { defineLogicFunction } from 'twenty-sdk/define';
import type { DatabaseEventPayload, ObjectRecordCreateEvent, CronPayload, RoutePayload } from 'twenty-sdk/define';
import { CoreApiClient, type Person } from 'twenty-client-sdk/core';

const handler = async (params: RoutePayload) => {
  const client = new CoreApiClient();
  const name = 'name' in params.queryStringParameters
    ? params.queryStringParameters.name ?? process.env.DEFAULT_RECIPIENT_NAME ?? 'Hello world'
    : 'Hello world';

  const result = await client.mutation({
    createPostCard: {
      __args: { data: { name } },
      id: true,
      name: true,
    },
  });
  return result;
};

export default defineLogicFunction({
  universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf',
  name: 'create-new-post-card',
  timeoutSeconds: 2,
  handler,
  httpRouteTriggerSettings: {
    path: '/post-card/create',
    httpMethod: 'GET',
    isAuthRequired: true,
  },
  /*databaseEventTriggerSettings: {
    eventName: 'people.created',
  },*/
  /*cronTriggerSettings: {
    pattern: '0 0 1 1 *',
  },*/
});
Verfügbare Trigger-Typen:
  • httpRoute: Stellt Ihre Funktion unter einem HTTP-Pfad und einer Methode unter dem Endpunkt /s/ bereit:
z. B. path: '/post-card/create' ist unter https://your-twenty-server.com/s/post-card/create aufrufbar
  • cron: Führt Ihre Funktion nach Zeitplan mithilfe eines CRON-Ausdrucks aus.
  • databaseEvent: Wird bei Lebenszyklusereignissen von Workspace-Objekten ausgeführt. Wenn die Ereignisoperation updated ist, können bestimmte zu überwachende Felder im Array updatedFields angegeben werden. Wenn das Array undefiniert oder leer ist, löst jede Aktualisierung die Funktion aus.
z. B. person.updated, *.created, company.*
Sie können eine Funktion auch manuell über die CLI ausführen:
yarn twenty exec -n create-new-post-card -p '{"key": "value"}'
yarn twenty exec -y e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf
Sie können Protokolle mit folgendem Befehl ansehen:
yarn twenty logs

Routen-Trigger-Payload

Wenn ein Route-Trigger Ihre Logikfunktion aufruft, erhält sie ein RoutePayload-Objekt, das dem AWS-HTTP-API-v2-Format folgt. Importieren Sie den Typ RoutePayload aus twenty-sdk:
import { defineLogicFunction, type RoutePayload } from 'twenty-sdk/define';

const handler = async (event: RoutePayload) => {
  const { headers, queryStringParameters, pathParameters, body } = event;
  const { method, path } = event.requestContext.http;

  return { message: 'Success' };
};
Der Typ RoutePayload hat die folgende Struktur:
EigenschaftTypBeschreibungBeispiel
headersRecord\<string, string | undefined>HTTP-Header (nur die in forwardedRequestHeaders aufgelisteten)siehe Abschnitt unten
queryStringParametersRecord\<string, string | undefined>Query-String-Parameter (mehrere Werte mit Kommas verbunden)/users?ids=1&ids=2&ids=3&name=Alice -> { ids: '1,2,3', name: 'Alice' }
pathParametersRecord\<string, string | undefined>Aus dem Routenmuster extrahierte Pfadparameter/users/:id, /users/123 -> { id: '123' }
bodyobject | nullGeparster Request-Body (JSON){ id: 1 } -> { id: 1 }
isBase64EncodedbooleanGibt an, ob der Body Base64-codiert ist
requestContext.http.methodZeichenketteHTTP-Methode (GET, POST, PUT, PATCH, DELETE)
requestContext.http.pathZeichenketteRohpfad der Anfrage

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 Array forwardedRequestHeaders auf:
export default defineLogicFunction({
  universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf',
  name: 'webhook-handler',
  handler,
  httpRouteTriggerSettings: {
    path: '/webhook',
    httpMethod: 'POST',
    isAuthRequired: false,
    forwardedRequestHeaders: ['x-webhook-signature', 'content-type'],
  },
});
Greifen Sie in Ihrem Handler wie folgt auf die weitergeleiteten Header zu:
const handler = async (event: RoutePayload) => {
  const signature = event.headers['x-webhook-signature'];
  const contentType = event.headers['content-type'];

  // Validate webhook signature...
  return { received: true };
};
Header-Namen werden in Kleinbuchstaben normalisiert. Greifen Sie mit Schlüsseln in Kleinbuchstaben darauf zu (z. B. event.headers['content-type']).

Eine Funktion als Tool bereitstellen

Logikfunktionen können als Tools für KI-Agenten und Workflows verfügbar gemacht werden. Wenn eine Funktion als Tool markiert ist, wird sie von den KI-Funktionen von Twenty auffindbar und kann in Workflow-Automatisierungen verwendet werden.Um eine Logikfunktion als Tool zu markieren, setzen Sie isTool: true:
src/logic-functions/enrich-company.logic-function.ts
import { defineLogicFunction } from 'twenty-sdk/define';
import { CoreApiClient } from 'twenty-client-sdk/core';

const handler = async (params: { companyName: string; domain?: string }) => {
  const client = new CoreApiClient();

  const result = await client.mutation({
    createTask: {
      __args: {
        data: {
          title: `Enrich data for ${params.companyName}`,
          body: `Domain: ${params.domain ?? 'unknown'}`,
        },
      },
      id: true,
    },
  });

  return { taskId: result.createTask.id };
};

export default defineLogicFunction({
  universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
  name: 'enrich-company',
  description: 'Enrich a company record with external data',
  timeoutSeconds: 10,
  handler,
  isTool: true,
});
Hauptpunkte:
  • Sie können isTool mit Triggern kombinieren — eine Funktion kann gleichzeitig sowohl ein Tool (von KI-Agenten aufrufbar) als auch durch Ereignisse ausgelöst werden.
  • toolInputSchema (optional): Ein JSON-Schema-Objekt, das die Parameter beschreibt, die Ihre Funktion akzeptiert. Das Schema wird automatisch durch statische Analyse des Quellcodes ermittelt, Sie können es jedoch auch explizit festlegen:
export default defineLogicFunction({
  ...,
  toolInputSchema: {
    type: 'object',
    properties: {
      companyName: {
        type: 'string',
        description: 'The name of the company to enrich',
      },
      domain: {
        type: 'string',
        description: 'The company website domain (optional)',
      },
    },
    required: ['companyName'],
  },
});
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.
Eine Post-Installationsfunktion ist eine Logikfunktion, die automatisch ausgeführt wird, nachdem Ihre App in einem Arbeitsbereich installiert wurde. Der Server führt sie nach der Synchronisierung der Metadaten der App und der Generierung des SDK-Clients aus, sodass der Arbeitsbereich vollständig einsatzbereit ist und das neue Schema bereitsteht. Typische Anwendungsfälle umfassen das Befüllen von Standarddaten, das Erstellen anfänglicher Datensätze, das Konfigurieren von Arbeitsbereichseinstellungen oder das Bereitstellen von Ressourcen bei Diensten von Drittanbietern.
src/logic-functions/post-install.ts
import { definePostInstallLogicFunction, type InstallPayload } from 'twenty-sdk/define';

const handler = async (payload: InstallPayload): Promise<void> => {
  console.log('Post install logic function executed successfully!', payload.previousVersion);
};

export default definePostInstallLogicFunction({
  universalIdentifier: 'f7a2b9c1-3d4e-5678-abcd-ef9876543210',
  name: 'post-install',
  description: 'Runs after installation to set up the application.',
  timeoutSeconds: 300,
  shouldRunOnVersionUpgrade: false,
  shouldRunSynchronously: false,
  handler,
});
Sie können die Post-Installationsfunktion auch jederzeit manuell über die CLI ausführen:
yarn twenty exec --postInstall
Hauptpunkte:
  • Post-Installationsfunktionen verwenden definePostInstallLogicFunction() — eine spezialisierte Variante, die Trigger-Einstellungen (cronTriggerSettings, databaseEventTriggerSettings, httpRouteTriggerSettings, isTool) weglässt.
  • Der Handler erhält ein InstallPayload mit { previousVersion?: string; newVersion: string }newVersion ist die zu installierende Version, und previousVersion ist die zuvor installierte Version (oder undefined bei einer Neuinstallation). Verwenden Sie diese Werte, um Neuinstallationen von Upgrades zu unterscheiden und versionsspezifische Migrationslogik auszuführen.
  • Wann der Hook ausgeführt wird: standardmäßig nur bei Neuinstallationen. Übergeben Sie shouldRunOnVersionUpgrade: true, wenn er auch beim Upgrade der App von einer vorherigen Version ausgeführt werden soll. Wenn weggelassen, ist das Flag standardmäßig false und Upgrades überspringen den Hook.
  • Ausführungsmodell — standardmäßig asynchron, synchron optional: Das Flag shouldRunSynchronously steuert, wie Post-Install ausgeführt wird.
    • shouldRunSynchronously: false (Standard) — der Hook wird in die Nachrichtenwarteschlange eingereiht mit retryLimit: 3 und läuft asynchron in einem Worker. Die Installationsantwort kommt zurück, sobald der Job eingereiht ist, sodass ein langsamer oder fehlschlagender Handler den Aufrufer nicht blockiert. Der Worker versucht es bis zu dreimal erneut. Verwenden Sie dies für lang laufende Jobs — das Befüllen großer Datensätze, Aufrufe langsamer Drittanbieter-APIs, Bereitstellung externer Ressourcen, alles, was ein vernünftiges HTTP-Antwortfenster überschreiten könnte.
    • shouldRunSynchronously: true — der Hook wird inline während des Installationsablaufs ausgeführt (gleicher Executor wie bei Pre-Install). Die Installationsanforderung blockiert, bis der Handler fertig ist, und wenn er einen Fehler wirft, erhält der Installationsaufrufer einen POST_INSTALL_ERROR. Keine automatischen Wiederholungen. Verwenden Sie dies für schnelle Aufgaben, die vor der Antwort abgeschlossen sein müssen — z. B. um dem Benutzer einen Validierungsfehler auszugeben oder für eine schnelle Einrichtung, auf die der Client unmittelbar nach der Rückkehr des Installationsaufrufs angewiesen ist. Beachten Sie, dass die Metadatenmigration bereits angewendet wurde, wenn Post-Install läuft, sodass ein Fehler im Synchronmodus die Schemaänderungen nicht rückgängig macht — er zeigt lediglich den Fehler an.
  • Stellen Sie sicher, dass Ihr Handler idempotent ist. Im asynchronen Modus kann die Warteschlange bis zu dreimal erneut versuchen; in beiden Modi kann der Hook bei Upgrades erneut laufen, wenn shouldRunOnVersionUpgrade: true.
  • Die Umgebungsvariablen APPLICATION_ID, APP_ACCESS_TOKEN und API_URL sind im Handler verfügbar (wie bei jeder anderen Logikfunktion), sodass Sie die Twenty API mit einem auf Ihre App beschränkten Anwendungszugriffstoken aufrufen können.
  • Pro Anwendung ist nur eine Post-Installationsfunktion zulässig. Der Manifest-Build schlägt fehl, wenn mehr als eine erkannt wird.
  • Die universalIdentifier, shouldRunOnVersionUpgrade und shouldRunSynchronously der Funktion werden während des Builds automatisch dem Anwendungsmanifest unter dem Feld postInstallLogicFunction hinzugefügt — Sie müssen sie in defineApplication() nicht referenzieren.
  • Das standardmäßige Timeout ist auf 300 Sekunden (5 Minuten) festgelegt, um längere Einrichtungsvorgänge wie Daten-Seeding zu ermöglichen.
  • Nicht im Dev-Modus ausgeführt: Wenn eine App lokal registriert ist (über yarn twenty dev), überspringt der Server den Installationsablauf vollständig und synchronisiert Dateien direkt über den CLI-Watcher — daher läuft Post-Install im Dev-Modus nie, unabhängig von shouldRunSynchronously. Verwenden Sie yarn twenty exec --postInstall, um es manuell gegen einen laufenden Workspace auszulösen.
Eine Pre-Install-Funktion ist eine Logikfunktion, die automatisch während der Installation ausgeführt wird, bevor die Metadatenmigration des Workspaces angewendet wird. Sie hat die gleiche Payload-Struktur wie Post-Install (InstallPayload), ist aber früher im Installationsablauf positioniert, sodass sie Zustände vorbereiten kann, von denen die bevorstehende Migration abhängt — typische Anwendungsfälle sind das Sichern von Daten, die Validierung der Kompatibilität mit dem neuen Schema oder das Archivieren von Datensätzen, die umstrukturiert oder entfernt werden sollen.
src/logic-functions/pre-install.ts
import { definePreInstallLogicFunction, type InstallPayload } from 'twenty-sdk/define';

const handler = async (payload: InstallPayload): Promise<void> => {
  console.log('Pre install logic function executed successfully!', payload.previousVersion);
};

export default definePreInstallLogicFunction({
  universalIdentifier: 'a1b2c3d4-5678-90ab-cdef-1234567890ab',
  name: 'pre-install',
  description: 'Runs before installation to prepare the application.',
  timeoutSeconds: 300,
  shouldRunOnVersionUpgrade: true,
  handler,
});
Sie können die Pre-Installationsfunktion auch jederzeit manuell über die CLI ausführen:
yarn twenty exec --preInstall
Hauptpunkte:
  • Pre-Install-Funktionen verwenden definePreInstallLogicFunction() — dieselbe spezialisierte Konfiguration wie bei Post-Install, nur an einen anderen Lifecycle-Slot gebunden.
  • Sowohl Pre- als auch Post-Install-Handler erhalten denselben InstallPayload-Typ: { previousVersion?: string; newVersion: string }. Importieren Sie ihn einmal und verwenden Sie ihn für beide Hooks wieder.
  • Wann der Hook ausgeführt wird: positioniert direkt vor der Metadatenmigration des Workspaces (synchronizeFromManifest). Vor der Ausführung führt der Server einen rein additiven “pared-down sync” durch, der die Pre-Install-Funktion der neuen Version in den Workspace-Metadaten registriert — sonst wird nichts angefasst — und führt sie dann aus. Da dieser Sync nur additiv ist, sind die Objekte, Felder und Daten der vorherigen Version noch intakt, wenn Ihr Handler läuft: Sie können den Zustand vor der Migration gefahrlos lesen und sichern.
  • Ausführungsmodell: Pre-Install wird synchron ausgeführt und blockiert die Installation. Wenn der Handler einen Fehler wirft, wird die Installation abgebrochen, bevor Schemaänderungen angewendet werden — der Workspace verbleibt in der vorherigen Version in einem konsistenten Zustand. Das ist beabsichtigt: Pre-Install ist Ihre letzte Chance, ein riskantes Upgrade abzulehnen.
  • Wie bei Post-Install ist pro Anwendung nur eine Pre-Installationsfunktion zulässig. Sie wird während des Builds automatisch dem Anwendungsmanifest unter preInstallLogicFunction hinzugefügt.
  • Nicht im Dev-Modus ausgeführt: wie bei Post-Install — der Installationsablauf wird für lokal registrierte Apps vollständig übersprungen, daher läuft Pre-Install unter yarn twenty dev nie. Verwenden Sie yarn twenty exec --preInstall, um es manuell auszulösen.
Beide Hooks sind Teil desselben Installationsablaufs und erhalten dasselbe InstallPayload. Der Unterschied besteht darin, wann sie relativ zur Metadatenmigration des Workspaces ausgeführt werden, und das ändert, auf welche Daten sie gefahrlos zugreifen können.
┌─────────────────────────────────────────────────────────────┐
│ install flow                                                │
│                                                             │
│   upload package → [pre-install] → metadata migration →     │
│   generate SDK → [post-install]                             │
│                                                             │
│                  old schema visible    new schema visible   │
└─────────────────────────────────────────────────────────────┘
Pre-Install ist immer synchron (blockiert die Installation und kann sie abbrechen). Post-Install ist standardmäßig asynchron — in einen Worker eingereiht mit automatischen Wiederholungen — kann aber per shouldRunSynchronously: true in die synchrone Ausführung wechseln. Siehe das Akkordeon zu definePostInstallLogicFunction oben, wann welcher Modus zu verwenden ist.Verwenden Sie post-install für alles, wofür das neue Schema existieren muss. Dies ist der Regelfall:
  • Standarddaten befüllen (Anlegen anfänglicher Datensätze, Standardansichten, Demo-Inhalte) für neu hinzugefügte Objekte und Felder.
  • Registrieren von Webhooks bei Drittanbieter-Diensten, jetzt, da die App ihre Anmeldedaten hat.
  • Aufrufen Ihrer eigenen API, um eine Einrichtung abzuschließen, die von den synchronisierten Metadaten abhängt.
  • Idempotente “Stelle sicher, dass dies existiert”-Logik, die bei jedem Upgrade den Zustand abgleichen soll — kombinieren Sie dies mit shouldRunOnVersionUpgrade: true.
Beispiel — nach der Installation einen Standard-PostCard-Datensatz anlegen:
src/logic-functions/post-install.ts
import { definePostInstallLogicFunction, type InstallPayload } from 'twenty-sdk/define';
import { createClient } from './generated/client';

const handler = async ({ previousVersion }: InstallPayload): Promise<void> => {
  if (previousVersion) return; // fresh installs only

  const client = createClient();
  await client.postCard.create({
    data: { title: 'Welcome to Postcard', content: 'Your first card!' },
  });
};

export default definePostInstallLogicFunction({
  universalIdentifier: 'f7a2b9c1-3d4e-5678-abcd-ef9876543210',
  name: 'post-install',
  description: 'Seeds a welcome post card after install.',
  timeoutSeconds: 300,
  shouldRunOnVersionUpgrade: false,
  handler,
});
Verwenden Sie pre-install, wenn eine Migration ansonsten vorhandene Daten löschen oder beschädigen würde. Da Pre-Install gegen das vorherige Schema läuft und ein Fehlschlag das Upgrade zurückrollt, ist es der richtige Ort für alles Riskante:
  • Sichern von Daten, die gleich gelöscht oder umstrukturiert werden — z. B. Sie entfernen in v2 ein Feld und müssen dessen Werte vor der Migration in ein anderes Feld kopieren oder in einen Speicher exportieren.
  • Archivieren von Datensätzen, die eine neue Einschränkung ungültig machen würde — z. B. ein Feld wird NOT NULL und Sie müssen zuerst Zeilen mit Null-Werten löschen oder korrigieren.
  • Kompatibilität validieren und das Upgrade ablehnen, wenn die aktuellen Daten nicht sauber migriert werden können — werfen Sie im Handler einen Fehler, und die Installation wird ohne Änderungen abgebrochen. Das ist sicherer, als die Inkompatibilität mitten in der Migration zu entdecken.
  • Daten umbenennen oder Schlüssel neu zuweisen vor einer Schemaänderung, bei der sonst die Zuordnung verloren ginge.
Beispiel — Datensätze vor einer destruktiven Migration archivieren:
src/logic-functions/pre-install.ts
import { definePreInstallLogicFunction, type InstallPayload } from 'twenty-sdk/define';
import { createClient } from './generated/client';

const handler = async ({ previousVersion, newVersion }: InstallPayload): Promise<void> => {
  // Only the 1.x → 2.x upgrade drops the legacy `notes` field.
  if (!previousVersion?.startsWith('1.') || !newVersion.startsWith('2.')) {
    return;
  }

  const client = createClient();
  const legacyRecords = await client.postCard.findMany({
    where: { notes: { isNotNull: true } },
  });

  if (legacyRecords.length === 0) return;

  // Copy legacy `notes` into the new `description` field before the migration
  // drops the `notes` column. If this fails, the upgrade is aborted and the
  // workspace stays on v1 with all data intact.
  await Promise.all(
    legacyRecords.map((record) =>
      client.postCard.update({
        where: { id: record.id },
        data: { description: record.notes },
      }),
    ),
  );
};

export default definePreInstallLogicFunction({
  universalIdentifier: 'a1b2c3d4-5678-90ab-cdef-1234567890ab',
  name: 'pre-install',
  description: 'Backs up legacy notes into description before the v2 migration.',
  timeoutSeconds: 300,
  shouldRunOnVersionUpgrade: true,
  handler,
});
Faustregel:
You want to…Verwenden
Standarddaten befüllen, den Workspace konfigurieren, externe Ressourcen registrierenpost-install
Lang laufendes Seeding oder Drittanbieteraufrufe ausführen, die die Installationsantwort nicht blockieren solltenpost-install (Standard — shouldRunSynchronously: false, mit Worker-Wiederholungen)
Schnelle Einrichtung ausführen, auf die sich der Aufrufer unmittelbar nach der Rückkehr des Installationsaufrufs verlassen wirdpost-install mit shouldRunSynchronously: true
Daten lesen oder sichern, die bei der bevorstehenden Migration verloren gingenpre-install
Ein Upgrade ablehnen, das vorhandene Daten beschädigen würdepre-install (throw im Handler)
Bei jedem Upgrade einen Abgleich ausführenpost-install mit shouldRunOnVersionUpgrade: true
Einmalige Einrichtung nur bei der ersten Installation durchführenpost-install mit shouldRunOnVersionUpgrade: false (Standard)
Im Zweifel auf Post-Install setzen. Greifen Sie nur zu Pre-Install, wenn die Migration selbst destruktiv ist und Sie den vorherigen Zustand abfangen müssen, bevor er verloren geht.

Typisierte API-Clients (twenty-client-sdk)

Das Paket twenty-client-sdk stellt zwei typisierte GraphQL-Clients bereit, um aus Ihren Logikfunktionen und Frontend-Komponenten mit der Twenty-API zu interagieren.
ClientImportierenEndpunktGeneriert?
CoreApiClienttwenty-client-sdk/core/graphql — Arbeitsbereichsdaten (Datensätze, Objekte)Ja, zur Entwicklungs-/Build-Zeit
MetadataApiClienttwenty-client-sdk/metadata/metadata — Arbeitsbereichskonfiguration, Datei-UploadsNein, wird vorgefertigt ausgeliefert
Der CoreApiClient ist der Haupt-Client zum Abfragen und Ändern von Arbeitsbereichsdaten. Er wird während yarn twenty dev oder yarn twenty build aus Ihrem Arbeitsbereichsschema generiert und ist daher vollständig typisiert, passend zu Ihren Objekten und Feldern.
import { CoreApiClient } from 'twenty-client-sdk/core';

const client = new CoreApiClient();

// Query records
const { companies } = await client.query({
  companies: {
    edges: {
      node: {
        id: true,
        name: true,
        domainName: {
          primaryLinkLabel: true,
          primaryLinkUrl: true,
        },
      },
    },
  },
});

// Create a record
const { createCompany } = await client.mutation({
  createCompany: {
    __args: {
      data: {
        name: 'Acme Corp',
      },
    },
    id: true,
    name: true,
  },
});
Der Client verwendet eine Selection-Set-Syntax: Übergeben Sie 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 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:
import { CoreApiClient, CoreSchema } from 'twenty-client-sdk/core';
import { useState } from 'react';

const [company, setCompany] = useState<
  Pick<CoreSchema.Company, 'id' | 'name'> | undefined
>(undefined);

const client = new CoreApiClient();
const result = await client.query({
  company: {
    __args: { filter: { position: { eq: 1 } } },
    id: true,
    name: true,
  },
});
setCompany(result.company);
MetadataApiClient ist im SDK bereits vorgefertigt enthalten (keine Generierung erforderlich). Er fragt den Endpunkt /metadata nach Arbeitsbereichskonfiguration, Anwendungen und Datei-Uploads ab.
import { MetadataApiClient } from 'twenty-client-sdk/metadata';

const metadataClient = new MetadataApiClient();

// List first 10 objects in the workspace
const { objects } = await metadataClient.query({
  objects: {
    edges: {
      node: {
        id: true,
        nameSingular: true,
        namePlural: true,
        labelSingular: true,
        isCustom: true,
      },
    },
    __args: {
      filter: {},
      paging: { first: 10 },
    },
  },
});

Dateien hochladen

Der MetadataApiClient enthält eine Methode uploadFile, um Dateien an Felder des Typs Datei anzuhängen:
import { MetadataApiClient } from 'twenty-client-sdk/metadata';
import * as fs from 'fs';

const metadataClient = new MetadataApiClient();

const fileBuffer = fs.readFileSync('./invoice.pdf');

const uploadedFile = await metadataClient.uploadFile(
  fileBuffer,                                         // file contents as a Buffer
  'invoice.pdf',                                      // filename
  'application/pdf',                                  // MIME type
  '58a0a314-d7ea-4865-9850-7fb84e72f30b',            // field universalIdentifier
);

console.log(uploadedFile);
// { id: '...', path: '...', size: 12345, createdAt: '...', url: 'https://...' }
ParameterTypBeschreibung
fileBufferBufferDer Rohinhalt der Datei
filenameZeichenketteDer Name der Datei (wird für Speicherung und Anzeige verwendet)
contentTypeZeichenketteMIME-Typ (standardmäßig application/octet-stream, wenn weggelassen)
fieldMetadataUniversalIdentifierZeichenketteDer universalIdentifier des Dateityp-Felds in Ihrem Objekt
Hauptpunkte:
  • Sie verwendet den universalIdentifier des Feldes (nicht dessen arbeitsbereichsspezifische ID), sodass Ihr Upload-Code in jedem Arbeitsbereich funktioniert, in dem Ihre App installiert ist.
  • Die zurückgegebene url ist 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-API
  • TWENTY_APP_ACCESS_TOKEN — Kurzlebiger Schlüssel, der auf die Standard-Funktionsrolle Ihrer Anwendung begrenzt ist
Sie müssen diese nicht an die Clients übergeben — sie lesen automatisch aus process.env. Die Berechtigungen des API-Schlüssels werden durch die Rolle bestimmt, auf die in defaultRoleUniversalIdentifier in Ihrer application-config.ts verwiesen wird.