Usa le risorse dell’SDK (tipi e configurazione)
Il pacchetto twenty-sdk fornisce blocchi tipizzati e funzioni helper da usare nella tua app. Di seguito gli elementi principali con cui interagirai più spesso.Funzioni helper
L’SDK fornisce funzioni helper per definire le entità della tua app. Come descritto in Rilevamento delle entità, devi usareexport default define<Entity>({...}) affinché le tue entità vengano rilevate:
| Funzione | Scopo |
|---|---|
defineApplication | Configura i metadati dell’applicazione (obbligatorio, uno per app) |
defineObject | Definisci oggetti personalizzati con campi |
defineLogicFunction | Definisci funzioni logiche con handler |
definePreInstallLogicFunction | Definisci una funzione logica di pre-installazione (una per app) |
definePostInstallLogicFunction | Definisci una funzione logica di post-installazione (una per app) |
defineFrontComponent | Definisci componenti front-end per un’interfaccia utente personalizzata |
defineRole | Configura i permessi dei ruoli e l’accesso agli oggetti |
defineField | Estendi gli oggetti esistenti con campi aggiuntivi |
defineView | Definisci viste salvate per gli oggetti |
defineNavigationMenuItem | Definisci i link di navigazione della barra laterale |
defineSkill | Definisci le competenze dell’agente IA |
Definizione degli oggetti
Gli oggetti personalizzati descrivono sia lo schema sia il comportamento per i record nel tuo spazio di lavoro. UsadefineObject() per definire oggetti con convalida integrata:
- Usa
defineObject()per una convalida integrata e un migliore supporto IDE. - Il
universalIdentifierdeve essere univoco e stabile tra i deployment. - Ogni campo richiede un
name,type,labele il propriouniversalIdentifierstabile. - L’array
fieldsè facoltativo: puoi definire oggetti senza campi personalizzati. - Puoi generare nuovi oggetti con
yarn twenty entity:add, che ti guida nella denominazione, nei campi e nelle relazioni.
I campi base vengono creati automaticamente. Quando definisci un oggetto personalizzato, Twenty aggiunge automaticamente i campi standard
come
id, name, createdAt, updatedAt, createdBy, updatedBy e deletedAt.
Non è necessario definirli nel tuo array fields — aggiungi solo i tuoi campi personalizzati.
Puoi sovrascrivere i campi predefiniti definendo un campo con lo stesso nome nel tuo array fields,
ma non è consigliato.Configurazione dell’applicazione (application-config.ts)
Ogni app ha un singolo fileapplication-config.ts che descrive:
- Identità dell’app: identificatori, nome visualizzato e descrizione.
- Come vengono eseguite le sue funzioni: quale ruolo usano per i permessi.
- Variabili (opzionali): coppie chiave–valore esposte alle funzioni come variabili d’ambiente.
- (Opzionale) funzione di pre-installazione: una funzione logica che viene eseguita prima che l’app venga installata.
- (Opzionale) funzione post-installazione: una funzione logica che viene eseguita dopo l’installazione dell’app.
defineApplication() per definire la configurazione della tua applicazione:
- I campi
universalIdentifiersono ID deterministici sotto il tuo controllo; generali una volta e mantienili stabili tra le sincronizzazioni. applicationVariablesdiventano variabili d’ambiente per le tue funzioni (ad esempio,DEFAULT_RECIPIENT_NAMEè disponibile comeprocess.env.DEFAULT_RECIPIENT_NAME).defaultRoleUniversalIdentifierdeve corrispondere al file del ruolo (vedi sotto).- Le funzioni di pre-installazione e post-installazione vengono rilevate automaticamente durante la build del manifesto. Vedi Funzioni di pre-installazione e Funzioni di post-installazione.
Ruoli e permessi
Le applicazioni possono definire ruoli che incapsulano i permessi sugli oggetti e sulle azioni del tuo spazio di lavoro. Il campodefaultRoleUniversalIdentifier in application-config.ts indica il ruolo predefinito utilizzato dalle funzioni logiche della tua app.
- La chiave API di runtime iniettata come
TWENTY_API_KEYè derivata da questo ruolo funzione predefinito. - Il client tipizzato sarà limitato ai permessi concessi a quel ruolo.
- Segui il principio del privilegio minimo: crea un ruolo dedicato con solo i permessi necessari alle tue funzioni, quindi fai riferimento al suo identificatore universale.
Ruolo funzione predefinito (*.role.ts)
Quando generi una nuova app con lo scaffolder, la CLI crea anche un file di ruolo predefinito. UsadefineRole() per definire ruoli con convalida integrata:
universalIdentifier di questo ruolo viene quindi referenziato in application-config.ts come defaultRoleUniversalIdentifier. In altre parole:
- *.role.ts definisce ciò che il ruolo funzione predefinito può fare.
- application-config.ts punta a quel ruolo in modo che le tue funzioni ne ereditino i permessi.
- Parti dal ruolo generato dallo scaffolder, quindi restringilo progressivamente seguendo il principio del privilegio minimo.
- Sostituisci
objectPermissionsefieldPermissionscon gli oggetti/campi di cui le tue funzioni hanno bisogno. permissionFlagscontrollano l’accesso alle funzionalità a livello di piattaforma. Mantienili al minimo; aggiungi solo ciò che ti serve.- Vedi un esempio funzionante nell’app Hello World:
packages/twenty-apps/hello-world/src/roles/function-role.ts.
Configurazione e punto di ingresso della funzione logica
Ogni file di funzione usadefineLogicFunction() per esportare una configurazione con un handler e trigger opzionali.
- route: Espone la funzione su un percorso e metodo HTTP sotto l’endpoint
/s/:
es.path: '/post-card/create',-> chiamata su<APP_URL>/s/post-card/create
- cron: Esegue la tua funzione secondo una pianificazione utilizzando un’espressione CRON.
- databaseEvent: Viene eseguito sugli eventi del ciclo di vita degli oggetti dello spazio di lavoro. Quando l’operazione dell’evento è
updated, è possibile specificare campi specifici da monitorare nell’arrayupdatedFields. Se lasciato non definito o vuoto, qualsiasi aggiornamento attiverà la funzione.
es. person.updated
Note:
- L’array
triggersè facoltativo. Le funzioni senza trigger possono essere utilizzate come funzioni di utilità richiamate da altre funzioni. - Puoi combinare più tipi di trigger in un’unica funzione.
Funzioni di pre-installazione
Una funzione di pre-installazione è una funzione logica che viene eseguita automaticamente prima che la tua app venga installata in uno spazio di lavoro. È utile per attività di convalida, controlli dei prerequisiti o per preparare lo stato dello spazio di lavoro prima che proceda l’installazione principale. Quando esegui lo scaffolding di una nuova app concreate-twenty-app, viene generata una funzione di pre-installazione in src/logic-functions/pre-install.ts:
- Le funzioni di pre-installazione utilizzano
definePreInstallLogicFunction()— una variante specializzata che omette le impostazioni dei trigger (cronTriggerSettings,databaseEventTriggerSettings,httpRouteTriggerSettings,isTool). - L’handler riceve un
InstallLogicFunctionPayloadcon{ previousVersion: string }— la versione dell’app precedentemente installata (oppure una stringa vuota per nuove installazioni). - È consentita una sola funzione di pre-installazione per applicazione. La build del manifesto genererà un errore se ne viene rilevata più di una.
- L’
universalIdentifierdella funzione viene impostato automaticamente comepreInstallLogicFunctionUniversalIdentifiernel manifesto dell’applicazione durante la build — non è necessario farvi riferimento indefineApplication(). - Il timeout predefinito è impostato a 300 secondi (5 minuti) per consentire attività di preparazione più lunghe.
- Le funzioni di pre-installazione non necessitano di trigger — vengono invocate dalla piattaforma prima dell’installazione o manualmente tramite
function:execute --preInstall.
Funzioni post-installazione
Una funzione post-installazione è una funzione logica che viene eseguita automaticamente dopo che la tua app è stata installata in uno spazio di lavoro. Questo è utile per attività di configurazione una tantum come il popolamento di dati predefiniti, la creazione di record iniziali o la configurazione delle impostazioni dello spazio di lavoro. Quando esegui lo scaffolding di una nuova app concreate-twenty-app, viene generata automaticamente una funzione di post-installazione in src/logic-functions/post-install.ts:
- Le funzioni di post-installazione utilizzano
definePostInstallLogicFunction()— una variante specializzata che omette le impostazioni dei trigger (cronTriggerSettings,databaseEventTriggerSettings,httpRouteTriggerSettings,isTool). - L’handler riceve un
InstallLogicFunctionPayloadcon{ previousVersion: string }— la versione dell’app precedentemente installata (oppure una stringa vuota per nuove installazioni). - È consentita una sola funzione di post-installazione per applicazione. La build del manifesto genererà un errore se ne viene rilevata più di una.
- L’
universalIdentifierdella funzione viene impostato automaticamente comepostInstallLogicFunctionUniversalIdentifiernel manifesto dell’applicazione durante la build — non è necessario farvi riferimento indefineApplication(). - Il timeout predefinito è impostato a 300 secondi (5 minuti) per consentire attività di configurazione più lunghe, come il popolamento dei dati.
- Le funzioni di post-installazione non necessitano di trigger — vengono invocate dalla piattaforma durante l’installazione o manualmente tramite
function:execute --postInstall.
Payload del trigger di route
Quando un trigger di route invoca la tua funzione logica, questa riceve un oggettoRoutePayload che segue il formato AWS HTTP API v2. Importa il tipo da twenty-sdk:
RoutePayload ha la seguente struttura:
| Proprietà | Tipo | Descrizione |
|---|---|---|
headers | Record<string, string | undefined> | Intestazioni HTTP (solo quelle elencate in forwardedRequestHeaders) |
queryStringParameters | Record<string, string | undefined> | Parametri della query string (valori multipli uniti da virgole) |
pathParameters | Record<string, string | undefined> | Parametri di percorso estratti dal pattern della route (ad es., /users/:id → { id: '123' }) |
body | object | null | Corpo della richiesta analizzato (JSON) |
isBase64Encoded | boolean | Indica se il corpo è codificato in base64 |
requestContext.http.method | string | Metodo HTTP (GET, POST, PUT, PATCH, DELETE) |
requestContext.http.path | string | Percorso della richiesta non elaborato |
Inoltro delle intestazioni HTTP
Per impostazione predefinita, le intestazioni HTTP delle richieste in ingresso non vengono passate alla tua funzione logica per motivi di sicurezza. Per accedere a intestazioni specifiche, elencale esplicitamente nell’arrayforwardedRequestHeaders:
I nomi delle intestazioni vengono normalizzati in minuscolo. Accedile usando chiavi in minuscolo (ad esempio,
event.headers['content-type']).- Generata dallo scaffolder: Esegui
yarn twenty entity:adde scegli l’opzione per aggiungere una nuova funzione logica. Questo genera un file iniziale con un handler e una configurazione. - Manuale: Crea un nuovo file
*.logic-function.tse usadefineLogicFunction(), seguendo lo stesso schema.
Contrassegnare una funzione logica come strumento
Le funzioni logiche possono essere esposte come strumenti per gli agenti di IA e i flussi di lavoro. Quando una funzione è contrassegnata come strumento, diventa individuabile dalle funzionalità di IA di Twenty e può essere selezionata come passaggio nelle automazioni dei flussi di lavoro. Per contrassegnare una funzione logica come strumento, impostaisTool: true e fornisci un toolInputSchema che descriva i parametri di input attesi utilizzando JSON Schema:
isTool(boolean, predefinito:false): Quando impostato sutrue, la funzione viene registrata come strumento e diventa disponibile per gli agenti IA e le automazioni dei flussi di lavoro.toolInputSchema(object, opzionale): Un oggetto JSON Schema che descrive i parametri accettati dalla funzione. Gli agenti IA utilizzano questo schema per capire quali input si aspetta lo strumento e per convalidare le chiamate. Se omesso, lo schema assume il valore predefinito{ type: 'object', properties: {} }(nessun parametro).- Le funzioni con
isTool: false(o non impostato) non vengono esposte come strumenti. Possono comunque essere eseguite direttamente o chiamate da altre funzioni, ma non compariranno nell’individuazione degli strumenti. - Denominazione dello strumento: Quando esposta come strumento, il nome della funzione viene normalizzato automaticamente in
logic_function_<name>(in minuscolo, i caratteri non alfanumerici vengono sostituiti da trattini bassi). Ad esempio,enrich-companydiventalogic_function_enrich_company. - È possibile combinare
isToolcon i trigger — una funzione può essere sia uno strumento (invocabile dagli agenti IA) sia attivata da eventi (cron, eventi del database, routes) contemporaneamente.
Scrivi una buona
description. Gli agenti IA fanno affidamento sul campo description della funzione per decidere quando usare lo strumento. Sii specifico su cosa fa lo strumento e quando dovrebbe essere invocato.Componenti front-end
I componenti front-end ti consentono di creare componenti React personalizzati che vengono renderizzati all’interno dell’interfaccia di Twenty. UsadefineFrontComponent() per definire componenti con convalida integrata:
- I componenti front-end sono componenti React che eseguono il rendering in contesti isolati all’interno di Twenty.
- Il campo
componentfa riferimento al tuo componente React. - I componenti vengono compilati e sincronizzati automaticamente durante
yarn twenty app:dev.
- Generata dallo scaffolder: Esegui
yarn twenty entity:adde scegli l’opzione per aggiungere un nuovo componente front-end. - Manuale: Crea un nuovo file
.tsxe usadefineFrontComponent(), seguendo lo stesso schema.
Abilità
Le skill definiscono istruzioni e capacità riutilizzabili che gli agenti IA possono utilizzare all’interno del tuo spazio di lavoro. UsadefineSkill() per definire skill con convalida integrata:
nameè una stringa identificativa univoca per la skill (kebab-case consigliato).labelè il nome di visualizzazione leggibile mostrato nell’UI.contentcontiene le istruzioni della skill — questo è il testo che l’agente IA utilizza.icon(opzionale) imposta l’icona visualizzata nell’UI.description(opzionale) fornisce contesto aggiuntivo sullo scopo della skill.
- Generata dallo scaffolder: Esegui
yarn twenty entity:adde scegli l’opzione per aggiungere una nuova skill. - Manuale: Crea un nuovo file e usa
defineSkill(), seguendo lo stesso schema.
Client tipizzati generati
Due client tipizzati sono generati automaticamente dayarn twenty app:dev e salvati in node_modules/twenty-sdk/generated in base allo schema del tuo spazio di lavoro:
CoreApiClient— interroga l’endpoint/graphqlper i dati dello spazio di lavoroMetadataApiClient— interroga l’endpoint/metadataper la configurazione dello spazio di lavoro e il caricamento dei file
yarn twenty app:dev ogni volta che i tuoi oggetti o campi cambiano.
Credenziali di runtime nelle funzioni logiche
Quando la tua funzione viene eseguita su Twenty, la piattaforma inietta le credenziali come variabili d’ambiente prima dell’esecuzione del tuo codice:TWENTY_API_URL: URL di base dell’API Twenty a cui punta la tua app.TWENTY_API_KEY: Chiave a breve durata con ambito al ruolo funzione predefinito della tua applicazione.
- Non è necessario passare URL o chiave API al client generato. Legge
TWENTY_API_URLeTWENTY_API_KEYda process.env in fase di esecuzione. - I permessi della chiave API sono determinati dal ruolo referenziato nel tuo
application-config.tstramitedefaultRoleUniversalIdentifier. Questo è il ruolo predefinito utilizzato dalle funzioni logiche della tua applicazione. - Le applicazioni possono definire ruoli per seguire il principio del privilegio minimo. Concedi solo i permessi necessari alle tue funzioni, quindi punta
defaultRoleUniversalIdentifierall’identificatore universale di quel ruolo.
Caricamento dei file
IlMetadataApiClient generato include un metodo uploadFile per allegare file ai campi di tipo file sugli oggetti del tuo spazio di lavoro. Poiché i client GraphQL standard non supportano nativamente il caricamento di file multipart, il client fornisce questo metodo dedicato che implementa la specifica della richiesta GraphQL multipart dietro le quinte.
| Parametro | Tipo | Descrizione |
|---|---|---|
fileBuffer | Buffer | Il contenuto grezzo del file |
filename | string | Il nome del file (utilizzato per l’archiviazione e la visualizzazione) |
contentType | string | Tipo MIME del file (predefinito su application/octet-stream se omesso) |
fieldMetadataUniversalIdentifier | string | L’universalIdentifier del campo di tipo file nel tuo oggetto |
- Il metodo
uploadFileè disponibile suMetadataApiClientperché la mutazione di upload viene risolta dall’endpoint/metadata. - Usa l’
universalIdentifierdel campo (non il suo ID specifico dello spazio di lavoro), quindi il tuo codice di upload funziona in qualsiasi spazio di lavoro in cui la tua app è installata — coerentemente con il modo in cui le app fanno riferimento ai campi altrove. - L’
urlrestituito è un URL firmato che puoi usare per accedere al file caricato.