Prezentare generală
Funcțiile de logică sunt funcții TypeScript pe partea de server care rulează pe platforma Twenty. Acestea pot fi declanșate de solicitări HTTP, programări cron sau evenimente din baza de date — și pot fi, de asemenea, expuse ca instrumente pentru agenți AI.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:Primul segment este ID-ul înregistrării aplicației dvs., iar al doilea este Răspunsul la un GET de verificare. Unii furnizori verifică un punct final înainte de a livra către acesta, trimițând un Provocarea ajunge în Contractul resolver-ului. Tipul Payload-ul include:Exemplu de eveniment de actualizare:Declanșare doar la actualizări ale e-mailului:Exemplu de eveniment de ștergere:Funcția de gestionare primește apoi un Evenimentele sunt grupate după utilizatorul care le-a provocat înainte de a fi incluse în loturi, astfel încât fiecare apel acoperă un singur actor, iar Creați-le pe amândouă o singură dată, la nivel de modul, iar fiecare loc de apel indică apoi accesul utilizat prin clientul pe care îl apelează. Funcțiile ajutătoare SDK care accesează propriile resurse ale aplicației dvs. folosesc întotdeauna accesul acesteia și ignoră Puncte cheie:Pentru a declara parametrii o singură dată și a deservi ambele suprafețe, definește o singură schemă JSON (Componenta citește apelul pe care îl afișează folosind Componenta se montează imediat ce agentul a terminat transmiterea în flux a argumentelor sale, astfel încât gestionează întregul apel, nu doar rezultatul. 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:
În cloud, fiecare rulare consumă credite ale spațiului de lucru: o taxă fixă per
apelare plus o taxă per milisecundă pentru timpul de rulare al funcției, astfel
încât menținerea unui
timeoutSeconds scurt și a codului rapid reduce costurile. Consultați
Credite pentru tarife.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.
Răspunsuri de eroare ale platformei
Pe lângă propriile răspunsuri ale handlerului tău, platforma răspunde direct la apelurile către rute în anumite situații:404 când ruta sau funcția nu există, 403 când aplicația este oprită, 402 când spațiul de lucru și-a epuizat alocarea de credite sau nu are un abonament activ, 409 când este atinsă o limită de stocare, 429 când este atinsă o limită a ratei de execuție sau o limită de utilizare și 422 când dependencies de producție ale aplicației sunt prea mari pentru a fi instalate — vezi limite privind dimensiunea dependențelor.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. O rută se rezolvă doar către un resolver al acelei înregistrări, în spațiul de lucru al proprietarului. Când aplicația dvs. înregistrează webhook-ul propriu-zis, construiți URL-ul dintr-o funcție logică folosind getServerRouteUrl; Twenty injectează URL-ul de bază al rutelor de server ale aplicației dvs. ca TWENTY_SERVER_ROUTES_URL:URL-urile care conțin doar
id sau universalIdentifier ale resolverului
(/webhooks/server/:identifier) sunt încă rezolvate deocamdată, iar ambele răspund cu
un antet Deprecation. Forma universalIdentifier returnează 409 atunci când două
înregistrări declară același identificator. Mutați URL-urile înregistrate la
furnizorii dvs. în formularul de înregistrare.GET care conține o provocare la același URL către care vor trimite ulterior evenimente prin POST — WhatsApp Cloud API de la Meta este unul dintre aceștia. O rută de server răspunde numai la POST, cu excepția cazului în care specifici altfel, așa că declară ambele metode:event.queryStringParameters, iar returnarea unui Response o retransmite furnizorului în aceeași cerere. Un corp de tip șir este trimis ca text/plain, ceea ce așteaptă acești furnizori:httpMethods înlocuiește valoarea implicită, în loc să se adauge la aceasta, astfel încât doar ['GET'] face ca ruta să respingă POST. Sunt acceptate numai GET și POST. Lăsați-o nesetată, cu excepția cazului în care furnizorul are nevoie de al doilea verb: o rută care declară GET își va executa resolverul pentru orice apelant neautentificat, inclusiv pentru crawlerele și serviciile de desfășurare a linkurilor care trimit GET fără solicitare. Orice pentru care platforma nu are o metodă primește răspunsul 405, fără ca resolverul să fie vreodată executat.Aplicația trebuie revendicată și instalată în spațiul de lucru al proprietarului său.
Urmați instrucțiunile din Revendicarea
aplicației dvs. pentru a
atribui un proprietar, apoi instalați aplicația în acel spațiu de lucru. Până când ambele condiții sunt îndeplinite,
resolver-ul nu are unde să ruleze, iar ruta serverului returnează
404
(LOGIC_FUNCTION_NOT_FOUND), chiar dacă aplicația este instalată în altă parte.
Căutarea Marketplace ascunde aplicațiile cu rute de server până când această configurare și toate
variabilele de server necesare sunt complete. Consultați costurile și
disponibilitatea spațiului de lucru al proprietarului
pentru detalii despre facturare și funcționare.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.Tokenuri Bearer. Unii furnizori, precum Microsoft Bot Framework, semnează fiecare solicitare cu un JWT în antetul
Authorization în locul unui antet de semnătură. O rută de server poate lista authorization în forwardedRequestHeaders pentru a-l primi, iar resolverul îl verifică la fel ca orice altă semnătură. Platforma elimină antetul dacă acesta conține un token emis de Twenty, astfel încât o rută de server nu primește niciodată o sesiune Twenty. cookie și proxy-authorization nu sunt niciodată redirecționate, iar rutele HTTP nu pot redirecționa niciunul dintre aceste trei anteturi.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.Resolverul rulează în spațiul de lucru al proprietarului și îi cheltuiește creditele, astfel încât ruta răspunde cu 402 când acel spațiu de lucru și-a epuizat alocarea sau nu are un abonament activ și cu 429 când este atinsă o limită de utilizare. Expeditorii care reîncearcă la 5xx nu vor reîncerca aceste răspunsuri, ceea ce este de dorit: refuzul nu va dispărea la următoarea încercare.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
Atunci când un declanșator de eveniment al bazei de date invocă funcția logică, aceasta primește câte unDatabaseEventPayload pentru fiecare înregistrare modificată (sau un DatabaseEventBatchPayload care acoperă mai multe înregistrări atunci când batchMode este activat). 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.databaseEventTriggerSettings acceptă:Exemplu de eveniment de creare:
Gruparea în loturi a evenimentelor bazei de date
O scriere în masă emite multe evenimente simultan: de exemplu, importarea unei cutii poștale poate actualiza mii de înregistrări într-o singură operație, iar un apel pentru fiecare înregistrare inundă coada. SetațibatchMode pentru a le primi împreună:DatabaseEventBatchPayload, care conține aceleași metadate ca DatabaseEventPayload, dar înlocuiește câmpurile de la nivelul înregistrării cu o matrice events:Dimensiunea lotului nu este ceva pe care o funcție de gestionare se poate baza. Serverul decide câte
evenimente conține un apel, cu o limită de 200, iar un lot conține de la un singur
eveniment până la această limită, în funcție de câte a produs scrierea inițială.
Scrieți funcția de gestionare astfel încât să parcurgă
events, indiferent de lungimea sa.context.workspaceMemberId rămâne relevant. Filtrarea updatedFields se aplică înainte de gruparea în loturi, astfel încât un lot conține numai înregistrările solicitate.Fără batchMode, funcția de gestionare continuă să primească un DatabaseEventPayload pentru fiecare înregistrare.Contextul execuției
Handler-ele funcțiilor logice generice primesc un al doilea argument care descrie rularea în sine, indiferent de ce a declanșat-o. În timp ce primul argument își schimbă forma pentru fiecare declanșator, acesta nu se schimbă:userWorkspaceId și workspaceMemberId sunt null atunci când nimeni nu a declanșat execuția: programările cron, hookurile de instalare și webhookurile neautentificate nu au nicio persoană în spatele lor. De asemenea, sunt null atunci când persoana nu are o înregistrare de membru al spațiului de lucru sau când aceasta a fost ștearsă.Contextul vă indică cine a declanșat rularea. Ce poate face rularea este o
declarație separată, mai jos.
Ale cui accesări le utilizează un apel
Fiecare client —CoreApiClient, MetadataApiClient și RestApiClient — acționează ca persoana care a declanșat execuția: rolul acesteia se intersectează cu cel al aplicației dvs., astfel încât apelul nu poate face niciodată mai mult decât poate face oricare dintre voi. Acesta este comportamentul implicit și înseamnă că o persoană nu poate folosi niciodată aplicația dvs. pentru a-și depăși propriile permisiuni.Când nimeni nu a declanșat execuția, nu există nicio persoană în numele căreia să se acționeze, astfel încât același client revine la accesul propriu al aplicației dvs.: programările cron, hookurile de instalare și webhookurile neautentificate nu necesită o gestionare specială.Unele apeluri au nevoie în mod legitim de propriul acces al aplicației chiar și atunci când o persoană se află în spatele rulării — pentru a citi înregistrările de configurare ale aplicației dvs. sau pentru a efectua operațiuni pe care acea persoană nu le-ar putea face singură. Creați un al doilea client pentru acestea:RestApiClient acceptă aceeași opțiune:O execuție pe care nu a declanșat-o nimeni acționează ca aplicația dvs. Programările cron, hookurile de instalare și webhookurile neautentificate nu au nicio persoană în spatele lor, astfel încât clientul implicit revine la accesul propriu al aplicației dvs. și continuă să funcționeze.
runAs: 'application' este necesar doar când doriți acel acces într-o execuție pe care o persoană a declanșat-o.Verificați context.workspaceMemberId atunci când o funcție se comportă diferit în funcție de existența unei persoane în spatele ei, de exemplu pentru a atribui o înregistrare.runAs: stocarea cheie-valoare, conexiunile, canalele de mesagerie, runAgent, getPublicAssetUrl și taxarea creditelor. ai.generate urmează în schimb clienții impliciți: acționează ca persoana care a declanșat execuția, în cadrul rolului aplicației tale, sau ca aplicația ta atunci când nu a făcut-o nimeni.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 acesteia inline.
workflowActionTriggerSettings este modul în care
transformați acel cod inline, de unică folosință, într-o acțiune reutilizabilă: definiți funcția
o singură dată în aplicația dvs. ș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:Afișarea unui apel de instrument cu o componentă front.
În mod implicit, un apel de instrument apare în chatul AI ca un rând de pași: numele instrumentului și un indicator de încărcare până când acesta returnează un rezultat. ConfigurațitoolTriggerSettings.frontComponentUniversalIdentifier să indice către una dintre componentele front, iar chatul va afișa în schimb acea componentă în linie, pentru fiecare apel al acestui instrument.useToolCall():src/front-components/invoice-preview.tsx
toolCall.status trece prin input-available, stările de aprobare atunci când instrumentul are nevoie de aprobare, apoi prin output-available, output-denied sau output-error; input este ceea ce a propus agentul, iar output este ceea ce a returnat handlerul dvs. Afișați fiecare stare care vă interesează, deoarece rândul de pași nu mai este disponibil pentru a le acoperi.Atât input, cât și output sunt tipizate ca Record\<string, unknown>, așa că restrângeți tipul fiecărui câmp înainte de a-l utiliza, în loc să faceți conversii de tip. Acest lucru contează cel mai mult pentru orice transmiteți DOM-ului: o valoare pe care o introduceți într-un href fără să verificați că este un șir este un link controlat de rezultatul instrumentului.Dacă identificatorul nu corespunde niciunei componente frontale din aplicație, chatul revine
la rândul de pas implicit. Componentele frontale din chatul AI rulează sub același
rol pe care îl declară aplicația dvs., astfel încât un widget
poate doar să citească și să scrie ceea ce aplicația însăși are permisiunea să facă.
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 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-urile de instalare — handlerii de preinstalare, postinstalare și dezinstalare — partajează
acest runtime, dar sunt declarați cu propriile lor funcții define și nu acceptă
setări de declanșare. Consultați Hook-uri de
instalare pentru
definePreInstallLogicFunction, definePostInstallLogicFunction și
defineUninstallLogicFunction.Verificare de sănătate a aplicației.
Declară o verificare de sănătate cudefineHealthCheck pentru a raporta dacă aplicația ta poate rula efectiv. Este pentru lucruri pe care numai aplicația le poate ști: o cheie prezentă, dar revocată, un cont cu planul greșit, un webhook care nu a fost niciodată înregistrat. Ceea ce Twenty poate vedea singur — o variabilă obligatorie pe care nimeni nu a completat-o — este acoperit de isRequired și nu necesită cod.
Rulează pe partea de server, deci citește variabile secrete ca orice altă funcție logică. O verificare a spațiului de lucru nu are pe nimeni în spatele ei, deci handler-ul nu are nevoie de argumente.
src/logic-functions/health-check.ts
OK nu afișează deloc un banner; orice altă stare redă titlul într-un banner colorat în funcție de aceasta, așa că alege-o pe cea care corespunde măsurii în care persoana trebuie să acționeze. Stările sunt propriile ApplicationHealthStatus ale Twenty, astfel încât șirul simplu și membrul enum sunt interschimbabile:
/ sau #: una externă, relativă la protocol sau relativă își pierde butonul în loc să devină o redirecționare în altă parte. Butonul este, de asemenea, eliminat atunci când aplicația nu raportează nicio locație și nu are nicio filă de configurare la care să revină, astfel încât o verificare a unei aplicații fără variabile și fără elemente de meniu de setări îi afișează titlul fără un buton inactiv.
Verificarea configurației fiecărui membru
O aplicație declară o funcție de verificare a stării. OmitețirunOnUserPreferences sau setați-o la false pentru a rula o verificare a spațiului de lucru în pagina de setări a aplicației, cu un handler fără argumente. Setați runOnUserPreferences: true pentru a rula în schimb o verificare a membrului în pagina sa de preferințe Apps. Un handler de membru primește { userWorkspaceId: string } obligatoriu din sesiunea autentificată:
src/logic-functions/health-check.ts
{ userWorkspaceId } din sesiunea autentificată, iar variabilele cu domeniu de utilizator își păstrează valorile. Obiectul parametrului și ID-ul sunt obligatorii pentru acest mod. Nu rulează în setările aplicației pentru spațiul de lucru. Transmiteți userWorkspaceId la listConnections() pentru ca aceasta să returneze numai conexiunile acelui membru. O conexiune a cărei reîmprospătare a tokenului eșuează este omisă din listă, deci „nicio conexiune” acoperă și „reconectare”. Un buton fără location duce la fila General a aplicației din acea pagină.
Verificările membrilor necesită Twenty 2.55.0 sau o versiune ulterioară. Preferințele Apps nu sunt încă activate
în fiecare spațiu de lucru: acolo unde nu sunt, o verificare a membrului nu rulează niciodată.
Creați o activitate pe cronologie
UtilizațicreateTimelineActivity() pentru a publica un eveniment de domeniu explicit dintr-o funcție logică. Definiți mai întâi evenimentul ca tip de activitate pe cronologie, apoi faceți referire la tip și la obiecte prin identificatorii lor universali stabili:
timelineActivityTypeUniversalIdentifier, targetObjectUniversalIdentifier și targetRecordId. De asemenea, puteți furniza happensAt, properties și workspaceMemberId. happensAt controlează poziția și ora afișată a evenimentului pe cronologie; în mod implicit, este momentul creării.
Pentru a asocia o altă înregistrare cu evenimentul, furnizați împreună linkedRecordId și linkedObjectMetadataUniversalIdentifier. În plus, puteți furniza linkedRecordCachedName ca alternativă istorică pentru afișare:
timelineActivity. Păstrați tipurile explicite de evenimente nelegate de o action; un tip legat de o acțiune primește deja evenimente de audit automate și, în caz contrar, ar produce rânduri duplicate.
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 cu twenty app generate-client sau după o sincronizare cu twenty app apply ori twenty app dev, astfel încât este complet tipizat pentru a corespunde obiectelor și câmpurilor dvs.shareWith contează numai pentru un obiect ale cărui înregistrări sunt private; în rest, argumentul este ignorat. Pentru un astfel de obiect, acesta enumeră cine primește acces la înregistrarea creată: fiecare intrare vizează exact unul dintre workspaceMemberId, roleId sau everyone: true, cu un accessLevel de READ, READ_WRITE sau FULL. Un membru al spațiului de lucru care creează o înregistrare primește întotdeauna o acordare de proprietar FULL, astfel că argumentul este opțional pentru acesta; o funcție logică care acționează ca aplicația sa sau o cheie API primește, de asemenea, o acordare FULL pentru rolul său, iar astfel de apelanți, precum un apelant de sistem, trebuie să transmită shareWith, altfel crearea este respinsă. Fiecare intrare trebuie să indice un membru sau un rol al spațiului de lucru. O funcție logică sau o cheie API partajează prin intermediul rolului său, astfel încât fiecare deținător al acelui rol primește același acces la înregistrările pe care le creează; atribuiți unei chei ale cărei înregistrări trebuie să rămână private un rol propriu.Clientul folosește o sintaxă de tip selection-set: transmiteți 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.Rulați
twenty app generate-client pentru a reîmprospăta clientul din schema
GraphQL a spațiului de lucru. twenty app apply și twenty app dev îl regenerează, de asemenea,
după sincronizare. twenty app build doar compilează local și nu generează
clientul.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. Acceptă aceeași opțiune runAs ca CoreApiClient — consultați Ale cui accesări le utilizează un apel.Este, de asemenea, modul în care o aplicație citește și actualizează propriile variabile de aplicație, într-o funcție de logică, la fel ca într-o componentă front-end. Un token de aplicație ajunge doar la propria aplicație, în propriul spațiu de lucru.O variabilă de utilizator se află în process.env cu valoarea membrului care a declanșat execuția sau cu valoarea sa implicită până când acesta își setează propria valoare. O execuție pe care nu a declanșat-o nimeni nu primește variabile de utilizator. Pentru a citi valoarea variabilelor de utilizator ale aplicației dvs. pentru fiecare membru, de exemplu într-o sarcină cron, interogați myUserApplicationVariables cu runAs: 'application'.Încărcarea fișierelor
MetadataApiClient include o metodă uploadFile pentru atașarea fișierelor la câmpuri de tip fișier. Fișierul ajunge direct în stocarea de fișiere a Twenty: API-ul emite o destinație de încărcare, clientul trimite octeții acolo, apoi API-ul confirmă încărcarea.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ă. - Tipul MIME este detectat din conținutul fișierului după încărcare, deci nu există nimic de declarat.
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ă pentru accesul implicit: rolul unei persoane se intersectează cu cel al aplicației dvs. atunci când cineva se află în spatele execuției, iar rolul propriu al aplicației dvs. atunci când nu se află nimeni. Persoana este cea care a declanșat execuția într-o funcție logică sau cea care privește pagina într-o componentă front-end.TWENTY_APP_APPLICATION_ACCESS_TOKEN— Cheie cu durată scurtă, limitată numai la rolul propriu al aplicației dvs. Numai funcții logice, injectată întotdeauna acolo și utilizată derunAs: 'application'.
process.env, iar Ale cui accesări le utilizează un apel explică alegerea dintre ele. Permisiunile proprii ale aplicației dvs. sunt determinate de rolul declarat cu defineApplicationRole() (sau referențiat prin defaultRoleUniversalIdentifier în application-config.ts); o execuție care acționează ca o persoană nu poate depăși niciodată acel rol sau rolul persoanei.