Salt la conținutul principal

Prezentare generală

Fiecare aplicație trebuie să aibă exact un apel defineApplication. Acesta declară:
  • Identitate — identificator universal, nume de afișare, descriere.
  • Permisiuni — sub ce rol rulează funcțiile logice și componentele front-end ale acesteia.
  • Capabilități media (opțional): acces la microfon sau cameră solicitat de componentele front-end, aprobat separat de permisiunile de rol.
  • Variabile (opțional) — perechi cheie–valoare expuse codului dvs. ca variabile de mediu.
  • Hook-uri de pre-instalare / post-instalare / dezinstalare (opțional) — vedeți Funcții logice.
  • Facturare (opțional) — billing.recurring pentru taxele de abonament pe care platforma le percepe automat, billing.operations pentru operațiunile pentru care aplicația dvs. percepe credite și billing.description pentru marketplace; consultați Perceperea creditelor.
src/application-config.ts
Notițe:
  • Câmpurile universalIdentifier sunt UUID-uri pe care le generați o singură dată și pe care le dețineți. Mențineți-le stabile între sincronizări. Propriul universalIdentifier al aplicației trebuie să fie un UUID valid: serverul respinge un manifest al cărui identificator nu este un UUID valid. Este unic în întreaga instanță și este asociat spațiului de lucru care deține înregistrarea sa, astfel încât numai acel spațiu de lucru poate sincroniza aplicația — consultați Proprietatea înregistrării.
  • applicationVariables acceptă un label opțional — un nume ușor de înțeles pentru utilizator, afișat în pagina de setări a aplicației în locul cheii brute a variabilei.
  • applicationVariables devin variabile de mediu pentru funcțiile și componentele front-end. În funcțiile de logică (server-side), acestea sunt disponibile ca process.env.VARIABLE_NAME. În componentele front-end, folosește getApplicationVariable('VARIABLE_NAME') din twenty-sdk/front-component. Variabilele marcate cu isSecret: true sunt injectate doar în funcțiile de logică. Componentele front-end primesc doar variabile non-secrete. O variabilă cu scope: 'USER' păstrează valoarea membrului pentru care rulează codul: consultați Variabilele spațiului de lucru și ale utilizatorului.
  • Aplicația ta poate, de asemenea, să citească și să actualizeze propriile valori ale variabilelor în timpul rulării, astfel salvează o componentă personalizată de setări ceea ce a introdus utilizatorul: consultă Citirea și actualizarea variabilelor în timpul rulării. O aplicație accesează doar propriile variabile, în propriul spațiu de lucru.
  • Rolul implicit este detectat automat din fișierul de rol marcat cu defineApplicationRole() — nu este necesar să faci referire la el în defineApplication().
  • Funcțiile de pre-instalare, post-instalare și dezinstalare, precum și verificările de stare, sunt detectate automat în timpul construirii manifestului — nu este nevoie să faceți referire la ele în defineApplication().
  • Transmiterea explicită a defaultRoleUniversalIdentifier este în continuare acceptată pentru compatibilitate retroactivă, dar este considerată învechită în favoarea defineApplicationRole().
  • serverVariables sunt configurări și secrete la nivel de instanță (de ex. chei API). Spre deosebire de applicationVariables, ele nu declară nicio valoare în manifest — operatorul spațiului de lucru le completează din setările aplicației și sunt injectate în funcțiile de logică doar după ce au fost setate.
  • O aplicație își poate raporta propria stare de configurare cu defineHealthCheck(), pentru aspecte pe care numai aplicația le poate cunoaște — o cheie prezentă, dar revocată, un cont terț cu planul greșit. isRequired acoperă ceea ce Twenty poate vedea singur; verificarea stării de sănătate acoperă restul. Setați runOnUserPreferences: true pentru a verifica configurația proprie a fiecărui membru în pagina sa de preferințe pentru aplicații, în locul setărilor aplicației pentru spațiul de lucru. Omiterea opțiunii sau setarea acesteia la false păstrează verificarea existentă pentru spațiul de lucru.
  • Ambele tipuri de variabile acceptă isRequired: true. O variabilă obligatorie pe care spațiul de lucru nu a completat-o încă lasă aplicația neconfigurată: pagina sa de setări afișează un banner care indică variabilele lipsă, cu un buton care duce la fila în care acestea sunt configurate. Marcați ca obligatoriu doar ceea ce aplicația chiar nu poate rula fără — o variabilă opțională cu o valoare implicită rezonabilă ar trebui să rămână opțională.
  • Ambele tipuri de variabile acceptă isDeprecated: true. Folosește-l pentru a retrage o variabilă în loc să o ștergi: păstrarea cheii declarate conservă valoarea stocată (ștergerea ei distruge valoarea introdusă de operator), iar variabila este în continuare injectată, astfel încât codul tău poate reveni la ea — process.env.NEW_API_KEY ?? process.env.API_KEY. O variabilă învechită dispare din setările aplicației odată ce nu mai are nicio valoare și nu este niciodată luată în calcul la verificarea configurației aplicației, astfel încât isDeprecated are prioritate față de isRequired.
  • Twenty setează aceste nume pentru fiecare rulare a funcției logice, așadar sunt rezervate: TWENTY_API_URL, TWENTY_APP_ACCESS_TOKEN, TWENTY_APP_APPLICATION_ACCESS_TOKEN, TWENTY_API_KEY, TWENTY_FUNCTIONS_URL, TWENTY_SERVER_ROUTES_URL și APPLICATION_ID. Toate celelalte nume care încep cu TWENTY_ sunt, de asemenea, rezervate, pentru variabilele pe care Twenty le adaugă ulterior. Un manifest care declară un nume rezervat ca variabilă de aplicație sau de server este respins atunci când aplicația este sincronizată sau publicată.
  • Pentru a adăuga propriile intrări în meniul de setări al aplicației (în locul paginii generate Variables), declară o componentă front și direcționează un defineSettingsMenuItem() către aceasta, într-un fișier separat. Declară oricâte ai nevoie și ordonează-le cu position; scope plasează un element în setările spațiului de lucru sau în setările proprii ale fiecărui membru. Elementul General gestionat de sistem (actualizare automată, URL-ul aplicației, conexiuni) este întotdeauna primul, iar URL-ul aplicației se afișează numai când aplicația are funcții declanșate prin HTTP.

Capabilități media solicitate

Setați requestedCapabilities când o componentă front-end utilizează navigator.mediaDevices.getUserMedia(). Matricea opțională acceptă 'microphone', 'camera' sau ambele. Omiteți-o sau utilizați o matrice goală când aplicația nu are nevoie de captură media.
Capabilitățile declarate apar în timpul instalării. Aprobarea necesită un membru al spațiului de lucru care poate gestiona aplicații și se aplică întregului spațiu de lucru. Aceste acordări sunt separate de permisiunile de rol ale aplicației și nu înlocuiesc permisiunile browserului sau ale sistemului de operare. O aplicație instalată fără acordarea necesară întrerupe captura și afișează un dialog de aprobare la prima utilizare, inclusiv aplicațiile mai vechi fără declarații de capabilități. Refuzul menține captura blocată înainte de solicitarea permisiunilor browserului. Actualizările pachetului nu acordă automat acces suplimentar. Aplicațiile de dezvoltare sincronizate local primesc capabilitățile declarate în manifestul lor. Consultați Captură media pentru comportamentul capturii și indicatorii de înregistrare.

Acces la conținut media pentru site-uri web încorporate

Setați requestedIframeMediaPermissions atunci când o componentă frontală sau un widget de dispunere a paginii IFRAME încorporează un site web care necesită microfonul sau camera, cum ar fi un instrument de telefonie sau video. Listați până la 20 de site-uri web, fiecare ca origine HTTPS exactă, cu accesul la microfon și cameră setat separat. Originile trebuie să fie unice, să nu conțină nicio cale sau caracter wildcard și să solicite acces la cel puțin unul dintre microfon sau cameră.
Site-urile web declarate apar în timpul instalării. Aprobarea necesită un membru al spațiului de lucru care poate gestiona aplicații și se aplică întregului spațiu de lucru, pentru propriile componente frontale și widgeturi iframe ale aplicației. Aprobările de securitate ale spațiului de lucru se aplică numai widgeturilor create în spațiul de lucru. Aplicațiile de dezvoltare sincronizate local primesc site-urile web declarate în manifestul lor. Aceste permisiuni acordate nu înlocuiesc permisiunile browserului sau ale sistemului de operare. Antetele browserului au o limită de dimensiune, astfel încât, dacă site-urile web ale unui spațiu de lucru o depășesc, site-urile web aprobate pentru spațiul de lucru au prioritate, iar site-urile web rămase nu primesc acces la conținut media. Actualizările aplicațiilor publicate păstrează permisiunile existente și nu acordă automat acces suplimentar la conținut media. Pentru a aproba solicitări noi, un membru care poate gestiona aplicații deschide fila Generale a aplicației instalate și selectează Revizuiește accesul la conținut media sub Acces la conținut media pentru site-uri web încorporate. Această aprobare utilizează o confirmare nativă a browserului care afișează aplicația, originile site-urilor web și accesul solicitat la microfon sau cameră. După aprobare, reîncărcați filele Twenty deschise pentru a aplica permisiunile actualizate. Consultați Site-uri web încorporate cu acces la conținut media pentru cerințele iframe.

Tipuri de variabile

Atât applicationVariables, cât și serverVariables acceptă un câmp opțional type (și, pentru SELECT / MULTI_SELECT, o listă options). Tipuri acceptate: TEXT (implicit), BOOLEAN, NUMBER, NUMERIC, DATE, DATE_TIME, SELECT, MULTI_SELECT, ARRAY, RAW_JSON, RICH_TEXT.
src/application-config.ts
Proprietatea type afectează doar prezentarea și validarea — selectează câmpul de intrare corespunzător în interfața de setări a spațiului de lucru (un comutator, câmp numeric, listă derulantă, selector de dată, editor JSON, …) și permite build‑ului să valideze configurația (de exemplu, SELECT / MULTI_SELECT trebuie să declare o listă options negoală). Nu modifică deloc modul în care valoarea ajunge în codul tău. Valorile sunt întotdeauna injectate ca stringuri — acest lucru este inerent pentru variabilele de mediu (process.env.* este doar string). Când rulează funcția ta de logică, executorul serializează fiecare valoare în funcție de type‑ul declarat în timp ce construiește process.env, astfel încât formatul stringului este consecvent indiferent de modul în care a fost setată valoarea (valoare implicită din manifest, interfața de setări sau o versiune anterioară): Parsează stringul înapoi în tipul pe care îl aștepți:
Același lucru se aplică și componentelor de interfață care citesc valori prin getApplicationVariable('VARIABLE_NAME') — valoarea returnată este un string; parseaz-o după cum este necesar.

Variabilele spațiului de lucru și ale utilizatorului

Fiecare variabilă a aplicației are un scope:
  • WORKSPACE (implicit): o valoare pentru întregul spațiu de lucru, setată de un membru care poate gestiona aplicații.
  • USER: fiecare membru își păstrează propria valoare.
src/application-config.ts
value al unei variabile de utilizator este valoarea sa implicită: un membru care nu și-a setat propria valoare o citește, iar o versiune nouă a aplicației dvs. o poate modifica. O variabilă secretă nu poate avea o valoare implicită. Fără una, un membru care nu și-a setat propria valoare citește un șir gol, astfel încât aplicația dvs. decide ce înseamnă o valoare nesetată. Un administrator al spațiului de lucru nu poate seta o valoare pentru o variabilă de utilizator: valorile acesteia aparțin fiecărui membru. Domeniul de aplicare al unei variabile este setat când aceasta este creată și nu poate fi modificat. Pentru a o modifica, declarați variabila cu un nou universalIdentifier: sincronizarea șterge variabila veche, împreună cu valorile membrilor săi, și o creează pe cea nouă. Variabilele de utilizator pot fi isSecret, isRequired sau ambele. De exemplu, o cheie API personală poate declara scope: 'USER', isSecret: true, isRequired: true. Valorile sunt criptate în repaus. Pentru variabilele de utilizator, isRequired descrie o cerință per membru. Un membru care nu are nicio valoare pentru aceasta, proprie sau implicită, vede aplicația dvs. marcată Configurație lipsă în preferințele Aplicații, cu un banner care menționează variabilele. Nu afectează avertismentul privind configurarea spațiului de lucru și nimic nu impune acest lucru la rulare: codul tău decide în continuare ce înseamnă o valoare nesetată. O variabilă de utilizator este injectată cu valoarea membrului pentru care rulează codul dvs. sau cu valoarea sa implicită până când acesta își setează propria valoare:
  • Într-o funcție logică, process.env păstrează valorile membrului care a declanșat rularea, același membru ca cel pentru care acționează TWENTY_APP_ACCESS_TOKEN. O rulare fără nicio persoană în spatele ei, cum ar fi o sarcină cron sau un hook de instalare, nu primește deloc variabile de utilizator.
  • Într-o componentă front-end, getApplicationVariable returnează valorile membrului care o vizualizează. Variabilele secrete ale utilizatorului sunt omise, la fel ca variabilele secrete ale spațiului de lucru.
Membrul care a declanșat o rulare nu este întotdeauna membrul despre care este vorba: un eveniment de bază de date rulează ca persoana care a editat înregistrarea. Când o rulare este despre altcineva sau despre fiecare membru, citiți valorile cu myUserApplicationVariables prin MetadataApiClient. Listează fiecare membru împreună cu valorile variabilelor de utilizator ale aplicației dvs. și funcționează în fiecare rulare de funcție logică, inclusiv în sarcini cron și webhook-uri. Fiecare intrare conține userWorkspaceId, workspaceMemberId și variables ale membrului: declarația fiecărei variabile de utilizator (label, description, type, options, isSecret, isRequired, isDeprecated) și valoarea membrului sau valoarea implicită până când acesta își setează propria valoare. Interogați-o ca aplicație pentru a obține valori reale: cu un token care are o persoană în spatele lui, returnează doar intrarea acelei persoane, cu secretele mascate.
Valorile sunt șiruri, în același format ca process.env (consultați Tipuri de variabile). updateMyUserApplicationVariable salvează propria valoare a unui membru. Preia applicationUniversalIdentifier al aplicației tale și scrie valoarea persoanei din spatele tokenului: sesiunea proprie a membrului sau tokenul aplicației tale atunci când un membru se află în spatele acestuia, cum ar fi într-o componentă frontend sau într-o funcție logică executată pentru un membru. Tokenul aplicației dvs. poate indica doar propria aplicație, iar un token fără nicio persoană asociată, cum ar fi într-o sarcină cron sau într-un hook de instalare, este refuzat. O valoare goală elimină valoarea proprie a membrului, astfel încât acesta citește din nou valoarea implicită sau un șir gol pentru o variabilă fără valoare implicită. Nu necesită permisiunea Workspace Apps, dar necesită User Apps: în rolul membrului și, atunci când tokenul aplicației tale efectuează apelul, și în rolul implicit al aplicației tale, dacă aceasta declară unul. Dacă aplicația ta salvează variabile ale utilizatorului, adaugă SystemPermissionFlag.USER_APPS la permissionFlagUniversalIdentifiers din rolul.

Rol implicit pentru funcții

Rolul declarat cu defineApplicationRole() controlează la ce pot avea acces funcțiile logice și componentele de interfață ale aplicației:
  • Tokenurile de runtime injectate în funcțiile dvs. de logică sunt derivate din acest rol. Un apel care acționează ca o persoană este restrâns suplimentar la ceea ce poate face acea persoană, astfel încât nu poate depăși niciodată niciuna dintre cele două limite. Consultați Ce acces utilizează un apel.
  • Clientul API tipizat este restricționat la permisiunile acordate acelui rol.
  • Respectați principiul celui mai mic privilegiu: declarați doar permisiunile de care au nevoie funcțiile.
Când generați o aplicație nouă, CLI creează un fișier de rol de pornire la src/roles/default-role.ts. Consultați Roluri și permisiuni pentru referința completă.

Metadate pentru marketplace

Dacă intenționați să publicați aplicația, aceste câmpuri opționale controlează modul în care apare în marketplace:
logoUrl și screenshots sunt aliasuri învechite pentru logo și galleryImages. URL-urile absolute externe (http:// sau https://) nu sunt acceptate pentru aceste câmpuri: ele sunt eliminate cu un avertisment în timpul build-ului. În schimb, include imaginile în folderul public/ al aplicației tale.