Panoramica
Le funzioni logiche sono funzioni TypeScript lato server che vengono eseguite sulla piattaforma Twenty. Possono essere attivate da richieste HTTP, pianificazioni cron o eventi del database — e possono anche essere esposte come strumenti per agenti di IA.defineLogicFunction
Definisci funzioni logiche e i relativi trigger
defineLogicFunction
Definisci funzioni logiche e i relativi trigger
Ogni file di funzione usa Tipi di trigger disponibili:Il tipo Nel tuo handler, accedi alle intestazioni inoltrate in questo modo:Per motivi di sicurezza, le intestazioni di risposta sono limitate a un elenco consentito. Qualsiasi intestazione che non è presente nell’elenco (ad esempio L’endpoint è raggiungibile all’indirizzo:Il primo segmento è l’id della registrazione della tua app, il secondo è il Risposta a una verifica GET. Alcuni provider verificano un endpoint prima di inviarvi dati, inviando un La verifica arriva in Contratto del resolver. Il tipo Il payload include:Esempio di evento “updated”:Attiva solo sugli aggiornamenti dell’email:Esempio di evento “destroyed”:L’handler riceve quindi un Gli eventi vengono raggruppati in base all’utente che li ha causati prima di essere inseriti in batch, quindi ogni chiamata riguarda un singolo attore e Crea entrambi una sola volta, nell’ambito del modulo, e ogni punto di chiamata indica quindi quale accesso utilizza in base al client che chiama. Gli helper dell’SDK che accedono alle risorse della tua applicazione usano sempre il relativo accesso e ignorano Punti chiave:Per dichiarare i parametri una sola volta e servire entrambi i contesti, definisci un unico JSON Schema (Il componente legge la chiamata di cui esegue il rendering con Il componente viene montato non appena l’agente ha terminato lo streaming dei suoi argomenti, quindi gestisce l’intera chiamata, non solo il risultato. Una volta che l’app è installata, Enrich Company appare nel selettore di azioni del generatore di workflow. Il generatore visualizza
defineLogicFunction() per esportare una configurazione con un handler e trigger opzionali.src/logic-functions/createPostCard.logic-function.ts
- httpRoute: Espone la tua funzione su un percorso e metodo HTTP. Nel codice dell’app, anteponi al percorso della route
/s/quando utilizziRestApiClient; l’URL distribuito utilizza la baseTWENTY_FUNCTIONS_URLiniettata (o\<server-url>/squando non è impostata).
Per richiamare, da un componente front-end (headless), una funzione logica attivata da una rotta, vedi Chiamare una funzione logica.
- 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.
ad es.person.updated,*.created,company.*
- serverRoute: espone una singola route HTTP con ambito di registrazione. Una funzione di resolver (dichiarata con
serverRouteTriggerSettings) viene eseguita nel workspace proprietario e restituisce unaResponsesincrona, oppure il workspace di destinazione e la funzione logica di destinazione da mettere in coda; nel percorso di messa in coda la piattaforma conferma con202ed esegue tale destinazione nella coda dei worker. Vedi Trigger route del server.
Puoi anche eseguire manualmente una funzione utilizzando la CLI:Puoi osservare i log con:
Nel cloud, ogni esecuzione consuma crediti dello spazio di lavoro: un costo fisso per
invocazione più un costo per millisecondo per il tempo di esecuzione della funzione, quindi
mantenere
timeoutSeconds limitato e il codice veloce riduce i costi. Vedi
Crediti per le tariffe.Payload del trigger di route
Quando un trigger di tipo route invoca la tua funzione logica, questa riceve un oggettoRoutePayload che segue il formato AWS HTTP API v2.
Importa il tipo RoutePayload da twenty-sdk/logic-function:RoutePayload ha la seguente struttura:forwardedRequestHeaders
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 nell’arrayforwardedRequestHeaders:I nomi delle intestazioni vengono normalizzati in minuscolo. Accedile usando chiavi in minuscolo
(ad es.,
event.headers['content-type']).Risposta HTTP personalizzata
Per impostazione predefinita, restituire un valore semplice dal tuo handler lo invia come risposta200 (JSON per gli oggetti, text/plain per le stringhe). Per controllare il codice di stato e le intestazioni della risposta, restituisci un oggetto Response da twenty-sdk/logic-function:Set-Cookie, intestazioni CORS come Access-Control-Allow-Origin o intestazioni personalizzate X-*) viene ignorata senza segnalazione prima che la risposta venga inviata. Le intestazioni di risposta consentite sono:content-typecontent-languagecontent-dispositioncache-controlretry-after
Il codice di stato deve essere un codice di stato HTTP valido (compreso tra 100 e 599).
I nomi delle intestazioni di risposta vengono confrontati senza distinzione tra maiuscole e minuscole.
Risposte di errore della piattaforma
Oltre alle risposte specifiche del tuo handler, la piattaforma risponde direttamente alle chiamate di route in alcune situazioni:404 quando la route o la funzione non esiste, 403 quando l’applicazione è arrestata, 402 quando il workspace ha esaurito il proprio credito o non ha un abbonamento attivo, 409 quando viene raggiunto un limite di archiviazione, 429 quando viene raggiunto un rate limit di esecuzione o un limite di utilizzo e 422 quando le dependencies dell’applicazione in produzione sono troppo grandi per essere installate — vedi limiti di dimensione delle dipendenze.Trigger route del server
httpRouteTriggerSettings espone una funzione sotto /s/ e risolve lo spazio di lavoro dall’host della richiesta — il che funziona quando ogni spazio di lavoro ha il proprio dominio. I provider di terze parti, tuttavia, inviano gli eventi di ogni tenant a un URL. Per questo caso, usa serverRouteTriggerSettings.Il trigger ha due parti:-
Una funzione logica di resolver — dichiarata con
serverRouteTriggerSettings— viene eseguita nel tuo workspace proprietario (il workspace che possiede la registrazione dell’applicazione). Analizza la richiesta in ingresso e restituisce:{ workspaceId, targetLogicFunctionUniversalIdentifier, payload? }— la piattaforma mette in coda tale destinazione nel workspace risolto e conferma con202 { queued: true }, oppure- una
Responsedatwenty-sdk/logic-function— la piattaforma restituisce tale risposta HTTP sincronicamente e non mette in coda alcuna destinazione (usa questo per challenge handshake come Slackurl_verification).
rawBodyoriginale e agli header inoltrati, e può rifiutare senza toccare la destinazione. - Una funzione logica di destinazione — una normale funzione logica per-workspace — viene quindi eseguita nel workspace risolto con il payload restituito dal resolver (o il payload originale della richiesta se il resolver non lo ha trasformato). Il suo valore di ritorno non viene osservato dal chiamante HTTP quando il resolver ha scelto il percorso di messa in coda.
src/logic-functions/resolve-server-route.logic-function.ts
src/logic-functions/handle-invoice-paid.logic-function.ts
universalIdentifier del resolver dal tuo manifest. Una route viene risolta solo a un resolver di quella registrazione, nel relativo workspace proprietario. Quando la tua app registra il webhook stesso, crea l’URL dall’interno di una funzione logica con getServerRouteUrl; Twenty inserisce l’URL di base delle route del server della tua app come TWENTY_SERVER_ROUTES_URL:Gli URL che contengono solo l’
id o l’universalIdentifier del resolver
(/webhooks/server/:identifier) continuano per ora a essere risolti, ed entrambi restituiscono
un’intestazione Deprecation. Il formato universalIdentifier restituisce 409 quando due
registrazioni dichiarano lo stesso identificatore. Sposta gli URL registrati presso i tuoi
provider nel modulo di registrazione.GET contenente una verifica allo stesso URL a cui in seguito invieranno eventi tramite POST — WhatsApp Cloud API di Meta è uno di questi. Una route del server risponde solo a POST, a meno che non venga specificato diversamente, quindi dichiara entrambi i metodi:event.queryStringParameters e la restituzione di un Response la rimanda al provider nella stessa richiesta. Un corpo stringa viene inviato come text/plain, che è ciò che questi provider si aspettano:httpMethods sostituisce l’impostazione predefinita anziché aggiungersi a essa, quindi ['GET'] da solo fa sì che la route rifiuti POST. Sono supportati solo GET e POST. Lascialo non impostato a meno che il provider non richieda il secondo verbo: una route che dichiara GET avrà il proprio resolver eseguito da qualsiasi chiamante non autenticato, inclusi i crawler e gli strumenti di anteprima dei link che inviano GET senza richiesta. A tutto ciò per cui la piattaforma non dispone di un metodo viene restituito 405 senza che il resolver venga mai eseguito.L’applicazione deve essere rivendicata e installata nel suo spazio di lavoro proprietario.
Segui Rivendicare la tua
app per
assegnare un proprietario, quindi installa l’app in quello spazio di lavoro. Finché entrambe le condizioni non sono soddisfatte,
il resolver non ha dove essere eseguito e la route del server restituisce
404
(LOGIC_FUNCTION_NOT_FOUND), anche se l’app è installata altrove.
La ricerca nel Marketplace nasconde le app con route del server finché questa configurazione e tutte
le variabili del server richieste non sono complete. Vedi costi e
disponibilità dello spazio di lavoro proprietario
per i dettagli di fatturazione e operativi.LogicFunctionConfig dell’SDK impone questo a tempo di compilazione: non appena imposti serverRouteTriggerSettings, il tuo handler è vincolato a restituire una Response, oppure { workspaceId: string; targetLogicFunctionUniversalIdentifier: string; payload?: object } (o una Promise di uno dei due). Nel percorso di dispatch, il workspaceId deve essere un workspace in cui la funzione di destinazione è installata, altrimenti la richiesta viene rifiutata con 404. Un risultato che non corrisponde a nessuna delle due forme — incluso uno i cui identificatori non sono UUID — viene rifiutato con 502.Token bearer. Alcuni provider, come Microsoft Bot Framework, firmano ogni richiesta con un JWT nell’intestazione
Authorization anziché con un’intestazione di firma. Una route del server può elencare authorization in forwardedRequestHeaders per riceverla e il resolver la verifica come qualsiasi altra firma. La piattaforma rimuove l’intestazione se contiene un token emesso da Twenty, quindi una route del server non riceve mai una sessione Twenty. cookie e proxy-authorization non vengono mai inoltrati e le route HTTP non possono inoltrare nessuna di queste tre intestazioni.Per le firme delle richieste, la maggior parte dei provider firma con HMAC-SHA256; le parti che differiscono sono il nome dell’header, la codifica del digest e la stringa del payload firmato. Alcuni esempi:L’esempio di resolver sopra mostra già il flusso HMAC-SHA256 di GitHub — adatta il nome dell’header, la codifica del digest e la stringa del payload firmato in base al provider con cui ti stai integrando.
Quando il resolver restituisce un oggetto di dispatch, la route risponde con
202 { queued: true } e la funzione di destinazione viene eseguita nella coda dei worker — il chiamante non osserva mai la latenza, il risultato o gli errori della funzione di destinazione (che vengono registrati nei log di esecuzione). Questo impedisce che le nuove consegne da parte del mittente amplifichino i rallentamenti nell’elaborazione, che è esattamente ciò che si desidera per l’acquisizione dei webhook.Il resolver viene eseguito nel workspace del proprietario e utilizza i relativi crediti, pertanto la route restituisce 402 quando tale workspace ha esaurito il proprio credito o non ha un abbonamento attivo, e 429 quando viene raggiunto un limite di utilizzo. I mittenti che ritentano in caso di 5xx non ritenteranno in questi casi, ed è ciò che vuoi: il rifiuto non si risolverà al tentativo successivo.Quando il chiamante deve leggere il corpo della risposta sulla stessa richiesta (challenge handshake, acknowledgement interattivi), restituisci invece una Response dal resolver. La piattaforma lo riecheggia in modo sincrono e salta la coda; i suoi header passano attraverso la stessa allow-list delle risposte delle route HTTP. Mantieni il resolver veloce — alcuni provider (ad es. Slack) vanno in timeout in pochi secondi. Poiché il resolver è raggiungibile come endpoint pubblico, proteggilo con rate limiting al tuo edge.Payload del trigger di evento del database
Quando un trigger di evento del database richiama la funzione logica, questa riceve unDatabaseEventPayload per ogni record modificato (oppure un DatabaseEventBatchPayload che copre più record quando batchMode è abilitato). Il payload combina i metadati sull’area di lavoro e sull’oggetto di origine con l’evento a livello di record.Per le eliminazioni logiche,
.deleted segue la struttura in stile aggiornamento perché il campo deletedAt del record cambia.
Per le eliminazioni permanenti, usa .destroyed.databaseEventTriggerSettings.updatedFields filtra quali eventi di aggiornamento
attivano la funzione. event.properties.updatedFields indica quali campi
sono effettivamente cambiati nell’evento corrente.databaseEventTriggerSettings accetta:Esempio di evento “created”:
Raggruppamento degli eventi del database
Una scrittura in blocco genera molti eventi contemporaneamente: l’importazione di una casella di posta, ad esempio, può aggiornare migliaia di record in una singola operazione e una chiamata per record sovraccarica la coda. ImpostabatchMode per riceverli insieme:DatabaseEventBatchPayload, che contiene gli stessi metadati di DatabaseEventPayload ma sostituisce i campi a livello di record con un array events:La dimensione del batch non è qualcosa su cui un handler può fare affidamento. Il server decide quanti
eventi contiene una chiamata, con un massimo di 200, e un batch contiene da un singolo
evento fino a tale limite, a seconda di quanti ne ha prodotto la scrittura di origine.
Scrivi l’handler in modo che esegua il ciclo su
events, indipendentemente dalla sua lunghezza.context.workspaceMemberId mantiene il proprio significato. Il filtro updatedFields viene applicato prima del raggruppamento in batch, quindi un batch contiene solo i record richiesti.Senza batchMode, l’handler continua a ricevere un DatabaseEventPayload per record.Contesto di esecuzione
I gestori di funzioni logiche generiche ricevono un secondo argomento che descrive l’esecuzione stessa, indipendentemente da ciò che l’ha attivata. Mentre il primo argomento cambia struttura in base all’attivatore, questo no:userWorkspaceId e workspaceMemberId sono null quando nessuno ha attivato l’esecuzione: le pianificazioni cron, gli hook di installazione e i webhook non autenticati non hanno una persona alle spalle. Sono inoltre null quando la persona non ha un record del membro dello spazio di lavoro o quando il suo è stato eliminato.Il contesto indica chi ha attivato l’esecuzione. Ciò che l’esecuzione può fare è una
dichiarazione separata, riportata di seguito.
Quale accesso utilizza una chiamata
Ogni client —CoreApiClient, MetadataApiClient e RestApiClient — agisce come la persona che ha attivato l’esecuzione: il suo ruolo intersecato con quello della tua applicazione, quindi la chiamata non può mai fare più di quanto possa fare ciascuno dei due. Questo è il comportamento predefinito e significa che una persona non può mai usare la tua app per superare le proprie autorizzazioni.Quando nessuno ha attivato l’esecuzione, non c’è nessuna persona per conto della quale agire, quindi lo stesso client usa come fallback l’accesso della tua applicazione: le pianificazioni cron, gli hook di installazione e i webhook non autenticati non richiedono una gestione speciale.Alcune chiamate necessitano legittimamente dell’accesso dell’applicazione stessa anche quando una persona è dietro l’esecuzione — per leggere i record di configurazione della tua app o per svolgere operazioni che quella persona non potrebbe eseguire autonomamente. Crea un secondo client per questi casi:RestApiClient accetta la stessa opzione:Un’esecuzione che nessuno ha attivato agisce come la tua applicazione. Le pianificazioni cron, gli hook di installazione e i webhook non autenticati non hanno una persona alle spalle, quindi il client predefinito usa come fallback l’accesso della tua applicazione e continua a funzionare.
runAs: 'application' è necessario solo quando vuoi tale accesso in un’esecuzione che una persona ha attivato.Controlla context.workspaceMemberId quando una funzione si comporta diversamente a seconda che ci sia qualcuno alle sue spalle, ad esempio per attribuire un record.runAs: l’archivio chiave-valore, le connessioni, i canali di messaggistica, runAgent, getPublicAssetUrl e l’addebito dei crediti. ai.generate segue invece i client predefiniti: agisce come la persona che ha avviato l’esecuzione, nell’ambito del ruolo della tua app, oppure come la tua app quando nessuno l’ha avviata.Esporre una funzione come strumento di IA o come azione del flusso di lavoro
Le funzioni logiche possono essere esposte su due superfici, ciascuna con il proprio trigger:toolTriggerSettings— rende la funzione individuabile dalle funzionalità di IA di Twenty (chat, MCP, function calling). Usa lo standard JSON Schema, il formato che gli LLM comprendono nativamente.workflowActionTriggerSettings— fa apparire la funzione come un passaggio nel builder visivo dei flussi di lavoro. Usa il riccoInputSchemadi Twenty affinché il builder possa visualizzare correttamente editor di campi, selettori di variabili ed etichette.
cronTriggerSettings, databaseEventTriggerSettings e httpRouteTriggerSettings — stesso schema, stessa struttura.Relazione con l’azione Code del workflow. L’azione Code incorporata nel
generatore di workflow è essa stessa una funzione logica — Twenty ne crea una per ogni passaggio Code
e ne espone l’editor inline.
workflowActionTriggerSettings è il modo in cui
trasformi quel codice inline una tantum in un’azione riutilizzabile: definisci la funzione
una volta nella tua app e diventa selezionabile in qualsiasi workflow, invece di essere
copiata e incollata in ogni passaggio Code. Consulta l’azione
Code nella guida
utente per la vista dell’utente finale.src/logic-functions/enrich-company.logic-function.ts
- Una funzione può combinare le superfici — dichiara sia
toolTriggerSettingssiaworkflowActionTriggerSettingsper esporla in chat E nel builder dei flussi di lavoro. toolTriggerSettings.inputSchemaeworkflowActionTriggerSettings.inputSchemasono entrambi opzionali. Se omessi, il builder del manifest li deduce dal codice sorgente dell’handler (JSON Schema per lo strumento di IA,InputSchemadi Twenty per l’azione del flusso di lavoro). Forniscine uno esplicitamente quando desideri una tipizzazione più ricca — ad esempio, con campi compatibili conFieldMetadataTypecomeCURRENCYoRELATIONper il builder dei flussi di lavoro, oppure con campidescriptionche l’agente di IA può leggere:
InputJsonSchema) e convertilo per l’azione del flusso di lavoro con jsonSchemaToInputSchema da twenty-sdk/logic-function. toolTriggerSettings.inputSchema accetta direttamente il JSON Schema, mentre workflowActionTriggerSettings.inputSchema si aspetta l’InputSchema di Twenty:Rendering di una chiamata dello strumento con un componente front
Per impostazione predefinita, una chiamata dello strumento viene visualizzata nella chat AI come riga del passaggio: il nome dello strumento e un indicatore di caricamento finché non restituisce un risultato. ImpostatoolTriggerSettings.frontComponentUniversalIdentifier su uno dei tuoi componenti front e la chat eseguirà invece il rendering di quel componente in linea, per ogni chiamata a questo strumento.useToolCall():src/front-components/invoice-preview.tsx
toolCall.status passa attraverso input-available, gli stati di approvazione quando lo strumento ne richiede una, e quindi output-available, output-denied o output-error; input è ciò che l’agente ha proposto, output ciò che il tuo gestore ha restituito. Esegui il rendering di ogni stato che ti interessa, poiché la riga del passaggio non è più presente per gestirli.Sia input sia output sono tipizzati come Record\<string, unknown>, quindi restringi ogni campo prima di utilizzarlo anziché eseguire un cast. Ciò è particolarmente importante per tutto ciò che passi al DOM: un valore che inserisci in un href senza verificare che sia una stringa è un link controllato dall’output dello strumento.Se l’identificatore non corrisponde a nessun componente front-end nell’app, la chat torna
alla riga del passaggio predefinita. I componenti front-end nella chat IA vengono eseguiti con lo stesso
ruolo dichiarato dalla tua app, pertanto un widget
può solo leggere e scrivere ciò che l’app stessa è autorizzata a fare.
Un esempio completo di azione di workflow
workflowActionTriggerSettings accetta quattro campi:Mettendo tutto insieme: una funzione esposta come azione di workflow, con un output dichiarato così che i passaggi successivi possano fare riferimento a
taskId:src/logic-functions/enrich-company.logic-function.ts
companyName e domain come campi di input (ognuno in grado di prelevare valori dai passaggi precedenti), e i passaggi a valle possono fare riferimento ai risultati taskId ed enriched del passaggio.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.Helper di runtime.
twenty-sdk/utils riesporta piccoli helper di runtime in modo che gli handler non importino mai direttamente da twenty-shared. Per esempio, isDefined(value) restituisce false sia per null che per undefined — usalo per restringere in modo sicuro gli input opzionali degli handler, che possono arrivare come null a runtime anche quando sono tipizzati come T | undefined:Hook di installazione — i gestori di pre-installazione, post-installazione e disinstallazione — condividono
questo runtime, ma sono dichiarati con le proprie funzioni di definizione e non accettano
impostazioni dei trigger. Consulta Hook di
installazione per
definePreInstallLogicFunction, definePostInstallLogicFunction e
defineUninstallLogicFunction.Controllo di integrità.
Dichiara un controllo di integrità condefineHealthCheck per segnalare se la tua app è effettivamente in grado di funzionare. Riguarda ciò che solo l’app può sapere: una chiave presente ma revocata, un account con il piano sbagliato, un webhook che non è mai stato registrato. Ciò che Twenty può rilevare autonomamente — una variabile obbligatoria che nessuno ha compilato — è gestito da isRequired e non richiede codice.
Viene eseguito lato server, quindi legge le variabili segrete come qualsiasi altra funzione logica. Un controllo dello spazio di lavoro non ha nessuno alle spalle, quindi il gestore non richiede argomenti.
src/logic-functions/health-check.ts
OK non mostra alcun banner; ogni altro stato visualizza il titolo in un banner colorato in base allo stato, quindi scegli quello che corrisponde al grado di azione richiesto alla persona. Gli stati sono gli ApplicationHealthStatus di Twenty, quindi la stringa semplice e il membro enum sono intercambiabili:
/ o #: una posizione esterna, relativa al protocollo o relativa perde il proprio pulsante anziché diventare un reindirizzamento altrove. Il pulsante viene inoltre rimosso quando l’app non segnala alcuna posizione e non dispone di una scheda di configurazione a cui ricorrere, quindi un controllo su un’app senza variabili e senza voci del menu delle impostazioni mostra il relativo titolo senza un pulsante non funzionante.
Controllo della configurazione di ciascun membro
Un’app dichiara una funzione di controllo dell’integrità. OmettirunOnUserPreferences o impostalo su false per eseguire un controllo dello spazio di lavoro nella pagina delle impostazioni dell’app, con un gestore senza argomenti. Imposta runOnUserPreferences: true per eseguire invece un controllo del membro nella pagina delle preferenze delle app. Un gestore del membro riceve il valore obbligatorio { userWorkspaceId: string } dalla sessione autenticata:
src/logic-functions/health-check.ts
{ userWorkspaceId } dalla sessione autenticata e le variabili con ambito utente mantengono i propri valori. L’oggetto parametro e l’ID sono obbligatori per questa modalità. Non viene eseguito nelle impostazioni dell’app dello spazio di lavoro. Passa userWorkspaceId a listConnections() affinché restituisca solo le connessioni di quel membro. Una connessione il cui aggiornamento del token non riesce viene esclusa dall’elenco, quindi “nessuna connessione” include anche “riconnetti”. Un pulsante senza location porta alla scheda Generale dell’app in quella pagina.
I controlli del membro richiedono Twenty 2.55.0 o versioni successive. Preferenze delle app non è ancora abilitato
in tutti gli spazi di lavoro: dove non lo è, un controllo del membro non viene mai eseguito.
Crea un’attività della cronologia di eventi
UsacreateTimelineActivity() per pubblicare un evento di dominio esplicito da una funzione logica. Definisci prima l’evento come tipo di attività della cronologia, quindi fai riferimento al tipo e agli oggetti tramite i relativi identificatori universali stabili:
timelineActivityTypeUniversalIdentifier, targetObjectUniversalIdentifier e targetRecordId. Puoi anche fornire happensAt, properties e workspaceMemberId. happensAt controlla la posizione e l’ora visualizzata dell’evento nella cronologia; per impostazione predefinita corrisponde all’ora di creazione.
Per associare un altro record all’evento, fornisci insieme linkedRecordId e linkedObjectMetadataUniversalIdentifier. Puoi inoltre fornire linkedRecordCachedName come alternativa di visualizzazione storica:
timelineActivity. Mantieni i tipi di evento espliciti non associati a un’action; un tipo associato a un’azione riceve già eventi di audit automatici e altrimenti produrrebbe righe duplicate.
Client API tipizzati (twenty-client-sdk)
Il pacchettotwenty-client-sdk fornisce due client GraphQL tipizzati per interagire con l’API di Twenty dalle tue funzioni logiche e dai componenti front-end.
CoreApiClient
Esegui query e modifica i dati dello spazio di lavoro (record, oggetti)
CoreApiClient
Esegui query e modifica i dati dello spazio di lavoro (record, oggetti)
CoreApiClient è il client principale per interrogare e modificare i dati dello spazio di lavoro. Viene generato dallo schema del tuo spazio di lavoro con twenty app generate-client, o dopo una sincronizzazione con twenty app apply o twenty app dev, quindi è completamente tipizzato per corrispondere ai tuoi oggetti e campi.shareWith è rilevante solo su un oggetto i cui record sono privati; altrove l’argomento viene ignorato. Su un oggetto di questo tipo, elenca chi ottiene l’accesso al record creato: ogni voce si rivolge esattamente a uno tra workspaceMemberId, roleId o everyone: true, con un accessLevel pari a READ, READ_WRITE o FULL. Un membro dello spazio di lavoro che crea un record riceve sempre un’autorizzazione proprietario FULL, quindi l’argomento è facoltativo per lui; anche una funzione logica che agisce come relativa applicazione o una chiave API riceve un’autorizzazione FULL per il proprio ruolo e tali chiamanti, come un chiamante di sistema, devono passare shareWith, altrimenti la creazione viene rifiutata. Ogni voce deve indicare un membro o un ruolo dello spazio di lavoro. Una funzione logica o una chiave API condivide tramite il proprio ruolo, quindi ogni titolare di tale ruolo ottiene lo stesso accesso ai record che crea; assegna a una chiave i cui record devono rimanere privati un ruolo proprio.Il client utilizza una sintassi a selection-set: passa true per includere un campo, usa __args per gli argomenti e annida oggetti per le relazioni. Ottieni completamento automatico e controllo dei tipi completi basati sullo schema del tuo spazio di lavoro.Esegui
twenty app generate-client per aggiornare il client dallo schema GraphQL del tuo spazio di lavoro. twenty app apply e twenty app dev lo rigenerano anche dopo la sincronizzazione. twenty app build esegue la build solo localmente e non genera il client.Utilizzo di CoreSchema per le annotazioni di tipo
CoreSchema fornisce tipi TypeScript corrispondenti agli oggetti del tuo spazio di lavoro — utile per tipizzare lo stato dei componenti o i parametri delle funzioni:MetadataApiClient
Configurazione dello spazio di lavoro, applicazioni e caricamenti di file
MetadataApiClient
Configurazione dello spazio di lavoro, applicazioni e caricamenti di file
MetadataApiClient è fornito pronto all’uso con l’SDK (nessuna generazione richiesta). Interroga l’endpoint /metadata per la configurazione dello spazio di lavoro, le applicazioni e i caricamenti di file. Accetta la stessa opzione runAs di CoreApiClient — vedi Quale accesso utilizza una chiamata.È anche il modo in cui un’app legge e aggiorna le proprie variabili dell’applicazione, in una funzione logica come in un componente front. Un token dell’applicazione raggiunge solo la propria applicazione, nel proprio spazio di lavoro.Una variabile utente si trova in process.env con il valore del membro che ha attivato l’esecuzione o con il relativo valore predefinito finché non imposta il proprio. Un’esecuzione non attivata da nessuno non riceve variabili utente. Per leggere il valore delle variabili utente della tua app per ogni membro, ad esempio in un processo cron, esegui una query su myUserApplicationVariables con runAs: 'application'.Caricamento dei file
MetadataApiClient include un metodo uploadFile per allegare file ai campi di tipo file. Il file viene inviato direttamente all’archiviazione file di Twenty: l’API fornisce una destinazione di caricamento, il client invia lì i byte, quindi l’API conferma il caricamento.Punti chiave:
- 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. - Il tipo MIME viene rilevato dal contenuto del file una volta caricato, quindi non c’è nulla da dichiarare.
- L’
urlrestituito è un URL firmato che puoi usare per accedere al file caricato.
Quando il tuo codice viene eseguito su Twenty (funzioni logiche o componenti front-end), la piattaforma inietta le credenziali come variabili d’ambiente:
TWENTY_API_URL— URL di base dell’API di TwentyTWENTY_APP_ACCESS_TOKEN— Chiave a breve durata per l’accesso predefinito: il ruolo di una persona intersecato con quello della tua applicazione quando qualcuno è alle spalle dell’esecuzione, il ruolo della tua applicazione quando non c’è nessuno. La persona è chiunque abbia attivato l’esecuzione in una funzione logica, oppure chiunque stia visualizzando la pagina in un componente front-end.TWENTY_APP_APPLICATION_ACCESS_TOKEN— Chiave a breve durata con ambito esclusivamente al ruolo della tua applicazione. Solo funzioni logiche, sempre inserita lì, ed è ciò che utilizzarunAs: 'application'.
process.env e Quale accesso utilizza una chiamata spiega come scegliere tra di essi. Le autorizzazioni della tua applicazione sono determinate dal ruolo dichiarato con defineApplicationRole() (o referenziato tramite defaultRoleUniversalIdentifier in application-config.ts); un’esecuzione che agisce come una persona non può mai superare né tale ruolo né il proprio.