defineLogicFunction
Definiți funcții logice și declanșatoarele acestora
defineLogicFunction
Definiți funcții logice și declanșatoarele acestora
Fiecare fișier de funcție folosește Tipuri de declanșatoare disponibile:Tipul În handler, accesați anteturile transmise mai departe astfel:Din motive de securitate, anteturile de răspuns sunt limitate la o listă de antete permise. Orice antet care nu se află pe listă (de exemplu, Endpoint-ul este accesibil la:Identificatorul este Contractul resolver-ului. Tipul Payload-ul include:Exemplu de eveniment de creare:Exemplu de eveniment de actualizare:Declanșare doar la actualizări ale e-mailului:Exemplu de eveniment de ștergere:Puncte cheie:Pentru a declara parametrii o singură dată și a deservi ambele suprafețe, definește o singură schemă JSON (Odată ce aplicația este instalată, Enrich Company apare în selectorul de acțiuni al constructorului de fluxuri de lucru. Constructorul afișează
defineLogicFunction() pentru a exporta o configurație cu un handler și declanșatoare opționale.src/logic-functions/createPostCard.logic-function.ts
- httpRoute: Expune funcția pe o cale și o metodă HTTP. În codul aplicației, prefixează calea rutei cu
/s/când foloseștiRestApiClient; URL-ul implementat folosește baza injectatăTWENTY_FUNCTIONS_URL(sau\<server-url>/satunci când nu este setată).
Pentru a apela o funcție logică declanșată de o rută dintr-o componentă front-end (headless), consultă Apelarea unei funcții logice.
- cron: Rulează funcția pe un program folosind o expresie CRON.
- databaseEvent: Rulează la evenimentele ciclului de viață ale obiectelor din spațiul de lucru. Când operațiunea evenimentului este
updated, câmpurile specifice de urmărit pot fi specificate în array-ulupdatedFields. Dacă este lăsat nedefinit sau gol, orice actualizare va declanșa funcția.
de ex.person.updated,*.created,company.*
- serverRoute: Expune o singură rută HTTP la nivelul înregistrării. O funcție de tip resolver (declarată cu
serverRouteTriggerSettings) rulează în workspace-ul proprietar și fie returnează unResponsesincron, fie workspace-ul țintă ȘI funcția logică de pus în coadă; pe ramura de punere în coadă, platforma confirmă cu202și rulează acea țintă în coada worker-ului. Consultați declanșatorul de rută de server.
Puteți, de asemenea, să executați manual o funcție folosind CLI:Puteți urmări jurnalele cu:
Payload-ul declanșatorului de rută
Când un declanșator de rută invocă funcția logică, aceasta primește un obiectRoutePayload care urmează
AWS HTTP API v2 format.
Importați tipul RoutePayload din twenty-sdk/logic-function:RoutePayload are următoarea structură:forwardedRequestHeaders
În mod implicit, anteturile HTTP din cererile de intrare nu sunt transmise funcției dvs. de logică din motive de securitate. Pentru a accesa anumite anteturi, listați-le explicit în array-ulforwardedRequestHeaders:Numele anteturilor sunt normalizate la litere mici. Accesați-le folosind chei cu litere mici (de exemplu,
event.headers['content-type']).Răspuns HTTP personalizat
În mod implicit, returnarea unei valori simple din handler trimite înapoi un răspuns200 (JSON pentru obiecte, text/plain pentru șiruri). Pentru a controla codul de stare și antetele răspunsului, returnează un Response din twenty-sdk/logic-function:Set-Cookie, anteturi CORS precum Access-Control-Allow-Origin sau anteturi personalizate X-*) este eliminat în mod silențios înainte ca răspunsul să fie trimis. Anteturile de răspuns permise sunt:content-typecontent-languagecontent-dispositioncache-controlretry-after
Codul de stare trebuie să fie un cod de stare HTTP valid (între 100 și 599). Numele anteturilor de răspuns sunt comparate fără a ține cont de majuscule și minuscule.
Declanșator de rută de server
httpRouteTriggerSettings expune o funcție sub /s/ și rezolvă spațiul de lucru din gazda cererii — ceea ce funcționează atunci când fiecare spațiu de lucru are propriul domeniu. Furnizorii terți, însă, livrează evenimentele fiecărui tenant către un singur URL. Pentru acest caz, folosiți serverRouteTriggerSettings.Declanșatorul are două părți:-
O funcție logică de resolver — declarată cu
serverRouteTriggerSettings— rulează în workspace-ul deținător (workspace-ul care deține înregistrarea aplicației). Inspectează cererea primită și returnează fie:{ workspaceId, targetLogicFunctionUniversalIdentifier, payload? }— platforma pune în coadă acea țintă în workspace-ul rezolvat și confirmă cu202 { queued: true }, sau- un
Responsede latwenty-sdk/logic-function— platforma transmite mai departe acel răspuns HTTP sincron și nu pune în coadă nicio țintă (folosiți acest lucru pentru handshake-uri de tip challenge, cum ar fi Slackurl_verification).
rawBodyoriginal și la headerele redirecționate și poate respinge fără a atinge vreodată ținta. - O funcție logică țintă — o funcție logică obișnuită per-workspace — rulează apoi în workspace-ul rezolvat cu payload-ul returnat de resolver (sau payload-ul original al cererii dacă resolver-ul nu l-a transformat). Valoarea de returnare nu este observată de apelantul HTTP atunci când resolver-ul a ales calea de punere în coadă.
src/logic-functions/resolve-server-route.logic-function.ts
src/logic-functions/handle-invoice-paid.logic-function.ts
universalIdentifier al resolver-ului din manifestul dvs. Înregistrați acel URL la furnizor.Aplicația trebuie revendicată și instalată în spațiul de lucru al proprietarului. Deoarece resolverul rulează în spațiul de lucru al proprietarului (spațiul de lucru care deține înregistrarea aplicației), un declanșator de rută de server funcționează doar după ce aplicația a fost revendicată — adică are un spațiu de lucru al proprietarului — și acea aplicație este instalată în spațiul de lucru al proprietarului. Până când ambele condiții sunt adevărate, resolverul nu are unde să ruleze, astfel ruta nu poate fi apelată. O aplicație care expune o funcție logică
serverRouteTriggerSettings nu poate fi, așadar, listată în marketplace până când nu este revendicată și instalată în spațiul de lucru al proprietarului.LogicFunctionConfig din SDK impune acest lucru la compilare: de îndată ce setați serverRouteTriggerSettings, handler-ul este constrâns să returneze fie un Response, fie { workspaceId: string; targetLogicFunctionUniversalIdentifier: string; payload?: object } (sau un Promise al uneia dintre acestea). Pe calea de trimitere, workspaceId trebuie să fie un workspace în care funcția țintă este instalată, altfel cererea este respinsă cu 404. Un rezultat care nu corespunde niciuneia dintre forme — inclusiv unul ale cărui identificatoare nu sunt UUID-uri — este respins cu 502.Pentru semnăturile cererilor, majoritatea furnizorilor semnează cu HMAC-SHA256; părțile care diferă sunt numele headerului, codificarea digestului și șirul de payload semnat. Câteva exemple:
Exemplul de resolver de mai sus arată deja fluxul GitHub HMAC-SHA256 — adaptați numele headerului, codificarea digestului și șirul de payload semnat în funcție de furnizorul cu care vă integrați.
Când resolver-ul returnează un obiect de dispatch, ruta răspunde cu
202 { queued: true }, iar ținta rulează în coada worker-ului — apelantul nu observă niciodată latența, rezultatul sau erorile țintei (acestea sunt înregistrate în jurnalele de execuție). Acest lucru împiedică retrimiterile expeditorului să amplifice încetinirile procesării, ceea ce este de dorit pentru ingestia de webhook-uri.Atunci când apelantul trebuie să citească corpul răspunsului în cadrul aceleiași cereri (challenge handshakes, confirmări interactive), returnați în schimb un Response din resolver. Platforma îl reflectă sincron și omite coada; header-ele acestuia trec prin aceeași listă de permisiuni ca răspunsurile rutelor HTTP. Mențineți resolver-ul rapid — unii furnizori (de ex. Slack) expiră după câteva secunde. Deoarece resolver-ul este accesibil ca endpoint public, protejați-l cu limitare de rată la marginea infrastructurii dvs.Payload-ul declanșatorului de eveniment al bazei de date
Când un declanșator de eveniment al bazei de date apelează funcția dvs. logică, aceasta primește unDatabaseEventPayload pentru fiecare înregistrare modificată. Payload-ul combină metadatele despre spațiul de lucru și obiectul sursă cu evenimentul la nivel de înregistrare.Pentru ștergeri logice (soft delete),
.deleted urmează structura de tip update deoarece câmpul deletedAt al înregistrării se modifică.
Pentru ștergeri permanente, folosiți .destroyed.databaseEventTriggerSettings.updatedFields filtrează ce evenimente de actualizare declanșează funcția.
event.properties.updatedFields vă indică ce câmpuri s-au modificat efectiv în evenimentul curent.Expunerea unei funcții ca instrument AI sau ca acțiune în fluxul de lucru
Funcțiile logice pot fi expuse în două locuri, fiecare cu propriul declanșator:toolTriggerSettings— face funcția descoperibilă de către funcționalitățile AI ale Twenty (chat, MCP, apelarea de funcții). Folosește JSON Schema standard, formatul pe care LLM-urile îl înțeleg nativ.workflowActionTriggerSettings— determină ca funcția să apară ca un pas în constructorul vizual de fluxuri de lucru. FoloseșteInputSchemabogat al Twenty, astfel încât constructorul să poată afișa editori de câmp adecvați, selectoare de variabile și etichete.
cronTriggerSettings, databaseEventTriggerSettings și httpRouteTriggerSettings — același tipar, aceeași formă.Relația cu acțiunea Code din fluxul de lucru. Acțiunea integrată Code din constructorul de fluxuri de lucru este ea însăși o funcție logică — Twenty creează câte una pentru fiecare pas Code și afișează editorul inline.
workflowActionTriggerSettings este modul în care transformi acel cod inline, de unică folosință, într-o acțiune reutilizabilă: definești funcția o singură dată în aplicația ta și devine selectabilă în orice flux de lucru, în loc să fie copiată și lipită în fiecare pas Code. Vezi acțiunea Code în ghidul utilizatorului pentru vizualizarea din perspectiva utilizatorului final.src/logic-functions/enrich-company.logic-function.ts
- O funcție poate combina suprafețele — declară atât
toolTriggerSettings, cât șiworkflowActionTriggerSettingspentru a o expune atât în chat, cât și în constructorul de fluxuri de lucru. toolTriggerSettings.inputSchemașiworkflowActionTriggerSettings.inputSchemasunt ambele opționale. Când sunt omise, generatorul de manifest le deduce din codul sursă al handlerului (JSON Schema pentru instrumentul AI,InputSchemaal Twenty pentru acțiunea de flux de lucru). Furnizează unul în mod explicit atunci când dorești o tipizare mai bogată — de exemplu, cu câmpuri compatibile cuFieldMetadataType, precumCURRENCYsauRELATIONpentru constructorul de fluxuri de lucru, sau cu câmpuridescriptionpe care agentul AI le poate citi:
InputJsonSchema) și convertește-o pentru acțiunea din fluxul de lucru cu jsonSchemaToInputSchema din twenty-sdk/logic-function. toolTriggerSettings.inputSchema primește direct schema JSON, în timp ce workflowActionTriggerSettings.inputSchema necesită InputSchema al Twenty:Un exemplu complet de acțiune de flux de lucru
workflowActionTriggerSettings acceptă patru câmpuri:Reunind totul — o funcție expusă ca o acțiune de flux de lucru, cu o ieșire declarată astfel încât pașii următori să poată face referire la
taskId:src/logic-functions/enrich-company.logic-function.ts
companyName și domain ca câmpuri de intrare (fiecare putând prelua valori din pașii anteriori), iar pașii ulteriori pot face referire la ieșirile taskId și enriched ale pasului.Scrieți o
description bună. Agenții AI se bazează pe câmpul description al funcției pentru a decide când să folosească instrumentul. Fiți specifici cu privire la ceea ce face instrumentul și când ar trebui apelat.Ajutoare la rulare (runtime helpers).
twenty-sdk/utils re-exportă mici ajutoare la rulare, astfel încât handlerii să nu importe niciodată direct din twenty-shared. De exemplu, isDefined(value) returnează false atât pentru null, cât și pentru undefined — folosește-l pentru a restrânge în siguranță intrările opționale ale handlerilor, care pot ajunge drept null la rulare, chiar și atunci când sunt tipate T | undefined:Hook-uri de instalare — handleri pre-instalare, post-instalare și dezinstalare — partajează acest runtime, dar sunt declarați cu propriile lor funcții
define și nu folosesc setări de declanșare. Consultați Hook-uri de instalare pentru definePreInstallLogicFunction, definePostInstallLogicFunction și defineUninstallLogicFunction.Clienți API tipizați (twenty-client-sdk)
Pachetultwenty-client-sdk oferă doi clienți GraphQL tipați pentru a interacționa cu API-ul Twenty din funcțiile de logică și componentele Front.
CoreApiClient
Interogați și modificați datele spațiului de lucru (înregistrări, obiecte)
CoreApiClient
Interogați și modificați datele spațiului de lucru (înregistrări, obiecte)
CoreApiClient este clientul principal pentru interogarea și modificarea datelor din spațiul de lucru. Este generat din schema spațiului de lucru în timpul yarn twenty dev sau yarn twenty dev:build, astfel încât este complet tipizat pentru a corespunde obiectelor și câmpurilor dvs.true pentru a include un câmp, folosiți __args pentru argumente și imbricați obiecte pentru relații. Obțineți autocompletare și verificare completă a tipurilor, pe baza schemei spațiului dvs. de lucru.CoreApiClient este generat în timpul dev/build. Dacă îl utilizați fără a rula mai întâi
yarn twenty dev sau yarn twenty dev:build, va arunca o eroare. Generarea are loc automat — CLI inspectează schema GraphQL a spațiului dvs. de lucru și generează un client tipizat folosind @genql/cli.Folosirea CoreSchema pentru adnotări de tip
CoreSchema oferă tipuri TypeScript care corespund obiectelor din spațiul dvs. de lucru — utile pentru tiparea stării componentelor sau a parametrilor funcțiilor:MetadataApiClient
Configurația spațiului de lucru, aplicații și încărcări de fișiere
MetadataApiClient
Configurația spațiului de lucru, aplicații și încărcări de fișiere
MetadataApiClient este livrat preconstruit împreună cu SDK-ul (nu este necesară generarea). Interoghează endpointul /metadata pentru configurarea spațiului de lucru, aplicații și încărcări de fișiere.Încărcarea fișierelor
MetadataApiClient include o metodă uploadFile pentru atașarea fișierelor la câmpuri de tip fișier:Puncte cheie:
- Folosește
universalIdentifieral câmpului (nu ID-ul specific spațiului de lucru), astfel încât codul dvs. de încărcare funcționează în orice spațiu de lucru în care aplicația dvs. este instalată. urlreturnat este un URL semnat pe care îl puteți folosi pentru a accesa fișierul încărcat.
Când codul dvs. rulează pe Twenty (funcții de logică sau componente Front), platforma injectează acreditările ca variabile de mediu:
TWENTY_API_URL— URL-ul de bază al API-ului TwentyTWENTY_APP_ACCESS_TOKEN— Cheie cu durată scurtă, limitată la rolul implicit de funcție al aplicației
process.env. Permisiunile cheii API sunt determinate de rolul declarat cu defineApplicationRole() (sau referențiat prin defaultRoleUniversalIdentifier în application-config.ts).