snapshot of https://github.com/twentyhq/twenty.git (main, 2026-09-17; blobs > 131072B omitted)
Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 2s

This commit is contained in:
upstream-mirror
2026-09-17 23:28:13 +05:00
commit e7da97194a
32688 changed files with 4208681 additions and 0 deletions

View File

@@ -0,0 +1,167 @@
---
title: Trimiterea e-mailurilor prin fluxuri de lucru
description: Trimiteți automat e-mailuri personalizate folosind acțiunile fluxurilor de lucru.
---
Trimiteți automat e-mailuri atunci când au loc evenimente specifice în CRM—întâmpinați noile contacte, urmăriți oportunitățile sau notificați membrii echipei.
## Cerințe
Înainte de a putea trimite e-mailuri din fluxuri de lucru:
1. Conectați un cont de e-mail în **Settings → Accounts**
2. Asigurați-vă că contul are activate permisiunile de trimitere
## Flux de lucru de bază pentru e-mail
### Exemplu: E-mail de bun venit pentru contacte noi
**Obiectiv**: Trimiteți un e-mail de bun venit atunci când o persoană nouă este adăugată în CRM.
**Configurare**:
1. **Creați fluxul de lucru**: Accesați **Settings → Workflows** și faceți clic pe **+ New Workflow**
2. **Adăugați declanșator**: Selectați **Record is Created** → **People**
3. **Adăugați acțiunea Send Email**:
* Faceți clic pe **+** pentru a adăuga o acțiune
* Selectați **Send Email**
* Configurați e-mailul:
| Câmp | Valoare |
| ----------- | -------------------------------------- |
| **Către** | `{{trigger.object.email}}` |
| **Subiect** | `Bun venit la {{Your Company Name}}` |
| **Corp** | `Hi {{trigger.object.firstName}}, ...` |
4. **Testați și activați**: Testați cu o înregistrare de probă, apoi activați
## Utilizarea variabilelor în e-mailuri
Faceți referire la date din pașii anteriori folosind sintaxa `{{variable}}`:
```text
Hi {{trigger.object.firstName}},
Thank you for connecting with us!
Your company, {{trigger.object.company.name}}, is now in our system.
Best regards,
The Team
```
### Variabile disponibile din declanșatoare
| Tipul Trigger-ului | Variabile comune |
| ----------------------------------- | -------------------------------------- |
| **Înregistrare creată/actualizată** | `{{trigger.object.fieldName}}` |
| **Manual** | `{{trigger.selectedRecord.fieldName}}` |
| **Webhook** | `{{trigger.body.fieldName}}` |
## Avansat: e-mailuri condiționale
### Exemplu: E-mailuri diferite în funcție de sursa lead-ului
**Obiectiv**: Trimiteți e-mailuri de bun venit diferite în funcție de sursa lead-ului.
**Configurare**:
1. **Declanșator**: Record is Created (People)
2. **Adăugați acțiunea de filtrare**:
* Condiție: `{{trigger.object.source}}` este egal cu `"Website"`
* Dacă este adevărat → continuați către e-mailul de bun venit pentru website
3. **Ramificație pentru alte surse**:
* Creați ramificații paralele pentru surse diferite
* Fiecare ramificație are propria acțiune Send Email
## Trimiterea e-mailurilor către mai mulți destinatari
### Exemplu: Notificați echipa când se finalizează tranzacția
**Obiectiv**: Trimiteți un e-mail reprezentantului de vânzări și managerului său atunci când o oportunitate este câștigată.
**Configurare**:
1. **Declanșator**: Record is Updated (Opportunities, Stage = "Closed Won")
2. **Search Records**: Găsiți managerul proprietarului oportunității
3. **Send Email #1**: Către proprietarul oportunității
* Către: `{{trigger.object.owner.email}}`
* Subiect: `Felicitări pentru închiderea {{trigger.object.name}}!`
4. **Send Email #2**: Către manager
* Către: `{{searchRecords.manager.email}}`
* Subiect: `Tranzacție câștigată: {{trigger.object.name}}`
## E-mailuri de urmărire programate
### Exemplu: Urmărire la 3 zile după întâlnire
**Obiectiv**: Trimiteți un e-mail de urmărire la 3 zile după ce o întâlnire este înregistrată.
**Configurare**:
1. **Declanșator**: Record is Created (Activities, Type = "Meeting")
2. **Acțiune de întârziere**: Așteptați 3 zile
3. **Trimite email**:
* Către: Participantul la întâlnire
* Subiect: Revenire la discuția noastră
* Conținut: Faceți referire la detaliile întâlnirii din declanșator
## Atașamente pentru e-mailuri
Puteți atașa fișiere la e-mailurile trimise din fluxuri de lucru. Atașamentul este un fișier static pe care îl încărcați atunci când configurați fluxul de lucru.
### Cum să adăugați un atașament
1. În acțiunea **Trimite e-mail**, faceți clic pe butonul **Atașamente**
2. Faceți clic pentru a încărca un fișier de pe computerul dvs.
3. Fișierul va fi atașat tuturor e-mailurilor trimise de această acțiune
### Cazuri de Utilizare Comune
| Caz de utilizare | Exemplu de fișier |
| ------------------------------------- | --------------------------------------- |
| **E-mailuri de bun venit** | Broșura companiei (PDF) |
| **Secvențe de introducere** | Ghid de inițiere |
| **Mesaje de urmărire pentru vânzări** | Catalog de produse sau listă de prețuri |
| **Confirmări pentru evenimente** | Detalii despre eveniment sau agendă |
<Note>
Atașamentele sunt statice — același fișier este trimis tuturor destinatarilor. Pentru documente dinamice (cum ar fi ofertele personalizate), generați și atașați fișiere folosind o [Funcție logică](/l/ro/user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty).
</Note>
## Cele mai bune practici
### Conținutul emailului
* Păstrați liniile de subiect concise și relevante
* Personalizați cu numele destinatarului
* Includeți un apel clar la acțiune
* Testați emailurile înainte de activare
### Livrabilitate
* Nu trimiteți prea multe emailuri prea repede
* Folosiți semnături de email profesionale
* Evitați cuvintele care declanșează filtrele de spam
* Asigurați opțiuni de dezabonare pentru emailurile de marketing
### Depanare
* Verificați că contul de email este conectat și activ
* Verificați că adresa de email a destinatarului este validă
* Revizuiți rulările fluxului de lucru pentru mesaje de eroare
* Testați mai întâi cu propria dvs. adresă de email
## Conexe
* [Declanșatoare ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-triggers)
* [Acțiuni ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-actions)

View File

@@ -0,0 +1,88 @@
---
title: Utilizați ramuri în fluxuri de lucru
description: Înțelegeți cum funcționează ramurile și cum să controlați care cale este executată.
---
## Cum funcționează ramurile
În editorul de fluxuri de lucru, puteți crea mai multe căi (ramuri) care pornesc dintr-un singur nod. Acest lucru vă permite să creați automatizări complexe cu rezultate diferite.
**Important**: Când rulează un flux de lucru, **toate ramurile se execută în paralel în mod implicit**. Nu există o logică "if/else" integrată pentru a alege o ramură în locul alteia — fiecare cale va rula simultan.
## Controlul ramurii care se execută
Pentru a executa doar o singură ramură pe baza unor condiții specifice, **adăugați un nod Filter la începutul fiecărei ramuri**.
### Exemplu de configurare
1. Creați fluxul de lucru cu mai multe ramuri dintr-un singur nod
2. Adăugați un nod **Filter** ca primul pas în fiecare ramură
3. Setați condiții în fiecare nod Filter pentru a determina când ar trebui să continue acea ramură
4. Vor continua doar ramurile pentru care condițiile din Filter sunt îndeplinite
### Cum funcționează nodurile Filter
* Dacă condiția din Filter este **îndeplinită**: Ramura își continuă execuția
* Dacă condiția din Filter **nu este îndeplinită**: Ramura se oprește la nodul Filter
Acest lucru creează, în mod eficient, o logică condițională în care rulează doar ramura potrivită, pe baza datelor dvs.
## Exemplu: Rutare după valoarea tranzacției
**Scenariu**: Când o tranzacție este închisă, trimiteți notificări diferite în funcție de valoarea tranzacției.
1. **Declanșator**: Opportunity updated (Stage = Closed Won)
2. **Ramura 1**: Filter pentru Amount > $10,000 → Trimiteți mesaj Slack către #big-deals
3. **Ramura 2**: Filter pentru Amount ≤ $10,000 → Trimiteți e-mail managerului de vânzări
Ambele ramuri pornesc, dar doar cea care corespunde sumei tranzacției va continua dincolo de propriul Filter.
## Crearea ramurilor
<Note>
Pentru a crea o ramură nouă dintr-un pas existent, faceți clic pe butonul **+** al acelui pas și adăugați acțiunea. Puteți adăuga mai multe ramuri făcând clic pe **+** de mai multe ori.
</Note>
1. În editorul de fluxuri de lucru, selectați pasul din care doriți să creați o ramură
2. Faceți clic pe butonul **+** pentru a adăuga o acțiune
3. Aceasta creează o ramură
4. Faceți clic din nou pe **+** la același pas pentru a crea ramuri suplimentare
5. Fiecare ramură poate avea propria secvență de acțiuni
## Îmbinarea ramurilor la loc
După ce ramurile paralele își finalizează activitatea, le puteți îmbina la loc într-o singură cale:
1. Finalizați acțiunile din ramuri
2. Adăugați un pas nou care ar trebui să ruleze după toate ramurile
3. Trageți o conexiune de la ultimul pas al fiecărei ramuri către acest pas nou
4. Pasul îmbinat așteaptă ca toate ramurile conectate să se finalizeze înainte de a se executa
### Exemplu: Procesare, apoi notificare
```
Trigger
│
├── Branch A: Update Customer Record
│
└── Branch B: Create Support Ticket
↘ ↙
Merged Step: Send Confirmation Email
```
E-mailul de confirmare este trimis numai după ce atât actualizarea clientului, cât și crearea tichetelor au fost făcute.
## Cele mai bune practici
* Folosiți întotdeauna **noduri Filter** la începutul ramurilor atunci când doriți execuție condițională
* Mențineți condițiile ramurilor **reciproc exclusive** pentru a evita acțiunile duplicate
* Testați fluxurile de lucru cu date diferite pentru a vă asigura că rulează ramurile corecte
* **Redenumiți pașii ramurilor** într-un mod descriptiv pentru a fi clar ce face fiecare cale
* **Îmbinați ramurile** când aveți nevoie de o acțiune finală după procesare în paralel
## Conexe
* [Întrebări frecvente despre fluxuri de lucru](/l/ro/user-guide/workflows/how-tos/need-more-help/workflows-faq) — răspunsuri despre execuția în paralel
* [Acțiuni ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-actions) — acțiuni disponibile pentru ramuri

View File

@@ -0,0 +1,183 @@
---
title: Utilizați Iterator
description: Parcurgeți array-uri de înregistrări pentru a executa acțiuni asupra fiecărui element.
---
Iterator vă permite să parcurgeți un array de înregistrări și să efectuați acțiuni pe fiecare în parte. Este esențial pentru fluxuri de lucru care trebuie să proceseze mai multe înregistrări returnate de Search Records sau primite prin webhook-uri.
## Când să folosiți Iterator
| Scenariu | Exemplu |
| ------------------------------------- | ------------------------------------------------------ |
| **Procesați rezultatele căutării** | Trimiteți e-mail fiecărei persoane găsite |
| **Gestionați array-urile de webhook** | Creați înregistrări pentru fiecare element, în ordine |
| **Actualizări în masă** | Actualizați mai multe înregistrări cu valori calculate |
| **Notificări** | Alertați mai multe persoane despre un eveniment |
## Înțelegerea Iteratorului
Iterator așteaptă un **array** ca intrare. Apoi:
1. Preia primul element din array
2. Rulează toate acțiunile din interiorul Iteratorului cu acel element
3. Trece la următorul element
4. Repetă până când toate elementele sunt procesate
### Selectarea tabloului peste care să se itereze
Majoritatea surselor de tablouri (Search Records, un câmp de tablou dintr-un webhook, un declanșator manual Bulk) pot fi selectate direct în selectorul de variabile.
Când un pas de tip **Code** sau **Logic Function** returnează un *tablou de nivel superior*, rezultatul său apare în selectorul de variabile ca intrări indexate (`0`, `1`, `2`, …). Pentru a itera peste întregul tablou, selectează opțiunea **Whole list** pentru acel pas — Iteratorul deduce apoi automat structura fiecărui element din listă.
## Configurare de bază
### Exemplu: Trimiteți e-mail tuturor din rezultatele căutării
**Obiectiv**: Găsiți toate contactele dintr-o companie specifică și trimiteți fiecăruia un e-mail personalizat.
### Pasul 1: Căutați înregistrări
1. Adăugați acțiunea **Search Records**
2. Obiect: **Persoane**
3. Filtru: Compania este egală cu "Acme Inc"
4. Aceasta returnează un array de persoane
### Pasul 2: Verificați dacă există rezultate
1. Adăugați acțiunea **Filter**
2. Condiție: `{{searchRecords.length}}` este mai mare decât 0
3. Aceasta previne erorile Iteratorului când rezultatele sunt goale
### Pasul 3: Adăugați un Iterator
1. Adăugați acțiunea **Iterator**
2. Intrare pentru array: selectați `{{searchRecords}}`
3. Aceasta creează o buclă
### Pasul 4: Adăugați acțiuni în interiorul Iteratorului
Acțiunile plasate după Iterator rulează pentru fiecare element:
1. Adaugă **Trimitere E-mail** (înăuntrul Iteratorului)
2. Către: `{{iterator.currentItem.email}}`
3. Subiect: Salut `{{iterator.currentItem.firstName}}`!
4. Conținut: Mesaj personalizat folosind câmpurile elementului curent
### Rezultat
Dacă Search Records returnează 5 persoane, Iteratorul:
* Trimite e-mail persoanei 1
* Trimite e-mail persoanei 2
* ... continuă pentru toate cele 5
## Accesarea datelor elementului curent
În interiorul Iteratorului, folosiți `{{iterator.currentItem}}` pentru a accesa înregistrarea curentă:
| Variabilă | Descriere |
| --------------------------------------- | ------------------------------------------- |
| `{{iterator.currentItem}}` | Întregul obiect al înregistrării curente |
| `{{iterator.currentItem.id}}` | ID-ul înregistrării |
| `{{iterator.currentItem.email}}` | Câmp de e-mail |
| `{{iterator.currentItem.company.name}}` | Numele companiei asociate |
| `{{iterator.index}}` | Poziția curentă în array (indexare de la 0) |
În selectorul de variabile, poți fie să intri într-un câmp specific al elementului curent, fie să alegi **Use the whole item** pentru a face referire la întregul element curent (`{{iterator.currentItem}}`). Selectarea întregului element este utilă atunci când vrei să transmiți o înregistrare completă direct într-un pas ulterior, în loc să o reconstruiești câmp cu câmp.
## Tipare comune
### Actualizați mai multe înregistrări
**Obiectiv**: Marcați toate sarcinile întârziate ca "Late"
```
1. Search Records (Tasks, Due Date < Today, Status ≠ Completed)
2. Filter (length > 0)
3. Iterator (searchRecords)
└── Update Record
- Object: Tasks
- Record: {{iterator.currentItem.id}}
- Status: Late
```
### Creați înregistrări dintr-un array
**Obiectiv**: Webhook-ul primește o comandă cu mai multe articole, creați o înregistrare pentru fiecare
```
1. Webhook Trigger (receives items array)
2. Filter (items.length > 0)
3. Iterator (trigger.body.items)
└── Create Record
- Object: Order Items
- Name: {{iterator.currentItem.name}}
- Quantity: {{iterator.currentItem.qty}}
- Related Order: {{trigger.body.orderId}}
```
### Procesare condițională în interiorul buclei
**Obiectiv**: Trimiteți e-mail doar contactelor cu adrese valide
```
1. Search Records (People)
2. Iterator (searchRecords)
└── Filter (currentItem.email is not empty)
└── Send Email
- To: {{iterator.currentItem.email}}
```
## Depanare
### "Iterator expects an array"
**Cauză**: Ați transmis o singură înregistrare în loc de un array.
**Remediere**: Asigurați-vă că transmiteți rezultatul acțiunii Search Records sau un câmp de tip array, nu o singură înregistrare.
```
✅ Correct: {{searchRecords}}
❌ Wrong: {{searchRecords[0]}}
```
### Iteratorul nu rulează
**Cauză**: Array-ul este gol.
**Remediere**: Adăugați un Filter înainte de Iterator pentru a verifica lungimea array-ului:
```
Filter: {{searchRecords.length}} > 0
```
### Acțiunile rulează de prea multe ori
**Cauză**: Search Records a returnat mai multe înregistrări decât era de așteptat.
**Remediere**:
* Adăugați filtre mai specifice în Search Records
* Setați o limită în Search Records (maxim 200)
* Adăugați un Filter în interiorul Iteratorului pentru condiții suplimentare
## Considerații de performanță
* **Utilizarea creditelor**: Fiecare iterație consumă credite pentru acțiunile sale
* **Timp**: Array-urile mari necesită mai mult timp pentru a fi procesate
* **Limite**: Luați în considerare procesarea în loturi a operațiunilor foarte mari
* **Limite de rată**: Apelurile către API-uri externe pot atinge limitele de rată la multe iterații
## Cele mai bune practici
1. **Verificați întotdeauna lungimea array-ului** înainte de Iterator pentru a evita erorile
2. **Adăugați filtre în interiorul buclelor** când nu toate elementele trebuie procesate
3. **Redenumiți pasul Iterator** pentru a descrie prin ce iterează
4. **Testați cu array-uri mici** înainte de a procesa seturi mari de date
5. **Monitorizați rulările fluxurilor de lucru** pentru a vă asigura că iterațiile se finalizează conform așteptărilor
## Conexe
* [Acțiuni ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-actions)
* [Cum să utilizați ramurile](/l/ro/user-guide/workflows/capabilities/use-branches-in-workflows)
* [Întrebări frecvente despre fluxurile de lucru](/l/ro/user-guide/workflows/how-tos/need-more-help/workflows-faq)

View File

@@ -0,0 +1,332 @@
---
title: Acțiuni Workflow
description: Aflați despre acțiunile disponibile în fluxurile de lucru Twenty.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
## Despre acțiuni
Acțiunile definesc ce se întâmplă după declanșarea unui trigger. Puteți înlănțui mai multe acțiuni pentru a construi automatizări complexe.
<Tip>
* Folosiți selectorul de variabile (faceți clic pe pictograma `(x+)`) pentru a răsfoi datele disponibile din pașii anteriori
* Plasați cursorul peste orice câmp de intrare pentru a vedea din care pas provine o variabilă — util atunci când același câmp (de ex., ID) există în mai mulți pași anteriori
* Dați fiecărei acțiuni un nume descriptiv pentru o mentenanță mai ușoară
</Tip>
## Acțiuni asupra înregistrărilor
<img src="/images/user-guide/workflows/workflow_actions.png" style={{width:'100%'}} />
### Creează înregistrare
Adaugă o nouă înregistrare la un obiect selectat.
**Configurare**:
* Selectați obiectul țintă
* Completați câmpurile obligatorii și opționale
* Folosiți date din pașii anteriori sau introduceți manual valori pentru a completa câmpurile
**Output**: Datele noii înregistrări create sunt disponibile pentru utilizare în pașii următori.
### Actualizați Înregistrarea
Modifică o înregistrare existentă într-un obiect selectat.
<img src="/images/user-guide/workflows/update_record.png" style={{width:'100%'}} />
**Configurare**:
* Selectați obiectul țintă
* Alegeți înregistrarea specifică de actualizat.
* Puteți alege fie o înregistrare specifică, folosind meniul derulant care afișează toate înregistrările disponibile.
* Sau puteți selecta dinamic înregistrarea, desemnând o înregistrare găsită într-un pas anterior, folosind `(x+)`. Nu puteți căuta înregistrarea pe baza unor criterii diferite în această etapă. Dacă încă nu ați identificat înregistrarea, adăugați un pas `Search Record` înaintea acestui pas `Update Record`.
* Selectați câmpurile de modificat și introduceți valori noi
**Output**: Datele înregistrării actualizate sunt disponibile pentru utilizare în pașii următori.
### Ștergeți Înregistrarea
Îndepărtează o înregistrare dintr-un obiect selectat.
**Configurare**:
* Selectați obiectul țintă
* Alegeți înregistrarea specifică de șters
**Output**: Datele înregistrării șterse rămân disponibile pentru utilizare în pașii următori.
### Căutați Înregistrări
Găsește înregistrări într-un obiect selectat folosind condițiile de filtrare.
**Configurare**:
* Selectați obiectul de căutat
* Setați criterii de filtrare pentru a restrânge rezultatele
* Configurați ordonarea și limitele
**Output**: Returnează înregistrările care se potrivesc care pot fi utilizate în pașii următori.
<Note>
**Limită**: Search Records returnează maximum **200 de înregistrări**. Dacă aveți nevoie să procesați mai multe, adăugați filtre specifice pentru a reduce rezultatele sau folosiți fluxuri de lucru programate pentru a procesa în loturi.
</Note>
**Cea mai bună practică**: Utilizați [ramuri](/l/ro/user-guide/workflows/capabilities/workflow-branches) după Search Records pentru a gestiona scenariile "găsit" vs "ne-găsit".
### Upsert Record
Creează o înregistrare nouă sau actualizează una existentă pe baza criteriilor de potrivire. Este util când nu sunteți sigur dacă o înregistrare există deja.
<img src="/images/user-guide/workflows/upsert_double_identifier.png" style={{width:'100%'}} />
**Configurare**:
* Selectați obiectul țintă
* Rețineți ce câmpuri pot fi folosite pentru potrivire: email pentru Persoane, domeniu pentru Companii, ID pentru orice obiect sau orice câmp marcat ca Unique. Va trebui să completați cel puțin unul dintre acestea mai jos.
* Completați valorile câmpurilor. Nu uitați să completați cel puțin unul dintre identificatorii unici.
<Note>
**Potrivirea funcționează de obicei și mai bine când adăugați un singur identificator unic.** De exemplu, captura de ecran de mai jos va potrivi companiile pe baza domeniului lor. ID-ul nu este neapărat necesar.
</Note>
<img src="/images/user-guide/workflows/upsert_simple_identifier.png" style={{width:'100%'}} />
* Folosiți datele din pașii anteriori pentru a completa câmpurile
**Cum funcționează**:
1. Caută o înregistrare care corespunde condițiilor specificate
2. Dacă este găsită → actualizează înregistrarea existentă
3. Dacă nu este găsită → creează o înregistrare nouă
**Output**: Datele înregistrării create sau actualizate sunt disponibile pentru utilizare în pașii următori.
## Acțiuni de flux
### Iterator
**Parcurge un array de înregistrări** returnat de un pas anterior, permițându-vă să efectuați acțiuni pe fiecare înregistrare individual.
**Configurare**:
* Selectați array de înregistrări dintr-un pas anterior (de exemplu, rezultate din Căutare Records, dintr-un declanșator manual cu disponibilitate în grup, dintr-un nod Cod). Când un pas de tip Cod sau funcție logică returnează un array de nivel superior, selectează opțiunea **Whole list** pentru a itera peste întregul rezultat.
* Definiți acțiunile de efectuat pe fiecare înregistrare în buclă.
<Note>
- Puteți adăuga mai multe acțiuni în interiorul unui Iterator.
- Când folosești ramuri în interiorul unui Iterator, asigură-te că ultimul pas al fiecărei ramuri se conectează înapoi la Iterator pentru a închide bucla.
</Note>
* Accesați câmpurile `Current Item`: pentru a utiliza câmpuri din înregistrarea procesată în prezent, faceți clic pe pasul **Iterator**, apoi selectați **Current item**. Lista câmpurilor disponibile din acea înregistrare va fi afișată și poate fi selectată pentru utilizare în acțiunile ulterioare. Poți, de asemenea, să selectezi **Use the whole item** pentru a trimite întregul element curent într-un pas ulterior.
<VimeoEmbed videoId="1146577247" title="Demonstrație video" />
### Filtru
Filtrează înregistrările pe baza condițiilor specificate, permițând trecerea doar a înregistrărilor care îndeplinesc criteriile.
**Configurare**:
* Selectați înregistrarea de filtrat
* Definiți condițiile și criteriile de filtrare
* Configurați care înregistrări ar trebui să treacă la pașii următori
<Note>
1. **Output**: Nodurile Filter nu returnează date — acționează ca porți. Dacă condițiile sunt îndeplinite, fluxul de lucru continuă. Dacă nu, fluxul de lucru se oprește pe acea ramură.
2. Operatorul `IS` poate fi utilizat cu câmpuri numerice. Se comportă ca un `EQUAL`.
</Note>
### Întârziere
Pauzează execuția fluxului de lucru pentru o durată specificată sau până la o anumită dată/oră.
**Tipuri de întârziere**:
| Tip | Descriere |
| ------------------- | -------------------------------------------------------------------- |
| **Durată** | Așteaptă o perioadă de timp specificată (zile, ore, minute, secunde) |
| **Dată programată** | Așteaptă până la o dată și o oră specifice |
**Configurare pentru durată**:
* Setați zile, ore, minute și/sau secunde
* Combinați mai multe unități (de ex., 2 zile și 4 ore)
**Configurare pentru dată programată**:
* Selectați o dată și o oră
* Poate face referire la un câmp de tip dată dintr-un pas anterior (de ex., un follow-up la 3 zile după o întâlnire)
**Cazuri de utilizare**:
* Așteaptă 24 de ore înainte de a trimite un email de follow-up
* Pauzează până la data de închidere a unei oportunități
* Programează acțiuni pentru programul de lucru
<Note>
Data programată nu poate fi în trecut. Dacă este utilizat un câmp de tip dată dintr-un pas anterior și data a trecut deja, fluxul de lucru va eșua.
</Note>
**Limitări și credite**:
* **Fără limită maximă de durată** — puteți seta întârzieri de minute, zile, săptămâni sau mai mult
* Se consumă **1 credit** la executarea nodului Delay, indiferent de durată
* **Nu se consumă credite** în timpul așteptării — o întârziere de 5 minute costă la fel ca o întârziere de 5 zile
## Acțiuni de comunicare
### Trimite email
Trimite un email din fluxul dumneavoastră de lucru. Este excelent pentru emailuri de grup bazate pe șabloane. Emailurile vor arăta ca cele pe care le trimiteți din căsuța de e-mail.
Nu este potrivit pentru newsletter-uri (care necesită formatare mai bogată) sau secvențe automate de e-mail.
**Cerințe prealabile**: Adăugați un cont de email în Settings → Accounts
**Configurare**:
* Selectați contul de email expeditor
<Note>
Puteți trimite emailuri doar din căsuțele poștale sincronizate cu propriul dvs. cont Twenty. Trimiterea din căsuțele poștale ale altor membri ai echipei (de ex., emailul proprietarului contului) este pe roadmap.
</Note>
Pentru toți pașii următori, puteți face referire la variabile din pașii anteriori pentru personalizare.
* Introduceți adresa de email a destinatarului.
<Note>
În acest moment este posibil un singur destinatar.
</Note>
* Setați linia de subiect.
* Compuneți corpul mesajului. Aveţi posibilitatea să formataţi link-uri, să creaţi liste numerotate, liste de puncte de liniuţă, şi să adăugaţi ataşamente.
<Note>
Adăugarea semnăturilor HTML nu este posibilă în acest moment.
</Note>
### Formular
Solicită un formular în timpul execuției fluxului de lucru pentru a colecta intrarea utilizatorului. Răspunsurile pot fi apoi folosite în pașii următori pentru a crea înregistrări, a trimite emailuri sau a executa orice altă acțiune pe baza datelor introduse.
<Warning>
**Formularele sunt concepute doar pentru declanșatoare manuale**. Pentru fluxurile de lucru cu alte declanșatoare (Înregistrare creată, actualizată, etc.), formularele sunt accesibile doar prin interfața de execuție a fluxului de lucru, ceea ce nu este experiența de utilizator așteptată. Un centru de notificare va fi lansat în 2026 pentru a sprijini în mod corespunzător formulare în fluxuri de lucru automate.
</Warning>
**Configurare**:
* Configurați câmpurile pe care utilizatorii vor fi solicitați să le completeze. Pentru fiecare câmp, alegeți
* un tip dintre text, număr, dată, o anumită înregistrare, un câmp select. Câmpurile din toate obiectele sunt disponibile pentru selecţie.
* o etichetă
* o valoare implicită la `Placeholder` (opțional)
* Editați titlul formularului
**Output**: Răspunsurile formularului sunt disponibile pentru utilizare în pașii următori.
**Exemplu**: Fluxul de lucru "Quick Lead" este disponibil implicit în toate locurile de lucru, disponibil oriunde în meniul de comandă `Cmd+K`.
**Cum să completați formularul**:
* Declanşaţi fluxul de lucru manual din Meniul de Comandă `Cmd+K`
* Completați formularul afișat în panoul lateral și faceți clic pe `Submit`.
<Note>
Câmpurile nu pot fi făcute obligatorii.
</Note>
<VimeoEmbed videoId="1147277989" title="Demonstrație video" />
## Acțiuni de integrare
### Cod
Rulați JavaScript personalizat în cadrul fluxului dumneavoastră de lucru.
În fundal, fiecare acțiune de cod este susținută de propria **funcție logică** — o funcție TypeScript pe server, care rulează pe platforma Twenty. Când adaugi o acțiune de cod, Twenty creează o funcție logică dedicată pentru acel pas și îi afișează editorul inline, astfel încât codul pe care îl scrii rămâne asociat cu workflow-ul.
**Configurare**:
* Accesați variabilele din pașii anteriori. Poți edita dinamic numele variabilelor.
<VimeoEmbed videoId="1147281795" title="Demonstrație video" />
* Scrieți cod JavaScript în editor
* Returnați variabilele pentru utilizare în pașii următori
* Testați codul direct în pas
<Note>
Dacă trebuie să utilizați chei API externe în codul dvs., trebuie să le introduceți direct în corpul funcției. Nu puteți configura cheile API în altă parte și să faceți referire la ele în funcția logică.
</Note>
<Tip>
**Lucrați cu array-uri?** Array-urile din sisteme externe sau din pași anteriori pot veni ca stringuri. Consultați [Cum să gestionați array-urile în acțiunile Code](/l/ro/user-guide/workflows/how-tos/advanced-configurations/handle-arrays-in-code-actions) pentru soluție.
</Tip>
<Tip>
Faceți clic pe pictograma pătrată din dreapta sus a editorului de cod pentru a-l afișa pe tot ecranul — util, deoarece lățimea implicită a editorului este limitată.
</Tip>
#### Reutilizarea unei funcții logice între workflow-uri
Acțiunea de cod inline este excelentă pentru logică ad-hoc, dar codul pe care îl conține aparține acelui singur pas. Când vrei să partajezi aceeași logică între mai multe workflow-uri — sau să o menții ca sursă versionată într-o aplicație — definește o **funcție logică reutilizabilă** în loc să copiezi și să lipești cod în fiecare acțiune de cod.
O funcție logică este definită o singură dată într-o aplicație (folosind `defineLogicFunction` din SDK) și expusă în constructorul de workflow prin adăugarea `workflowActionTriggerSettings`. După ce aplicația ta este instalată, acea funcție apare ca acțiune separată în constructorul de workflow, alături de acțiunile încorporate. Selectarea acesteia afișează câmpurile de intrare pe care le-ai declarat (cu selectoare de variabile, la fel ca alte acțiuni) și rulează codul tău partajat — fără a fi necesar JavaScript inline.
| | Acțiune de cod | Funcție logică reutilizabilă |
| ---------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------- |
| **Locul în care „trăiește” codul** | Editor inline, legat de un singur pas al workflow-ului | Definită într-o aplicație, versionată în sistemul de control al sursei |
| **Reutilizare** | Copiat și lipit pentru fiecare pas | Adăugată ca acțiune în orice workflow |
| **Intrări** | Variabile conectate în editor | Câmpuri afișate pe baza schemei de intrare declarate |
| **Cel mai potrivit pentru** | Logică rapidă, specifică workflow-ului | Logică partajată, folosită în mai multe workflow-uri |
Ambele rulează pe același runtime pentru funcții logice, astfel încât o acțiune de cod pe care ai prototipat-o inline poate fi ulterior promovată într-o funcție logică reutilizabilă cu modificări minime.
<Tip>
Pentru documentația destinată dezvoltatorilor privind definirea funcțiilor logice și expunerea lor în constructorul de workflow, consultă [Logic Functions](/l/ro/developers/extend/apps/logic/logic-functions) — în special secțiunea **Exposing a function as an AI tool or workflow action** și `workflowActionTriggerSettings`.
</Tip>
### Solicitare HTTP
Trimite o cerere la un API extern ca parte a fluxului dumneavoastră de lucru.
<img src="/images/user-guide/workflows/http_action.png" style={{width:'100%'}} />
**Configurare**:
* Introduceți URL-ul punctului final API. Puteți utiliza parametri din pașii anteriori.
* Selectați metoda HTTP (GET, POST, PUT, PATCH, DELETE)
* Adăugați anteturile și valorile necesare
* Oferiți un exemplu de răspuns pentru previzualizarea structurii
## Acțiuni AI
### Agent AI - În curând
Rulează un agent AI în cadrul fluxului dvs. de lucru pentru a efectua sarcini inteligente.
**Configurare**:
* **Agent**: Selectați un agent AI existent sau folosiți agentul implicit
* **Prompt**: Scrieți instrucțiunea pentru agentul AI
* Faceți referire la variabile din pașii anteriori în prompt
**Ce pot face agenții AI**:
* Analizează și rezumă date
* Clasifică sau categorizează înregistrări
* Generează conținut text
* Ia decizii pe baza datelor
* Interacționează cu datele CRM folosind instrumente
**Output**: Răspunsul agentului AI este disponibil pentru utilizare în pașii următori. Dacă agentul are o schemă de ieșire structurată, răspunsul va urma acel format.
<Note>
Acțiunile agentului AI consumă credite ale fluxului de lucru în funcție de modelul AI utilizat. Consultați [Credite pentru fluxuri de lucru](/l/ro/user-guide/workflows/capabilities/workflow-credits) pentru detalii.
</Note>
<Note>
Agenții AI respectă permisiunile bazate pe roluri. Puteți atribui roluri specifice agenților în **Settings → Members → Roles** pentru a controla la ce date pot avea acces. Consultați [Permisiuni](/l/ro/user-guide/permissions-access/capabilities/permissions) pentru detalii.
</Note>

View File

@@ -0,0 +1,66 @@
---
title: Sucursale de lucru
description: Creați căi paralele și logică condițională în fluxurile dvs. de lucru.
---
Ramificațiile vă permit să împărțiți fluxul de lucru în mai multe căi care pot rula simultan sau condițional, în funcție de datele dvs.
<img src="/images/user-guide/workflows/branches.png" style={{width:'100%'}} />
## Cum funcționează ramificațiile
Când creați mai multe conexiuni dintr-un singur nod, fiecare cale devine o ramificație. În mod implicit, **toate ramificațiile se execută în paralel**—nu se așteaptă una pe alta.
## Crearea ramificațiilor
### Adăugați o ramificație nouă
1. **Faceți clic dreapta pe pânza principală** a fluxului de lucru (nu pe un nod existent)
2. Faceți clic pe **Adăugați nod**
3. Alegeți tipul de nod pentru ramificația nouă
4. Trageți o săgeată din partea de jos a pasului anterior la partea de sus a acestei noi acțiuni
5. Repetați pentru a adăuga mai multe ramificații din același nod
<Note>
Fiecare ramificație este independentă. Adăugarea unei ramificații nu afectează celelalte căi existente din acel nod.
</Note>
### Machetă vizuală
Ramificațiile apar ca căi paralele în editorul de fluxuri de lucru. Puteți glisa noduri pentru a rearanja macheta vizuală fără a afecta execuția.
## Ramificații condiționale
Deoarece toate ramificațiile rulează în mod implicit, utilizați noduri **Filtru** pentru a controla care căi se execută de fapt:
| Ramificație | Condiție de filtrare | Acțiune |
| ----------- | -------------------- | --------------------------------- |
| A | Etapă = "Câștigat" | Trimiteți un e-mail de felicitări |
| B | Etapă = "Pierdut" | Creați o sarcină de urmărire |
| C | Etapă = "Negociere" | Notificați managerul |
1. Creați ramificații din declanșatorul sau acțiunea dvs.
2. Adăugați un nod **Filtru** ca prim pas al fiecărei ramificații
3. Configurați fiecare filtru cu condiții care se exclud reciproc
4. Adăugați acțiunile după fiecare filtru
Doar ramificațiile în care condiția filtrului este îndeplinită vor continua să se execute.
## Îmbinarea ramificațiilor
**Ramificațiile nu se îmbină automat.** Fiecare ramificație rulează independent până când se încheie. Aveți flexibilitate completă în modul în care gestionați acest lucru:
* **Opțiunea 1: Păstrați ramificațiile separate**
Fiecare ramificație gestionează independent propriile acțiuni de urmărire. Aceasta este cea mai simplă abordare atunci când ramificațiile nu trebuie să convergă.
* **Opțiunea 2: Îmbinați ramificațiile manual**
La crearea fluxului de lucru, puteți conecta manual mai multe ramificații la aceeași acțiune ulterioară. Pur și simplu trageți săgeți de la capătul fiecărei ramificații către un nod comun.
<Note>
Deși puteți utiliza un nod [Întârziere](/l/ro/user-guide/workflows/capabilities/workflow-actions#delay) pentru a întrerupe execuția, în prezent nu poate fi configurat să aștepte "până când se termină o altă ramificație".
</Note>
## Conexe
* [Cum să utilizați ramificațiile în fluxuri de lucru](/l/ro/user-guide/workflows/capabilities/use-branches-in-workflows) - Ghid pas cu pas
* [Acțiuni ale fluxului de lucru](/l/ro/user-guide/workflows/capabilities/workflow-actions) - Acțiuni disponibile, inclusiv Filtru

View File

@@ -0,0 +1,75 @@
---
title: Credite pentru fluxuri de lucru
description: Înțelegeți consumul și gestionarea creditelor pentru fluxurile de lucru.
---
Creditele fluxului de lucru stimulează automatizările dvs. în Twenty. Înțelegerea modului în care funcționează vă ajută să optimizați costurile și să gestionați eficient bugetul de automatizare.
## Alocarea creditelor
Creditele pentru fluxurile de lucru sunt alocate în funcție de ciclul de facturare, nu de nivelul planului:
| Ciclu de facturare | Credite |
| ------------------- | ------------------- |
| **Abonament lunar** | 5 credite pe lună |
| **Abonament anual** | 50 de credite pe an |
<Note>
5 credite lunare sunt generoase pentru automatizările standard. Majoritatea echipelor nu vor depăși această limită cu utilizarea tipică a fluxurilor de lucru. Credite suplimentare sunt necesare în principal pentru acțiuni Code avansate și pentru fluxuri de lucru bazate pe AI.
</Note>
## Cum funcționează consumul de credite
Creditele sunt consumate când fluxurile de lucru se execută, nu atunci când le creați. Fiecare acțiune a fluxului de lucru consumă credite în funcție de complexitatea sa:
### Consumul de credite în funcție de tipul de acțiune
* **Operațiuni interne de bază**: Consum foarte mic de credite
* Căutați Înregistrări
* Creează înregistrare
* Actualizați Înregistrarea
* Ștergeți Înregistrarea
* Acțiuni de formular
* **Operațiuni complexe**: Consum mai ridicat de credite
* Acțiuni de cod (execuție JavaScript)
* Solicitări HTTP către servicii externe
* **Funcționalități AI**: Consum mai ridicat de credite
* Acțiunile agentului AI consumă credite în funcție de modelul AI utilizat
* Prompturile mai complexe și rezultatele mai lungi utilizează mai multe credite
* **Acțiuni Delay**: Consum minim de credite
* Nodul Delay consumă **1 credit** la execuție
* **Nu se consumă credite** în perioada de așteptare
* O întârziere de 5 minute costă la fel ca o întârziere de 5 zile
### Deducere în timp real
Creditele sunt retrase în timp real pe măsură ce fluxurile de lucru se execută. Acest lucru înseamnă:
* Fluxurile de lucru în ciornă nu consumă credite
* Numai fluxurile de lucru active, rulate utilizează alocarea dvs. de credite
* Fluxurile de lucru eșuate consumă totuși credite pentru pașii finalizați
## Gestionarea creditelor
### Verificați utilizarea creditelor
1. Accesați **Setări → Facturare**
2. Vizualizați consumul dvs. actual de credite și soldul rămas
3. Monitorizați modelele de utilizare pentru a optimiza fluxurile de lucru
### Achiziționarea de credite suplimentare
Dacă aveți nevoie de mai multe credite decât alocarea planificată:
1. Accesați **Setări → Facturare**
2. Faceți clic pe opțiunea de a achiziționa credite suplimentare. Sunt disponibile pachete de diferite dimensiuni.
3. Creditele sunt adăugate la soldul dvs. actual
## Cele mai bune practici
* **Prelucrarea în lot**: Folosește operațiuni în vrac și acțiuni ale Iteratorului în mod eficient pentru a reduce apelurile individuale de acțiune
* **Optimizare pentru declanșatorul manual**: Pentru declanșatoarele manuale, alegeți disponibilitatea `Bulk` pentru a procesa mai multe înregistrări într-o singură rulare a fluxului de lucru
* Optimizați acțiunile de cod pentru eficiență

View File

@@ -0,0 +1,93 @@
---
title: Rulările fluxului de lucru
description: Monitorizați și gestionați execuțiile fluxurilor de lucru.
---
## Despre Rulări
O **rulare** este o înregistrare a execuției unui flux de lucru. De fiecare dată când un flux de lucru este declanșat—fie de un eveniment al unei înregistrări, de o planificare, o acțiune manuală sau un webhook—se creează o nouă rulare.
## Vizualizarea Rulărilor
### Din editorul de fluxuri de lucru
1. Deschideți fluxul de lucru pe care doriți să îl monitorizați
2. Faceți clic pe panoul **Rulări** din partea dreaptă
3. Vedeți o listă cu rulările recente și starea lor
### Din vizualizarea Rulări ale fluxurilor de lucru
1. Accesați **Rulări ale fluxurilor de lucru** în bara laterală
2. Vizualizați rulările din toate fluxurile de lucru
3. Filtrați după stare, flux de lucru sau dată
## Stările rulărilor
| Status | Descriere |
| ---------------- | -------------------------------------------------------------------------------------------------- |
| **Se execută** | Fluxul de lucru se execută în prezent |
| **Completat** | Fluxul de lucru s-a finalizat cu succes |
| **Eșuat** | Fluxul de lucru a întâmpinat o eroare și s-a oprit |
| **În așteptare** | Fluxul de lucru este în pauză (de ex., așteaptă o acțiune Întârziere sau trimiterea unui formular) |
## Detalii despre rulare
Faceți clic pe orice rulare pentru a vedea:
* **Stare**: Starea curentă a rulării
* **Pornită la**: Când a început rularea
* **Durată**: Cât a durat rularea
* **Date ale declanșatorului**: Datele de intrare care au pornit fluxul de lucru
* **Ieșirile pașilor**: Datele returnate de fiecare pas
* **Mesaje de eroare**: Dacă rularea a eșuat, ce a mers prost
## Execuție pas cu pas
Fiecare rulare afișează progresul în fluxul dvs. de lucru:
1. Vedeți care pași s-au finalizat cu succes
2. Identificați unde au apărut eșecurile
3. Vizualizați datele transmise între pași
4. Depanați problemele examinând intrările și ieșirile pașilor
## Gestionarea erorilor
Când o rulare eșuează:
1. Deschideți rularea eșuată
2. Găsiți pasul care a cauzat eșecul
3. Verificați mesajul de eroare pentru detalii
Probleme comune:
* Lipsesc câmpuri obligatorii
* Format de date invalid
* Erori ale API-urilor externe
* Probleme de permisiuni
## Rularea din nou a fluxurilor de lucru
Dacă o rulare eșuează, puteți:
* Remediați problema de bază și așteptați următorul declanșator
* Pentru fluxurile de lucru manuale, declanșați din nou cu aceleași date sau cu date actualizate
* Revizuiți logica fluxului de lucru pentru a preveni eșecuri viitoare
## Sfaturi privind performanța
### Gestionarea istoricului rulărilor
* Rulările sunt păstrate pentru referință istorică
* Rulările foarte vechi pot fi arhivate automat
* Exportați datele rulărilor dacă trebuie să păstrați înregistrări
### Cele mai bune practici de monitorizare
* Verificați regulat rulările după activarea unor fluxuri de lucru noi
* Analizați rulările eșuate pentru a identifica tipare
## Conexe
* [Declanșatoare ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-triggers)
* [Acțiuni ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-actions)
* [Depanarea fluxurilor de lucru](/l/ro/user-guide/workflows/how-tos/need-more-help/workflow-troubleshooting)

View File

@@ -0,0 +1,137 @@
---
title: Declanșatoare pentru fluxuri de lucru
description: Află mai multe despre diferiții declanșatori care îți încep fluxurile de lucru.
---
## Despre declanşatori
Fluxurile de lucru întotdeauna încep cu un declanșator unic care definește când ar trebui să ruleze automatizarea.
<img src="/images/user-guide/workflows/workflow_triggers.png" style={{width:'100%'}} />
<Tip>
**Obiectele avansate sunt acceptate!** Dincolo de obiectele standard CRM (People, Companii, Oportunități), puteți declanșa, de asemenea, fluxuri de lucru și efectua acțiuni pe:
* Membri ai spațiului de lucru
* Evenimente Calendar
* Mesaje (Emails)
* Sarcini, Note și multe alte obiecte de sistem
Acest lucru deschide automate puternice cum ar fi notificarea membrilor echipei atunci când evenimentele din calendar sunt create sau procesarea automată a e-mailurilor primite.
</Tip>
## Înregistrarea este creată
Pornește fluxul de lucru când este creată o nouă înregistrare într-un obiect selectat (Persoane, Companii, Oportunități sau orice obiect personalizat).
**Configurare**: Selectați tipul de obiect pentru a monitoriza noile înregistrări.
<Note>
* Acest declanșator este grozav pentru înregistrările create de CSV, cutia poștală și sincronizarea calendarului, sau API.
* **Nu este recomandat pentru înregistrările create manual**: cu acest declanșator, fluxurile de lucru încep imediat ce înregistrarea este creată. Deoarece 20 de UI oferă salvare automată în zbor (nu există nici un mod de editare și apoi o validare pentru a salva înregistrările), fluxul de lucru va fi declanșat înainte ca utilizatorul să introducă toate câmpurile.
Pentru a declanșa acest flux de lucru pe înregistrările create manual, este recomandat să utilizați declanșatorul `Record este creat sau actualizat`.
</Note>
## Înregistrarea este actualizată
Pornește fluxul de lucru când se fac modificări într-o înregistrare existentă.
**Configurare**:
* Selectați tipul de obiect
* Specificați opțional care câmpuri să fie monitorizate pentru modificări
## Înregistrarea este actualizată sau creată
Pornește fluxul de lucru când o înregistrare este fie creată, fie actualizată într-un obiect selectat.
**De ce contează acest lucru**: Acest declanșator este deosebit de util deoarece înregistrările create prin metode diferite se comportă diferit:
* **Importuri API/CSV**: Înregistrările sunt create cu toate câmpurile completate imediat
* **Creare manuală**: Înregistrările sunt create mai întâi, apoi câmpurile sunt adăugate în actualizări ulterioare
**Configurare**:
* Selectați tipul de obiect pentru a monitoriza
* Specificați opțional care câmpuri să fie monitorizate pentru modificări
* Fluxul de lucru va fi declanșat atât la crearea inițială, cât și la orice actualizări ulterioare
## Înregistrarea este ștearsă
Pornește fluxul de lucru când o înregistrare este eliminată dintr-un obiect.
**Configurare**: Selectați tipul de obiect pentru a monitoriza ștergerile.
## Declanșare manuală
Pornește fluxul de lucru când este declanșat de o acțiune a utilizatorului. Acest declanșator poate fi accesat prin meniul `Cmd+K` sau printr-un buton personalizat care va fi afișat în bara de navigare de sus după selectarea înregistrării(lor).
<img src="/images/user-guide/workflows/add_to_newsletter_button.png" style={{width:'100%'}} />
**Configurare disponibilitate**:
Alegeți cum ar trebui ca fluxul de lucru să gestioneze selecția înregistrărilor:
* **Global**: Nu se necesită nicio înregistrare pentru a declanșa acest flux de lucru. Fluxul de lucru este declanșat din meniul de comandă `Cmd+K` oriunde (de la orice obiect) și nu folosește înregistrarea (înregistrările) ca intrare.
Pentru disponibilitatea **Single** și **Bulk**, înregistrările selectate vor fi transmise la fluxul de lucru. Aceasta este configurată pentru un obiect dat, și mai multe înregistrări pot fi selectate înainte de a declanșa fluxul de lucru.
* **Single**: Fluxul de lucru va rula de la început la sfârșit de câte ori există înregistrări selectate.
<Note>
**Limita soft: 100 runs/minut**. Dincolo de aceasta, fluxurile de lucru rămân în starea „Nu s-a început” și sunt procesate treptat — fie de un job de fundal sau atunci când un alt flux de lucru intră în coadă. Asta înseamnă că poți selecta mai mult de 100 de înregistrări cu un singur declanșator; execuția va fi mai lentă.
</Note>
* **Bulk**: Fluxul de lucru va rula o dată, furnizând întreaga listă de înregistrări ca intrare. Aceasta înseamnă că fluxul de lucru trebuie să conțină o [acțiune Iterator](/l/ro/user-guide/workflows/capabilities/workflow-actions#iterator).
<Note>
Acest lucru este mai avansat, și cel mai bine pentru cei care doresc să optimizeze numărul de alergări de fluxuri de lucru.
</Note>
<img src="/images/user-guide/workflows/manual_trigger.png" style={{width:'100%'}} />
**Configurare suplimentară**:
* Selectați obiectul țintă (pentru modurile Single și Bulk)
* Alegeți o pictogramă de comandă pentru declanșarea fluxului de lucru
* Configurați plasarea în navbar (fixat sau nefixat)
**Metode de acces**:
* Meniul `Cmd+K` pentru a găsi și lansa fluxuri de lucru manuale
* Buton personalizat în navbarul superior (dacă este configurat)
## Declanșator temporal: Pe un program
Pornește fluxul de lucru în mod recurent, conform configurării pe care o definiți.
**Configurare**:
* Selectați unitatea de timp (minute, ore, zile)
* Introduceți o valoare sau folosiți expresii cron personalizate pentru programare avansată
<Note>
**Fus orar**: Fluxuri de lucru programate rulează în **UTC**. Când sunt stabilite ore pentru orarele zilnice, convertiți ora locală în UTC.
</Note>
## Declanșator extern: Webhook
Pornește fluxul de lucru când este primită o cerere GET sau POST de la un serviciu extern.
<img src="/images/user-guide/workflows/webhook_trigger.png" style={{width:'100%'}} />
**Configurare**:
* Fluxul de lucru oferă un URL webhook unic - copiați-l și adăugați-l în sistemul dvs. extern ca punct final pentru apelare.
* În ceea ce privește cererile POST, să se definească structura organică preconizată, astfel încât douăzeci să știe ce date să aștepte. Adăugați aici câmpurile pe care le veți primi care vor fi necesare mai jos în fluxul de lucru.
* Configurați autentificarea (în curând).
## Alegerea Declanșatorului din dreapta
| Utilizare Caz | Declanșator recomandat |
| ---------------------------------------- | ----------------------------------------- |
| Noi piste necesită procesare | Înregistrarea este creată |
| Schimbarea datelor necesită sincronizare | Înregistrarea este actualizată |
| Import/manipularea manuală a datelor | Înregistrarea este actualizată sau creată |
| Curățare după ștergere | Înregistrarea este ștearsă |
| Acțiune inițiată de utilizator | Lansare manuală |
| Rapoarte periodice | Conform unui program |
| Integrarea externă | Webhook sau pe o programare |

View File

@@ -0,0 +1,84 @@
---
title: Versiunile fluxului de lucru
description: Gestionați versiunile și schițele fluxului de lucru.
---
## Despre versiuni
De fiecare dată când activați un flux de lucru, se creează o versiune nouă. Acest lucru vă permite să urmăriți modificările în timp și să reveniți la configurațiile anterioare, dacă este necesar.
## Stările versiunilor
| Status | Descriere |
| -------------- | -------------------------------------------- |
| **Schiță** | În curs de editare, încă nepublicată |
| **Activ** | Versiunea live care răspunde la declanșatori |
| **Dezactivat** | Anterior activă, oprită manual |
| **Arhivat** | Versiuni anterioare păstrate pentru istoric |
## Lucrul cu schițele
Când editați un flux de lucru activ, modificările sunt salvate ca **schiță**. Versiunea activă continuă să ruleze în timp ce lucrați la actualizări.
După ce ați terminat editarea, puteți:
* **Activați**: Publicați schița ca noua versiune activă (versiunea anterioară este arhivată)
* **Renunțați**: Ștergeți schița și păstrați versiunea activă curentă
## Istoria versiunilor
### Vizualizarea versiunilor anterioare
1. Deschideți fluxul de lucru
2. Faceți clic pe fila **Versiuni**
3. Vedeți toate versiunile anterioare cu marcaje de timp
### Restaurarea unei versiuni
1. Găsiți versiunea pe care doriți să o restaurați
2. Faceți clic pe **Utilizează ca schiță**
3. Versiunea este copiată într-o nouă schiță
4. Efectuați actualizările necesare
5. Activați când sunteți gata
## Cele mai bune practici
### Gestionarea versiunilor
* Activați numai când este gata pentru producție
* Păstrați modificările semnificative între versiuni
* Documentați modificările majore în numele sau descrierile fluxurilor de lucru
* Testați în modul schiță înainte de a activa
### Anularea modificărilor
* Dacă o versiune nouă provoacă probleme, restaurați versiunea anterioară
* Utilizați istoricul versiunilor pentru a urmări ce s-a schimbat
* Testați întotdeauna versiunile restaurate înainte de activare
## Fluxuri de lucru comune
### Editare rapidă
1. Faceți modificări minore la un flux de lucru activ
2. Testați în modul schiță
3. Activați noua versiune
### Revizie majoră
1. Folosiți versiunea anterioară ca punct de pornire
2. Efectuați modificări semnificative în schiță
3. Testați temeinic toate scenariile
4. Activați când sunteți încrezători
### Revenire
1. Identificați problema versiunii curente
2. Găsiți în istoric ultima versiune funcțională
3. Faceți clic pe **Utilizează ca schiță**
4. Activați pentru a restabili comportamentul vechi
## Conexe
* [Noțiuni de bază despre fluxuri de lucru](/l/ro/user-guide/workflows/overview)
* [Execuții ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-runs)

View File

@@ -0,0 +1,82 @@
---
title: Gestionarea tablourilor în acțiunile de cod
description: Aflați cum să gestionați corect intrările de tip tablou în acțiunile de cod din fluxurile de lucru.
---
Când lucrați cu tablouri în acțiunile de cod, este posibil să întâmpinați două provocări frecvente:
1. **Tablouri transmise ca șiruri** — datele din sisteme externe sau din pașii anteriori sosesc ca un șir în loc de un tablou propriu-zis
2. **Nu puteți selecta elemente individuale** — puteți selecta doar întregul tablou, nu câmpuri specifice din interiorul lui
Ambele pot fi rezolvate cu un nod de cod.
## Analizarea tablourilor din șiruri
Tablourile sunt adesea transmise între pașii unui flux de lucru ca șiruri sau JSON, mai degrabă decât ca tablouri native. Acest lucru se întâmplă când:
* Primirea de date de la API-uri externe prin HTTP Request
* Procesarea payload-urilor de webhook
* Transmiterea datelor între pașii fluxului de lucru
**Soluție**: Adăugați acest tipar la începutul acțiunii dvs. de cod:
```javascript
export const main = async (params: {
users: any;
}): Promise<object> => {
const { users } = params;
// Handle input that may come as a string or an array
const usersFormatted = typeof users === "string" ? JSON.parse(users) : users;
// Now you can safely work with usersFormatted as an array
return {
users: usersFormatted.map((user) => ({
...user,
activityStatus: String(user.activityStatus).toUpperCase(),
})),
};
};
```
Linia esențială `typeof users === "string" ? JSON.parse(users) : users` verifică dacă intrarea este un șir, o parsează dacă este necesar sau o folosește direct dacă este deja un tablou.
## Extragerea câmpurilor individuale din tablouri
Un webhook poate returna un tablou de forma `answers: [...]`, dar în pașii următori ai fluxului de lucru puteți selecta doar **întregul tablou** — nu și elemente individuale din interiorul lui.
**Soluție**: Adăugați un nod de cod pentru a extrage câmpuri specifice și a le returna ca obiect structurat:
```javascript
export const main = async (params: {
answers: any;
}): Promise<object> => {
const { answers } = params;
// Handle input that may come as a string or an array
const answersFormatted = typeof answers === "string"
? JSON.parse(answers)
: answers;
// Extract specific fields from the array
const firstname = answersFormatted[0]?.text || "";
const name = answersFormatted[1]?.text || "";
return {
answer: {
firstname,
name
}
};
};
```
Nodul de cod returnează un obiect structurat în locul unui tablou. În pașii următori, acum puteți selecta câmpuri individuale precum `answer.firstname` și `answer.name` din selectorul de variabile.
<Tip>
**Vrei să iterezi peste array în loc să extragi câmpuri?** Când un pas Code sau Logic Function returnează un array de nivel superior, îl poți trimite direct într-un [Iterator](/l/ro/user-guide/workflows/capabilities/use-iterator): selectează opțiunea pasului **Whole list** ca intrare pentru Iterator, apoi fă referire la fiecare element cu `{{iterator.currentItem}}` în interiorul buclei. În acest caz nu este nevoie să restructurezi array-ul într-un obiect.
</Tip>
<Tip>
Faceți clic pe pictograma pătrată din dreapta sus a editorului de cod pentru a-l afișa pe tot ecranul — util, deoarece lățimea implicită a editorului este limitată.
</Tip>

View File

@@ -0,0 +1,182 @@
---
title: Importați datele despre produse în Twenty
description: Sincronizați datele catalogului de produse dintr-un depozit de date în CRM-ul dvs., conform unui program.
---
Folosiți acest model pentru a menține Twenty sincronizat cu datele despre produse din depozitul dvs. de date (de ex., Snowflake, BigQuery, PostgreSQL).
## Structura fluxului de lucru
1. **Declanșator**: Conform unui program
2. **Code**: Interogați depozitul de date
3. **Code** (opțional): Formatați datele ca tablou
4. **Iterator**: Parcurgeți fiecare produs
5. **Upsert Record**: Creați sau actualizați în Twenty
<img src="/images/user-guide/workflows/create_users_workflow.png" style={{width:'100%'}} />
## Pasul 1: Programați declanșatorul
Configurați fluxul de lucru să ruleze la o frecvență care corespunde nevoilor dvs. privind actualitatea datelor:
* La fiecare 5 minute pentru sincronizare aproape în timp real
* La fiecare oră pentru date mai puțin critice
* Zilnic pentru actualizări în lot
## Pasul 2: Interogați depozitul dvs. de date
Adăugați o acțiune **Code** pentru a prelua datele recente:
```javascript
export const main = async () => {
const intervalMinutes = 10; // Match your schedule frequency
const cutoffTime = new Date(Date.now() - intervalMinutes * 60 * 1000).toISOString();
// Replace with your actual data warehouse connection
const response = await fetch("https://your-warehouse-api.com/query", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
query: `
SELECT id, name, sku, price, stock_quantity, updated_at
FROM products
WHERE updated_at >= '${cutoffTime}'
`
})
});
const data = await response.json();
return { products: data.results };
};
```
<Tip>
Filtrați după `updated_at >= last X minutes` pentru a prelua doar înregistrările modificate recent. Acest lucru menține sincronizarea eficientă.
</Tip>
## Pasul 3: Formatați datele (opțional)
Dacă depozitul dvs. de date returnează date într-un format care necesită transformare, adăugați o altă acțiune **Code**. Transformările uzuale includ conversii de tip, redenumirea câmpurilor și curățarea datelor.
### Exemplu: Date despre utilizatori cu câmpuri booleene și de stare
```javascript
export const main = async (params: {
users: any;
}): Promise<object> => {
const { users } = params;
const usersFormatted = typeof users === "string" ? JSON.parse(users) : users;
// Convert string "true"/"false" to actual booleans
const toBool = (v: any) => v === true || v === "true";
return {
users: usersFormatted.map((user) => ({
...user,
activityStatus: String(user.activityStatus).toUpperCase(),
isActiveLast30d: toBool(user.isActiveLast30d),
isActiveLast7d: toBool(user.isActiveLast7d),
isActiveLast24h: toBool(user.isActiveLast24h),
isTwenty: toBool(user.isTwenty),
})),
};
};
```
### Exemplu: Date de produs cu conversii de tip
```javascript
export const main = async (params: { products: any }) => {
const products = typeof params.products === "string"
? JSON.parse(params.products)
: params.products;
return {
products: products.map(product => ({
externalId: product.id,
name: product.name,
sku: product.sku,
price: parseFloat(product.price), // String → Number
stockQuantity: parseInt(product.stock_quantity),
isActive: product.status === "active" // String → Boolean
}))
};
};
```
### Exemplu: Formatarea datelor calendaristice și a valorilor monetare
```javascript
export const main = async (params: { deals: any }) => {
const deals = typeof params.deals === "string"
? JSON.parse(params.deals)
: params.deals;
return {
deals: deals.map(deal => ({
...deal,
// Convert Unix timestamp to ISO date
closedAt: deal.closed_timestamp
? new Date(deal.closed_timestamp * 1000).toISOString()
: null,
// Ensure amount is a number (remove currency symbols)
amount: parseFloat(String(deal.amount).replace(/[^0-9.-]/g, "")),
// Normalize stage names
stage: deal.stage?.toLowerCase().replace(/_/g, " ")
}))
};
};
```
### Transformări uzuale
| Format sursă | Format țintă | Cod |
| -------------------- | ---------------- | ---------------------------------------- |
| `"true"` / `"false"` | `true` / `false` | `v === true \|\| v === "true"` |
| `"123.45"` | `123.45` | `parseFloat(value)` |
| `"active"` | `"ACTIVE"` | `value.toUpperCase()` |
| `1704067200` (Unix) | Dată ISO | `new Date(v * 1000).toISOString()` |
| `"$1,234.56"` | `1234.56` | `parseFloat(v.replace(/[^0-9.-]/g, ""))` |
| `null` / `undefined` | `""` | `value \|\| ""` |
## Pasul 4: Parcurgeți produsele
Adăugați o acțiune **Iterator**:
* Intrare: `{{code.products}}`
Aceasta parcurge fiecare produs din array.
## Pasul 5: Efectuați upsert pentru fiecare înregistrare
În interiorul iteratorului, adăugați o acțiune **Upsert Record**:
| Setare | Valoare |
| ------------------ | -------------------------------------- |
| **Obiect** | Obiectul dvs. Product personalizat |
| **Potrivire după** | ID extern sau SKU (identificator unic) |
| **Nume** | `{{iterator.item.name}}` |
| **SKU** | `{{iterator.item.sku}}` |
| **Preț** | `{{iterator.item.price}}` |
<Tip>
Utilizați **Upsert** (actualizare sau creare) în loc să construiți ramuri separate pentru creare vs. actualizare. Se construiește mai rapid și este mai ușor de depanat.
</Tip>
## Exemple de cazuri de utilizare
| Sursa | Date |
| --------------------------- | ------------------------------------------- |
| **Sistem ERP** | Catalog de produse, prețuri, stocuri |
| **Platformă de e-commerce** | Comenzi, clienți, actualizări de produse |
| **Depozit de date** | Metrici agregate, date îmbogățite |
| **Sistem de inventar** | Niveluri de stoc, alerte de reaprovizionare |
## Conexe
* [Declanșatoare ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-triggers)
* [Acțiuni ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-actions)
* [Gestionați array-urile în acțiunile Code](/l/ro/user-guide/workflows/how-tos/advanced-configurations/handle-arrays-in-code-actions)

View File

@@ -0,0 +1,130 @@
---
title: Aduceți răspunsurile din Typeform în Twenty
description: Gestionați payload-ul webhook al Typeform pentru a crea potențiali clienți din răspunsurile la formular.
---
Pentru configurarea standard a unui webhook, consultați [Configurați un declanșator Webhook](/l/ro/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger). Acest articol acoperă gestionarea specifică necesară pentru structura payload-ului personalizat al Typeform.
### Pasul 1: Creați un flux de lucru Webhook
1. Accesați **Setări → Fluxuri de lucru**
2. Faceți clic pe **+ Flux de lucru nou**
3. Selectați **Webhook** ca declanșator
4. Copiați URL-ul webhook
### Pasul 2: Configurați Typeform
1. În Typeform, deschideți formularul dvs.
2. Accesați **Connect → Webhooks**
3. Lipiți URL-ul webhook al Twenty
4. Salvează
### Pasul 3: Înțelegeți payload-ul Typeform
Typeform trimite o structură JSON îmbricată. Iată un exemplu simplificat:
```json
{
"event_type": "form_response",
"form_response": {
"form_id": "abc123",
"submitted_at": "2025-01-15T10:30:00Z",
"answers": [
{
"text": "Jane",
"type": "text",
"field": { "id": "field1", "type": "short_text", "title": "First Name" }
},
{
"text": "Smith",
"type": "text",
"field": { "id": "field2", "type": "short_text", "title": "Last Name" }
},
{
"text": "Acme Corp",
"type": "text",
"field": { "id": "field3", "type": "short_text", "title": "Company" }
},
{
"email": "jane@acme.com",
"type": "email",
"field": { "id": "field4", "type": "email", "title": "Email" }
},
{
"type": "choice",
"field": { "id": "field5", "type": "dropdown", "title": "Team Size" },
"choice": { "label": "10-50" }
}
]
}
}
```
Lucruri importante de reținut:
* Datele formularului sunt îmbricate sub `form_response`
* **Răspunsurile sunt returnate ca un array**, nu ca câmpuri denumite
* Fiecare răspuns include tipul și titlul câmpului pentru referință
### Pasul 4: Extrageți câmpurile din array-ul răspunsurilor
Deoarece `answers` este un array, în pașii următori puteți selecta doar întregul array — nu câmpuri individuale. Adăugați o acțiune **Code** pentru a extrage câmpurile de care aveți nevoie:
```javascript
export const main = async (params: {
answers: any;
}): Promise<object> => {
const { answers } = params;
// Handle input that may come as a string or an array
const answersFormatted = typeof answers === "string"
? JSON.parse(answers)
: answers;
// Extract fields by position or by finding the field type
const firstName = answersFormatted[0]?.text || "";
const lastName = answersFormatted[1]?.text || "";
const company = answersFormatted[2]?.text || "";
const email = answersFormatted.find(a => a.type === "email")?.email || "";
const teamSize = answersFormatted.find(a => a.type === "choice")?.choice?.label || "";
return {
contact: {
firstName,
lastName,
company,
email,
teamSize
}
};
};
```
Acum, în pașii următori, puteți selecta `contact.firstName`, `contact.email` etc. din selectorul de variabile.
<Tip>
Pentru mai multe detalii despre gestionarea array-urilor în acțiunile Code, consultați [Gestionați array-urile în acțiunile Code](/l/ro/user-guide/workflows/how-tos/advanced-configurations/handle-arrays-in-code-actions).
</Tip>
### Pasul 5: Creați înregistrarea
Adăugați o acțiune **Create Record**:
| Câmp | Valoare |
| ------------------- | ----------------------------------------------------- |
| **Obiect** | Persoane |
| **Prenume** | `{{code.contact.firstName}}` |
| **Nume de familie** | `{{code.contact.lastName}}` |
| **Email** | `{{code.contact.email}}` |
| **Companie** | Căutați sau creați pe baza `{{code.contact.company}}` |
### Pasul 6: Testați și activați
1. Trimiteți un răspuns de test în Typeform
2. Verificați rularea fluxului de lucru pentru a confirma că datele au fost capturate
3. Activați fluxul de lucru
## Conexe
* [Configurați un declanșator Webhook](/l/ro/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger)
* [Gestionați array-urile în acțiunile Code](/l/ro/user-guide/workflows/how-tos/advanced-configurations/handle-arrays-in-code-actions)

View File

@@ -0,0 +1,263 @@
---
title: Generați un PDF din Twenty
description: Creați un flux de lucru pentru a genera și atașa un PDF (de exemplu, o ofertă) la o înregistrare.
---
Generați sau preluați automat un PDF și atașați-l la o înregistrare în Twenty. Aceasta este utilizată frecvent pentru a crea oferte, facturi sau rapoarte care sunt asociate cu Companii, Oportunități sau alte obiecte.
## Prezentare generală
Acest flux de lucru folosește un **Manual Trigger** pentru ca utilizatorii să poată genera un PDF la cerere pentru orice înregistrare selectată. O **funcție logică** se ocupă de:
1. Descărcarea PDF-ului dintr-un URL (de la un serviciu de generare PDF)
2. Încărcarea fișierului în Twenty
3. Crearea unui atașament asociat înregistrării
## Cerințe
Înainte de a configura fluxul de lucru:
1. **Creați o cheie API**: Accesați **Settings → APIs** și creați o nouă cheie API. Vei avea nevoie de acest jeton pentru Funcția Logică.
2. **Configurați un serviciu de generare PDF** (opțional): Dacă doriți să generați dinamic fișiere PDF (de ex., oferte), utilizați un serviciu precum Carbone, PDFMonkey sau DocuSeal pentru a crea PDF-ul și a obține un URL de descărcare.
## Configurare pas cu pas
### Pasul 1: Configurați declanșatorul
1. Accesați **Workflows** și creați un nou flux de lucru
2. Selectați **Manual Trigger**
3. Alegeți obiectul la care doriți să atașați fișiere PDF (de ex., **Companie** sau **Oportunitate**)
<Tip>
Cu un declanșator manual, utilizatorii pot rula acest flux de lucru folosind un buton care apare în dreapta sus odată ce o înregistrare este selectată — aceasta rulează fluxul de lucru pentru a genera și atașează un PDF.
</Tip>
### Pasul 2: Adăugați o funcție logică
1. Adauga o actiune **Codul** (Functie Logica)
2. Creați o funcție nouă cu codul de mai jos
3. Configurați parametrii de intrare
#### Parametri de intrare
| Parametru | Valoare |
| ----------- | ----------------------- |
| `companyId` | `{{trigger.object.id}}` |
<Note>
Dacă atașați la un alt obiect (Persoană, Oportunitate etc.), redenumiți parametrul în mod corespunzător (de ex., `personId`, `opportunityId`) și actualizați funcția logică.
</Note>
#### Codul funcției logice
```typescript
export const main = async (
params: { companyId: string },
) => {
const { companyId } = params;
// Replace with your Twenty GraphQL endpoints (/metadata for metadata and files or /graphql for your records)
// Cloud: https://api.twenty.com/graphql
// Self-hosted: https://your-domain.com/graphql
const metadataGraphqlEndpoint = 'https://api.twenty.com/metadata';
const dataGraphqlEndpoint = 'https://api.twenty.com/graphql';
// Replace with your API key from Settings → APIs
const authToken = 'YOUR_API_KEY';
// Replace with your PDF URL
// This could be from a PDF generation service or a static URL
const pdfUrl = 'https://your-pdf-service.com/generated-quote.pdf';
const filename = 'quote.pdf';
// Step 1: Download the PDF file
const pdfResponse = await fetch(pdfUrl);
if (!pdfResponse.ok) {
throw new Error(`Failed to download PDF: ${pdfResponse.status}`);
}
const pdfBlob = await pdfResponse.blob();
const pdfFile = new File([pdfBlob], filename, { type: 'application/pdf' });
const fieldMetadataIdQuery = `
query FindUploadFileFieldMetadataId {
objects {
edges {
node {
nameSingular
fieldsList {
id
name
}
}
}
}
}
`;
// Step 2: Find a fieldMetadataId of "Attachment file" field in Attachments object with GraphQL API
const response = await fetch(metadataGraphqlEndpoint, {
method: 'POST',
headers: {
Authorization: `Bearer ${authToken}`
},
body: {
query: fieldMetadataIdQuery,
}
});
const result = await response.json();
const uploadFileFieldMetadataId = result.data.objects.edges.find(object => object.node.nameSingular === 'attachment').node.fieldsList.find(field => field.name === 'file').id;
// Step 3: Upload the file via GraphQL multipart upload
const uploadMutation = `
mutation UploadFilesFieldFile($file: Upload!, $fieldMetadataId: String!) {
uploadFilesFieldFile(file: $file, fieldMetadataId: $fieldMetadataId) {
id
}
}
`;
const uploadForm = new FormData();
uploadForm.append('operations', JSON.stringify({
query: uploadMutation,
variables: { file: null, fieldMetadataId: uploadFileFieldMetadataId },
}));
uploadForm.append('map', JSON.stringify({ '0': ['variables.file'] }));
uploadForm.append('0', pdfFile);
const uploadResponse = await fetch(metadataGraphqlEndpoint, {
method: 'POST',
headers: { Authorization: `Bearer ${authToken}` },
body: uploadForm,
});
const uploadResult = await uploadResponse.json();
if (uploadResult.errors?.length) {
throw new Error(`Upload failed: ${uploadResult.errors[0].message}`);
}
const fileId = uploadResult.data?.uploadFilesFieldFile?.id;
if (!fileId) {
throw new Error('No file id returned from upload');
}
// Step 4: Create the attachment linked to the company
const attachmentMutation = `
mutation CreateOneAttachment($data: AttachmentCreateInput!) {
createAttachment(data: $data) {
id
name
}
}
`;
const attachmentResponse = await fetch(dataGraphqlEndpoint, {
method: 'POST',
headers: {
Authorization: `Bearer ${authToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: attachmentMutation,
variables: {
data: {
name: filename,
targetCompanyId: companyId,
file: [
{
fileId: fileId,
label: filename
}
]
},
},
}),
});
const attachmentResult = await attachmentResponse.json();
if (attachmentResult.errors?.length) {
throw new Error(`Attachment creation failed: ${attachmentResult.errors[0].message}`);
}
return attachmentResult.data?.createAttachment;
};
```
### Pasul 3: Personalizați pentru cazul dvs. de utilizare
#### Pentru a atașa la un alt obiect
Înlocuiți `targetCompanyId` cu câmpul corespunzător:
| Obiect | Nume câmp |
| ------------------- | -------------------------- |
| Companie | `targetCompanyId` |
| Persoană | `targetPersonId` |
| Oportunitate | `targetOpportunityId` |
| Obiect personalizat | `targetYourCustomObjectId` |
Actualizați atât parametrul funcției, cât și obiectul `variables.data` în mutația de atașare.
#### Pentru a utiliza un URL PDF dinamic
Dacă utilizați un serviciu de generare PDF, puteți:
1. Mai întâi creați o acțiune HTTP Request pentru a genera PDF-ul
2. Transmiteți URL-ul PDF returnat către funcția logică ca parametru
```typescript
export const main = async (
params: { companyId: string; pdfUrl: string; filename: string },
) => {
const { companyId, pdfUrl, filename } = params;
// ... rest of the function
};
```
### Pasul 4: Testați și activați
1. Salvați fluxul de lucru
2. Navigați la o înregistrare de tip Company
3. Faceți clic pe meniul **⋮** și selectați fluxul dvs. de lucru
4. Verificați secțiunea **Attachments** din înregistrare pentru a confirma că PDF-ul a fost atașat
5. Activați fluxul de lucru
## Combinare cu servicii de generare PDF
Pentru crearea de oferte sau facturi dinamice:
### Exemplu: Generați ofertă → Atașați PDF
| Pas | Acțiune | Scop |
| --- | ------------------------ | ------------------------------------------------------ |
| 1 | Manual Trigger (Company) | Utilizatorul inițiază dintr-o înregistrare |
| 2 | Căutare înregistrare | Obțineți detalii despre Opportunity sau despre poziții |
| 3 | Solicitare HTTP | Apelați API-ul de generare PDF cu datele înregistrării |
| 4 | Funcție logică | Descărcați și atașați PDF-ul generat |
### Servicii populare de generare PDF
* **Carbone** - Generare de documente pe bază de șabloane
* **PDFMonkey** - Creare dinamică de PDF-uri din șabloane
* **DocuSeal** - Platformă de automatizare a documentelor
* **Documint** - Generare de documente orientată pe API
Fiecare serviciu furnizează un API care returnează un URL PDF, pe care apoi îl puteți trece la Funcția Logică.
## Depanare
| Problemă | Soluție |
| ------------------------------------- | ---------------------------------------------------------------------------- |
| "Nu s-a reușit descărcarea PDF-ului" | Verificați că URL-ul PDF este accesibil și returnează un PDF valid |
| "Nu s-a reușit încărcarea" | Verificați că cheia API este validă și are permisiuni de scriere |
| "Nu s-a reușit crearea atașamentului" | Asigurați-vă că numele câmpului ID al obiectului corespunde obiectului țintă |
## Conexe
* [Declanșatoare ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-triggers)
* [Funcții logice](/l/ro/user-guide/workflows/capabilities/workflow-actions#code)
* [Generați o ofertă sau o factură din Twenty](/l/ro/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty)

View File

@@ -0,0 +1,144 @@
---
title: Generați o ofertă sau o factură din Twenty
description: Creați automat facturi în instrumente externe atunci când se închid oportunitățile.
---
Trimiteți automat datele oportunității către sistemul dvs. de facturare (Stripe, QuickBooks, Xero etc.) atunci când o oportunitate este câștigată.
## Structura fluxului de lucru
1. **Declanșator**: Înregistrarea este actualizată (Oportunitate)
2. **Filtru**: Etapă = Closed Won
3. **Căutare înregistrare**: Obțineți detaliile Companiei
4. **Cod** (opțional): Formatați payload-ul
5. **Cerere HTTP**: Trimiteți către sistemul de facturare
## Pasul 1: Configurați declanșatorul
1. Creați un nou flux de lucru
2. Selectați declanșatorul **Record is Updated**
3. Alegeți **Opportunity** ca obiect
## Pasul 2: Filtrați pentru Closed Won
Adăugați o acțiune **Filter** pentru a continua doar când oportunitatea este câștigată:
| Setare | Valoare |
| ------------ | ------------------------------------- |
| **Câmp** | Etapa |
| **Condiție** | Egal |
| **Valoare** | `CLOSED_WON` (sau numele etapei dvs.) |
<Tip>
Declanșatorul se activează la orice actualizare a unei Oportunități. Filtrul asigură că fluxul de lucru continuă doar când etapa se schimbă la Closed Won.
</Tip>
## Pasul 3: Obțineți detalii despre Companie
Înregistrarea Oportunității s-ar putea să nu includă toate câmpurile Companiei de care aveți nevoie pentru factură. Adăugați o acțiune **Search Record**:
| Setare | Valoare |
| ------------------ | ----------------------------------------- |
| **Obiect** | Companie |
| **Potrivire după** | ID egal cu `{{trigger.object.companyId}}` |
Aceasta preia înregistrarea completă a Companiei cu adresa de facturare, ID fiscal etc.
## Pasul 4: Formatați payload-ul (opțional)
Dacă sistemul dvs. de facturare așteaptă un format specific, adăugați o acțiune **Code**:
```javascript
export const main = async (params: {
opportunity: any;
company: any;
}): Promise<object> => {
const { opportunity, company } = params;
return {
invoice: {
// Customer info from Company
customer_name: company.name,
customer_email: company.email || "",
billing_address: {
line1: company.address?.street || "",
city: company.address?.city || "",
postal_code: company.address?.postalCode || "",
country: company.address?.country || ""
},
tax_id: company.taxId || null,
// Invoice details from Opportunity
amount: opportunity.amount,
currency: opportunity.currency || "USD",
description: `Invoice for ${opportunity.name}`,
due_days: 30,
// Reference back to Twenty
metadata: {
opportunity_id: opportunity.id,
company_id: company.id
}
}
};
};
```
## Pasul 5: Trimiteți către sistemul de facturare
Adăugați o acțiune **HTTP Request**:
| Setare | Valoare |
| ------------ | ------------------------------------------------------ |
| **Metodă** | POST |
| **URL** | Punctul final al API-ului sistemului dvs. de facturare |
| **Anteturi** | `Authorization: Bearer YOUR_API_KEY` |
| **Corp** | `{{code.invoice}}` sau mapați câmpurile direct |
### Exemplu: Factură Stripe
```
POST https://api.stripe.com/v1/invoices
Headers:
Authorization: Bearer sk_live_xxx
Content-Type: application/x-www-form-urlencoded
Body:
customer: {{company.stripeCustomerId}}
collection_method: send_invoice
days_until_due: 30
```
### Exemplu: Factură QuickBooks
```
POST https://quickbooks.api.intuit.com/v3/company/{realmId}/invoice
Headers:
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
Body: {{code.invoice}}
```
## Rezumat complet al fluxului de lucru
| Pas | Acțiune | Scop |
| --- | ------------------------------------------- | ---------------------------------------------------------- |
| 1 | Declanșator: Înregistrarea este actualizată | Se activează la orice modificare a unei Oportunități |
| 2 | Filtru | Continuați doar dacă Etapa = Closed Won |
| 3 | Căutare înregistrare | Obțineți detaliile complete ale Companiei pentru facturare |
| 4 | Cod | Formatați datele pentru API-ul de facturare |
| 5 | Solicitare HTTP | Creați factura în sistemul extern |
## Sfaturi
* **Stocați ID-urile externe**: Salvați ID-ul facturii returnat de API înapoi în Oportunitate folosind o acțiune **Update Record**
* **Gestionarea erorilor**: Adăugați o ramură pentru a trimite o notificare dacă cererea HTTP eșuează
* **Testați mai întâi**: Utilizați modul sandbox/test al sistemului dvs. de facturare înainte de lansare
## Conexe
* [Generați un PDF din Twenty](/l/ro/user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty) — atașați PDF-uri generate la înregistrări
* [Declanșatoare ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-triggers)
* [Acțiuni ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-actions)
* [Automatizări pentru Closed Won](/l/ro/user-guide/workflows/how-tos/crm-automations/closed-won-automations)

View File

@@ -0,0 +1,170 @@
---
title: Configurați un declanșator webhook
description: Primiți date de la servicii externe pentru a declanșa fluxuri de lucru.
---
Declanșatoarele webhook permit serviciilor externe să pornească fluxurile dvs. de lucru trimițând date către un URL unic. Folosiți-le pentru a conecta formulare, aplicații terțe și integrări personalizate.
## Când să folosiți webhook-uri
| Caz de utilizare | Exemplu |
| --------------------------- | ---------------------------------------------------------------- |
| **Formulare web** | Trimiterile din formularul de contact creează potențiali clienți |
| **Aplicații terțe** | Plată Stripe → creează o înregistrare de client |
| **Integrări personalizate** | Aplicația dvs. → automatizare în Twenty |
| **Instrumente no-code** | Conexiuni Zapier, Make, n8n |
## Configurare pas cu pas
### Pasul 1: Creați fluxul de lucru
1. Accesați **Setări → Fluxuri de lucru**
2. Faceți clic pe **+ Flux de lucru nou**
3. Denumiți-l (de ex., "Trimitere formular site")
### Pasul 2: Configurați declanșatorul webhook
1. Faceți clic pe blocul declanșator
2. Selectați **Webhook**
3. Veți primi un URL de webhook unic, de exemplu:
```
https://api.twenty.com/webhooks/workflow/abc123...
```
4. Copiați acest URL — veți avea nevoie de el pentru serviciul dvs. extern
### Pasul 3: Definiți structura de date așteptată
Pentru cererile **POST**, definiți structura așteptată a corpului:
1. Faceți clic pe **Define expected body**
2. Introduceți un exemplu JSON care corespunde cu ceea ce va trimite serviciul dvs.:
```json
{
"firstName": "John",
"lastName": "Doe",
"email": "john@example.com",
"company": "Acme Inc",
"message": "Interested in your product"
}
```
3. Faceți clic pe **Salvați** — aceasta creează variabile pe care le puteți utiliza în pașii următori
### Pasul 4: Adăugați acțiuni
Acum adăugați acțiuni care folosesc datele webhook-ului:
**Exemplu: Creați o înregistrare Person**
1. Adăugați acțiunea **Create Record**
2. Selectați obiectul **People**
3. Asociați câmpurile:
| Câmp | Valoare |
| --------------- | ----------------------------------------------------- |
| Prenume | `{{trigger.body.firstName}}` |
| Nume de familie | `{{trigger.body.lastName}}` |
| Email | `{{trigger.body.email}}` |
| Companie | Căutați sau creați pe baza `{{trigger.body.company}}` |
### Pasul 5: Testați webhook-ul
Înainte de activare, testați webhook-ul:
**Folosind cURL**:
```bash
curl -X POST https://api.twenty.com/webhooks/workflow/abc123... \
-H "Content-Type: application/json" \
-d '{"firstName":"Test","lastName":"User","email":"test@example.com"}'
```
**Folosind Postman sau similar**:
1. Creați o cerere POST către URL-ul webhook-ului
2. Setați antetul Content-Type la `application/json`
3. Adăugați corpul JSON de test
4. Trimiteți și verificați rulările fluxului de lucru
### Pasul 6: Activați
După testare, faceți clic pe **Activați** pentru a activa fluxul de lucru.
## Gestionarea diferitelor structuri de date
### Date îmbricate
Dacă webhook-ul trimite date îmbricate:
```json
{
"contact": {
"name": "John Doe",
"email": "john@example.com"
},
"source": "website"
}
```
Faceți referire astfel: `{{trigger.body.contact.email}}`
### Tablouri
Dacă datele includ tablouri:
```json
{
"items": [
{"name": "Product A", "qty": 2},
{"name": "Product B", "qty": 1}
]
}
```
Modul în care gestionați tablourile depinde de cazul dvs. de utilizare:
**Număr necunoscut de elemente → Folosiți Iterator**
Dacă trebuie să procesați fiecare element din tablou (de ex., să creați o înregistrare pentru fiecare), adăugați o acțiune **Code** pentru a analiza tabloul, apoi folosiți **Iterator**:
```javascript
export const main = async (params: { items: any }) => {
const items = typeof params.items === "string"
? JSON.parse(params.items)
: params.items;
return { items };
};
```
Apoi utilizați Iterator pentru a itera: `{{code.items}}`
**Câmpuri cunoscute/specifice → Extrageți în câmpuri denumite**
Dacă tabloul conține câmpuri specifice la care doriți să accesați individual (de ex., răspunsuri de formular în care poziția 0 este întotdeauna "prenume", poziția 1 este întotdeauna "nume"), adăugați o acțiune **Code** pentru a le extrage:
```javascript
export const main = async (params: { items: any }) => {
const items = typeof params.items === "string"
? JSON.parse(params.items)
: params.items;
return {
product: {
name: items[0]?.name || "",
qty: items[0]?.qty || 0
}
};
};
```
Acum puteți selecta `product.name` și `product.qty` individual în pașii următori.
<Tip>
Pentru mai multe detalii despre gestionarea tablourilor, consultați [Gestionarea tablourilor în acțiunile Code](/l/ro/user-guide/workflows/how-tos/advanced-configurations/handle-arrays-in-code-actions).
</Tip>
## Conexe
* [Declanșatoare ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-triggers)
* [Acțiuni ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-actions)

View File

@@ -0,0 +1,121 @@
---
title: Răspuns automat la e-mailurile primite
description: Creează un flux de lucru care folosește IA pentru a tria e-mailurile primite și pentru a trimite automat răspunsuri în același fir.
---
Răspunde la e-mailurile primite în câteva secunde — nu în ore. Acest flux de lucru folosește un AI Agent pentru a filtra zgomotul (buletine de știri, spam, răspunsuri automate) și pentru a crea un răspuns personalizat la mesajele reale. Apoi, AI îl trimite ca un răspuns filetat în conversația originală.
## Cum funcționează firele de e-mail
Fiecare e-mail are un antet ascuns `Message-ID` — o amprentă unică atribuită de serverul de e-mail al expeditorului. Când răspundeți la un e-mail, clientul dvs. de e-mail setează un antet `In-Reply-To` care face referire la acea amprentă. Astfel, Gmail, Outlook și orice alt client grupează mesajele în fire de discuție.
În Twenty, acea amprentă este stocată ca `headerMessageId` pe obiectul Message. Fluxul dvs. de lucru o preia și o transmite în câmpul In-Reply-To al acțiunii Send Email.
## Construirea fluxului de lucru
### Pasul 1: Creați un flux de lucru nou
Accesați **Settings -> Workflows** și faceți clic pe **+ New Workflow**.
### Pasul 2: Declanșare la mesajele primite
Alegeți **When a Record is Created** și selectați **Messages**.
De fiecare dată când un e-mail ajunge în Twenty, aceasta se declanșează.
<img src="/images/user-guide/workflows/auto-reply/workflow-overview.png" style={{width:'100%'}} />
### Pasul 3: Căutați cine l-a trimis
Adăugați o acțiune **Search Records**.
Adresa expeditorului nu este în mesajul propriu-zis — se găsește în înregistrarea asociată Message Participant.
| Câmp | Valoare |
| ---------- | --------------------------------- |
| **Obiect** | Participanți la mesaj |
| **Filtru** | Mesajul **este** `{{trigger.id}}` |
| **Filtru** | Rolul **este** From |
| **Limită** | 1 |
Aceasta vă oferă e-mailul expeditorului în `handle` și numele acestuia în `displayName`.
<img src="/images/user-guide/workflows/auto-reply/find-sender.png" style={{width:'100%'}} />
### Pasul 4: Trimiteti si redactati un raspuns cu AI
Adăugați o acțiune **AI Agent**. Acest singur pas face două lucruri: decide dacă e-mailul merită un răspuns și, dacă da, redactează unul.
Folosiți un prompt de tipul:
```
You are an email triage assistant for a sales team. Read the following
inbound email and decide if it deserves a reply.
Subject: {{trigger.subject}}
Body: {{trigger.text}}
From: {{Find Sender.first.displayName}} ({{Find Sender.first.handle}})
If this email is spam, a newsletter, an automated notification, or
otherwise does not need a human reply, respond with exactly: SKIP
Otherwise, write a short, professional reply (3-4 sentences max) that:
- Acknowledges their specific message
- Lets them know someone from the team will follow up shortly
- Is warm but not overly casual
Respond with only the reply text, no subject line or greeting prefix.
```
AI Agent produce răspunsul în câmpul `response`, la care pot face referire pașii următori.
<img src="/images/user-guide/workflows/auto-reply/ai-triage.png" style={{width:'100%'}} />
### Pasul 5: Ramificați în funcție de decizia AI
Adăugați o acțiune **If/Else** pentru a verifica dacă AI a decis să răspundă sau să o omită.
| Câmp | Valoare |
| ---------------------- | -------------------------------------------- |
| **Condiție** | AI Agent `response` **nu conține** `SKIP` |
| **Dacă este adevărat** | Continuați la Send Email |
| **Altfel** | Nu faceți nimic (fluxul de lucru se încheie) |
Spam-ul, buletinele informative și mesajele generate automat sunt ignorate. Tot restul trece la pasul următor.
<img src="/images/user-guide/workflows/auto-reply/should-reply.png" style={{width:'100%'}} />
### Pasul 6: Trimiteți un răspuns în același fir
Adăugați o acțiune **Send Email** pe ramura "if true". Faceți clic pe **Advanced options**, apoi pe **Add In-Reply-To**.
| Câmp | Valoare |
| --------------- | -------------------------------------- |
| **Către** | `{{Find Sender.first.handle}}` |
| **Subiect** | `Re: {{trigger.subject}}` |
| **Body** | `{{AI Triage & Draft Reply.response}}` |
| **In-Reply-To** | `{{trigger.headerMessageId}}` |
Câmpul In-Reply-To este cel care face ca acesta să fie un răspuns, nu o conversație nouă. Destinatarul îl vede afișat în fir sub e-mailul original în Gmail, Outlook sau orice alt client.
<img src="/images/user-guide/workflows/auto-reply/send-email.png" style={{width:'100%'}} />
<Tip>
**In-Reply-To** necesită un `message.headerMessageId` din declanșator — este amprenta unică a e-mailului, nu o adresă a destinatarului. Dacă îl lăsați necompletat, e-mailul se trimite în continuare, doar ca un mesaj independent.
</Tip>
<Warning>
Gmail folosește subiectul pentru a grupa mesajele în fire de discuție. Subiectul **trebuie** să înceapă cu `Re:` (inclusiv două puncte și spațiu) pentru ca Gmail să afișeze răspunsul în cadrul firului original. Fără acesta, răspunsul va apărea ca o conversație separată — chiar dacă antetul In-Reply-To este setat corect.
</Warning>
### Pasul 7: Testați și activați
Apăsați **Test**, apoi verificați clientul de e-mail. Răspunsul ar trebui să apară sub mesajul original.
Activați când sunteți mulțumit(ă) de rezultat.
## Idei pe care să le dezvoltați
* **Răspundeți doar VIP-urilor** — adăugați o ramură care verifică domeniul expeditorului sau dacă acesta există ca Contact în Twenty
* **Dirijați în funcție de intenție** — folosiți prompturi AI Agent separate pentru a trata diferit solicitările de vânzări față de cererile de asistență
* **Îmbogățiți înainte de a răspunde** — adăugați un pas Search Records pentru a include compania expeditorului sau istoricul tranzacțiilor în promptul AI, pentru răspunsuri mai personalizate

View File

@@ -0,0 +1,179 @@
---
title: Automatizări pentru Closed Won
description: Automatizați activitățile de după câștig atunci când oportunitățile se închid.
---
Când o tranzacție se închide, trebuie să se întâmple mai multe lucruri: actualizați starea companiei, notificați membrii echipei, creați sarcini de onboarding. Automatizați totul cu un singur flux de lucru.
## Problema
Atunci când o oportunitate trece la "Closed Won":
* Tipul companiei trebuie să se schimbe din "Prospect" în "Customer"
* Trebuie create sarcini de onboarding
* Echipa de Customer Success trebuie notificată
* Reprezentantul de vânzări are nevoie de confirmare
Efectuarea manuală a acestor pași consumă timp și este predispusă la erori.
## Soluția
Creați un flux de lucru care gestionează automat toate activitățile de după câștig.
## Configurare completă a fluxului de lucru
### Pasul 1: Creați fluxul de lucru
1. Accesați **Setări → Fluxuri de lucru**
2. Faceți clic pe **+ Flux de lucru nou**
3. Denumiți-l "Deal Won - Post-Win Automation"
### Pasul 2: Configurați declanșatorul
1. Selectați **Record is Updated**
2. Alegeți **Oportunități**
3. La "Fields to monitor", selectați **Stage**
### Pasul 3: Adăugați filtrul de stadiu
1. Adăugați acțiunea **Filter**
2. Condiție: `{{trigger.object.stage}}` este egal cu "Closed Won"
### Pasul 4: Actualizați tipul companiei
1. Adăugați acțiunea **Update Record**
2. Configurați:
| Câmp | Valoare |
| -------------------------- | ------------------------------- |
| **Obiect** | Companii |
| **Înregistrare** | `{{trigger.object.company.id}}` |
| **Tip** | Client |
| **Data primei tranzacții** | `{{trigger.object.closedAt}}` |
| **Proprietarul contului** | `{{trigger.object.owner.id}}` |
### Pasul 5: Creați o sarcină de onboarding
1. Adăugați acțiunea **Create Record**
2. Configurați:
| Câmp | Valoare |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| **Obiect** | Sarcini |
| **Titlu** | `Onboarding: {{trigger.object.name}}` |
| **Responsabil** | Membru al echipei de Customer Success |
| **Data scadenței** | Peste 3 zile |
| **Prioritate** | Ridicată |
| **Companie asociată** | `{{trigger.object.company.id}}` |
| **Oportunitate asociată** | `{{trigger.object.id}}` |
| **Descriere** | `Onboarding pentru noul client {{trigger.object.company.name}}. Valoarea tranzacției: {{trigger.object.amount}}` |
### Pasul 6: Notificați echipa de Customer Success
1. Adăugați acțiunea **Send Email**
2. Configurați:
| Câmp | Valoare |
| ----------- | ------------------------------------------------ |
| **Către** | customer-success@yourcompany.com |
| **Subiect** | `🎉 Client nou: {{trigger.object.company.name}}` |
| **Corp** | Consultați exemplul de mai jos |
**Exemplu de corp al e-mailului**:
```
Hi CS Team,
We have a new customer!
Company: {{trigger.object.company.name}}
Deal: {{trigger.object.name}}
Value: {{trigger.object.amount}}
Sales Rep: {{trigger.object.owner.name}}
Close Date: {{trigger.object.closedAt}}
An onboarding task has been created automatically.
Let's give them a great start!
```
### Pasul 7: Confirmare către reprezentantul de vânzări
1. Adăugați încă o acțiune **Send Email**
2. Configurați:
| Câmp | Valoare |
| ----------- | ----------------------------------------------------------------------------------------------------------------- |
| **Către** | `{{trigger.object.owner.email}}` |
| **Subiect** | `✅ Tranzacție închisă: {{trigger.object.name}}` |
| **Corp** | Felicitări! Tranzacția a fost procesată. Echipa de Customer Success a fost notificată și onboarding-ul a început. |
### Pasul 8: Testați și activați
1. Testați mutând o oportunitate de test la "Closed Won"
2. Verifică:
* Tipul companiei schimbat la "Customer"
* Sarcină de onboarding creată
* Echipa de Customer Success a primit e-mailul
* Reprezentantul de vânzări a primit confirmarea
3. Activați când sunteți gata
## Gestionarea Closed Lost
Creați un flux de lucru similar pentru tranzacțiile pierdute:
### Declanșator
* Record is Updated (Oportunități, Stage = "Closed Lost")
### Acțiuni
1. **Create Record**: Sarcină pentru "Lost Deal Analysis"
2. **Update Record**: Adăugați motivul pierderii în înregistrarea companiei
3. **Send Email**: Notificați managerul privind tranzacția pierdută
## Avansat: Onboarding în mai mulți pași
Pentru onboarding complex, creați mai multe sarcini:
```javascript
export const main = async (params) => {
const tasks = [
{ title: "Welcome call", daysFromNow: 1, assignee: "CS" },
{ title: "Send onboarding materials", daysFromNow: 2, assignee: "CS" },
{ title: "Technical setup", daysFromNow: 5, assignee: "Support" },
{ title: "30-day check-in", daysFromNow: 30, assignee: "CS" }
];
return { tasks };
};
```
Utilizați **Iterator** pentru a crea fiecare sarcină din array.
## Idei de personalizare
### Mențineți celelalte instrumente actualizate
* Creați un client în sistemul de facturare cu un **HTTP Request**
### Acţiuni condiţionate
Utilizați acțiunile **Filter** pentru:
* Onboarding diferit pentru enterprise vs IMM
* Responsabili diferiți în funcție de regiune
* Omiteți notificările pentru tranzacții mici
### Include detaliile tranzacției
Utilizați acțiunea **Code** pentru a formata:
* Documente cu rezumatul tranzacției
* Note de predare pentru echipa de Customer Success
* Liste de verificare personalizate pentru onboarding
## Conexe
* [Acțiuni ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-actions)
* [Trimiteți e-mailuri din fluxuri de lucru](/l/ro/user-guide/workflows/capabilities/send-emails-from-workflows)

View File

@@ -0,0 +1,136 @@
---
title: Detectați oportunitățile stagnante
description: Notificați automat managerii când oportunitățile nu au fost actualizate.
---
Mențineți pipeline-ul sănătos alertând managerii când oportunitățile devin stagnante. Acest flux de lucru verifică oportunitățile care nu au fost actualizate într-un număr specificat de zile.
## Problema
Oportunitățile lăsate fără actualizări duc la:
* Tranzacții care se răcesc
* Previziuni nesigure
* Venituri pierdute
## Soluția
Creați un flux de lucru programat care găsește oportunități stagnante și le trimite prin e-mail managerilor lor.
## Configurare pas cu pas
### Pasul 1: Creați fluxul de lucru
1. Accesați **Setări → Fluxuri de lucru**
2. Faceți clic pe **+ Flux de lucru nou**
3. Denumiți-l "Alertă pentru oportunități stagnante"
### Pasul 2: Configurați declanșatorul
1. Selectați **On a Schedule**
2. Setați să ruleze zilnic (de exemplu, în fiecare zi la 8 AM)
### Pasul 3: Căutați oportunități stagnante
1. Adăugați acțiunea **Search Records**
2. Configurați:
| Câmp | Valoare |
| ---------- | --------------------------------------------------- |
| **Obiect** | Oportunități |
| **Filtru** | Updated At este înainte de (astăzi - 7 zile) |
| **Filtru** | Stage nu este "Closed Won" ȘI nu este "Closed Lost" |
| **Limită** | 100 |
### Pasul 4: Verificați dacă s-au găsit rezultate
1. Adăugați acțiunea **Filter**
2. Condiție: `{{searchRecords.length}}` este mai mare decât 0
3. Dacă nu există oportunități stagnante, fluxul de lucru se oprește aici
### Pasul 5: Formatați alerta (acțiune Code)
Adăugați o acțiune **Code** pentru a formata e-mailul:
```javascript
export const main = async (params) => {
const opportunities = params.opportunities;
// Group opportunities by owner
const byOwner = {};
opportunities.forEach(opp => {
const ownerEmail = opp.owner?.email || 'unassigned';
if (!byOwner[ownerEmail]) {
byOwner[ownerEmail] = [];
}
byOwner[ownerEmail].push({
name: opp.name,
amount: opp.amount,
lastUpdated: opp.updatedAt,
stage: opp.stage
});
});
// Format summary for manager
let summary = "Stale Opportunities Report\n\n";
Object.entries(byOwner).forEach(([owner, opps]) => {
summary += `${owner}: ${opps.length} stale opportunities\n`;
opps.forEach(opp => {
summary += ` - ${opp.name} (${opp.stage})\n`;
});
summary += "\n";
});
return {
summary,
totalCount: opportunities.length
};
};
```
### Pasul 6: Trimiteți e-mailul de alertă
Adăugați acțiunea **Send Email**:
| Câmp | Valoare |
| ----------- | ---------------------------------------------------------------- |
| **Către** | sales-manager@yourcompany.com |
| **Subiect** | `🚨 {{code.totalCount}} oportunități stagnante necesită atenție` |
| **Corp** | `{{code.summary}}` |
### Pasul 7: Testați și activați
1. Faceți clic pe **Test** pentru a rula fluxul de lucru
2. Verificați că e-mailul conține datele corecte
3. Activați când sunteți gata
## Opțiuni de personalizare
### Modificați pragul de stagnare
Modificați filtrul Search Records pentru a schimba de la 7 zile la perioada preferată:
* 3 zile pentru vânzări cu ritm ridicat
* 14 zile pentru tranzacții enterprise
* 30 de zile pentru cicluri de vânzări lungi
### Alerte pentru reprezentanți individuali
În loc de un singur e-mail către manager, folosiți **Iterator** pentru a trimite e-mailuri personalizate fiecărui reprezentant despre tranzacțiile lor stagnante.
### Adăugați escaladare
Creați mai multe fluxuri de lucru cu severitate în creștere:
1. Ziua 7: E-mail către reprezentant
2. Ziua 14: E-mail către reprezentant + manager
3. Ziua 21: Creați o sarcină pentru ca managerul să intervină
### Includeți în Slack
Utilizați **HTTP Request** pentru a posta către un webhook Slack în locul sau pe lângă e-mail.
## Conexe
* [Acțiuni ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-actions)
* [Trimiteți e-mailuri din fluxuri de lucru](/l/ro/user-guide/workflows/capabilities/send-emails-from-workflows)

View File

@@ -0,0 +1,69 @@
---
title: Afişare număr de e-mailuri primite
description: Creați un flux de lucru pentru a număra automat și afișa numărul de e-mailuri primite de la fiecare contact.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
<img src="/images/user-guide/workflows/workflow-number-of-emails-received.png" style={{width:'100%'}} />
## Prezentare generală
Acest flux de lucru declanșează de fiecare dată când se primește un nou e-mail și actualizează un câmp personalizat în Înregistrarea Persoanei cu numărul total de e-mailuri de la acel expeditor.
## Cerințe
Înainte de a configura acest flux de lucru, creaţi un câmp personalizat pe obiectul **Persoane**:
1. Mergeți la \*\*Setări → Model de date → Oameni \*\*
2. Adauga un nou camp **Numărul**
3. Numește-l ceva ca "Numărul de e-mailuri primite de la această persoană"
## Configurare pas cu pas
<VimeoEmbed videoId="1148700336" title="Demonstrație video" />
### Pasul 1: Configurați Declanșatorul
1. Mergeți la **Fluxuri de lucru** și creați un nou flux de lucru
2. Selectați **Înregistrarea este creată** ca declanșator
3. Alege **Participanţii la mesaje** (disponibil sub obiecte avansate)
<Note>
Un participant la mesaj este o combinație între un ID de mesaj și un ID de persoană, creând o înregistrare unică per mesaj. Acest lucru este mai uşor de urmărit decât mesajele direct, deoarece putem accesa câmpul "handle", care conţine adresa de e-mail a expeditorului (sau a destinatarului).
</Note>
### Pasul 2: Filtrare pe rol
1. Adaugă o acțiune **filtru**
2. Setaţi condiţia: **Rol** este egal cu **FROM**
Acest lucru vă asigură că numărați doar mesajele trimise de această persoană, nu le sunt trimise.
### Pasul 3: Caută toţi participanţii la mesaje cu acelaşi manual
1. Adăugați o **acțiune de căutare Records**
2. Selectați **Participanții la mesaje** ca obiect
3. Adaugă filtre: **Handle** este egal cu procesorul de la declanșatorul (adresa de e-mail a expeditorului) și **Rol** egal cu **FROM**
4. Crește **Limita** de la 1 la **200** (maxim)
Aceasta găsește toate mesajele de la această adresă de e-mail pentru a obține numărul total.
<Note>
Acțiunea de căutare Înregistrări este limitată la maxim 200 de înregistrări. Cu toate acestea, deoarece utilizaţi doar valoarea `totalCount` (nu înregistrările individuale), acest pas va returna numărul total de e-mailuri trimise de această persoană.
</Note>
### Pasul 4: Actualizați înregistrarea persoanei cu o acțiune de creare sau actualizare a înregistrării
1. Adăugați o acțiune **Creare sau Actualizare Înregistrare**
2. Selectează **persoane** ca obiect
3. Găsiți persoana potrivindu-și adresa de e-mail cu `handle` de la Participantul la Mesaj
4. Setaţi câmpul personalizat "Număr de e-mailuri primite" la `{{searchRecords.totalCount}}`
Valoarea `totalCount` din acțiunea de căutare Înregistrări reprezintă numărul total de e-mailuri primite de la această persoană.
## Conexe
* [Acțiuni flux de lucru](/l/ro/user-guide/workflows/capabilities/workflow-actions)
* [Creare câmpuri personalizate](/l/ro/user-guide/data-model/how-tos/customize-your-data-model)
* [Search Records Action](/l/ro/user-guide/workflows/capabilities/workflow-actions#search-records)

View File

@@ -0,0 +1,170 @@
---
title: Afișarea datelor din înregistrări asociate
description: Afișați date din înregistrări asociate (de ex., informații despre Companie pe Oportunități) folosind fluxuri de lucru.
---
Afișați date din înregistrări asociate direct pe înregistrările dvs. — de exemplu, afișați numărul de angajați al unei Companii pe Oportunitățile sale. Această soluție de ocolire prin fluxuri de lucru este utilă până când câmpurile imbricate vor fi disponibile nativ.
## Cazuri de Utilizare Comune
| Sursa | Destinație | Câmpuri de copiat |
| ------------ | ------------ | ---------------------------------------------------------- |
| Companie | Oportunitate | Industrie, Dimensiunea Companiei, ARR |
| Persoană | Oportunitate | Email, Telefon, Funcție |
| Oportunitate | Companie | Suma ultimei tranzacții, Data ultimei tranzacții câștigate |
## Copiere de câmpuri de bază
### Exemplu: Copiați Emailul Contactului în Oportunitate
**Obiectiv**: Atunci când setați un Punct de Contact pe o oportunitate, copiați emailul persoanei în oportunitate pentru acces facil.
### Condiție prealabilă
Creați câmpurile destinație în **Settings → Data Model → Opportunities** înainte de a construi fluxul de lucru:
* Email Contact (tip: Email)
* Telefon Contact (tip: Phone)
### Configurare
1. **Declanșator**: Înregistrarea este actualizată (Oportunități, câmp Punct de Contact)
2. **Filtru**: Verificați că Punctul de Contact nu este gol
3. **Căutare înregistrări**: Găsiți persoana asociată
* Obiect: Persoane
* Filtru: ID egal cu `{{trigger.object.pointOfContact.id}}`
4. **Actualizați Înregistrarea**:
* Obiect: Oportunități
* Înregistrare: `{{trigger.object.id}}`
* Email Contact: `{{searchRecords[0].email}}`
* Telefon Contact: `{{searchRecords[0].phone}}`
## Copierea mai multor câmpuri
### Exemplu: Sincronizați informațiile Companiei cu toate Oportunitățile asociate
**Obiectiv**: Când se schimbă detaliile companiei, actualizați toate oportunitățile asociate.
### Configurare
1. **Declanșator**: Înregistrarea este actualizată (Companii)
* Câmpuri: Industrie, Dimensiunea Companiei, Venit Anual
2. **Căutare înregistrări**: Găsiți toate oportunitățile pentru această companie
* Obiect: Oportunități
* Filtru: ID Companie egal cu `{{trigger.object.id}}`
3. **Iterator**: Parcurgeți fiecare oportunitate
4. **Actualizați Înregistrarea** (în interiorul iteratorului):
* Obiect: Oportunități
* Înregistrare: `{{iterator.currentItem.id}}`
* Industria Companiei: `{{trigger.object.industry}}`
* Dimensiunea Companiei: `{{trigger.object.companySize}}`
* ARR al Companiei: `{{trigger.object.annualRevenue}}`
## Copiere la crearea înregistrării
### Exemplu: Precompletați Oportunitatea cu datele Companiei
**Obiectiv**: La crearea unei oportunități legate de o companie, copiați automat informațiile esențiale ale companiei.
### Condiție prealabilă
Creați câmpurile destinație în **Settings → Data Model → Opportunities**:
* Industria Companiei (tip: Text)
* Dimensiunea Companiei (tip: Number)
### Configurare
1. **Declanșator**: Înregistrarea este creată (Oportunități)
* Filtru: Compania nu este goală
2. **Căutare înregistrări**: Obțineți detaliile companiei asociate
* Obiect: Companii
* Filtru: ID egal cu `{{trigger.object.company.id}}`
3. **Actualizați Înregistrarea**:
* Obiect: Oportunități
* Înregistrare: `{{trigger.object.id}}`
* Industria Companiei: `{{searchRecords[0].industry}}`
* Dimensiunea Companiei: `{{searchRecords[0].employees}}`
<Note>
**Limitare Tasks and Notes**: Relațiile pentru Tasks și Notes sunt codificate ca many-to-many și nu sunt încă disponibile în declanșatoare sau acțiuni de flux de lucru. Pentru a accesa aceste relații, utilizați [API-ul](/l/ro/developers/extend/api) în schimb.
</Note>
## Sincronizare bidirecțională
### Exemplu: Mențineți contactul principal sincronizat
**Obiectiv**: Când se schimbă contactul principal al unei companii, actualizați contactul. Când o persoană devine principală, actualizați compania.
### Flux de lucru 1: Companie → Persoană
1. **Declanșator**: Înregistrarea este actualizată (Companii, câmp Contact principal)
2. **Actualizați Înregistrarea**: Setați "Is Primary Contact" al persoanei la true
3. **Căutare înregistrări**: Găsiți contactul principal anterior
4. **Actualizați Înregistrarea**: Setați "Is Primary Contact" al contactului anterior la false
### Flux de lucru 2: Persoană → Companie
1. **Declanșator**: Înregistrarea este actualizată (Persoane, Is Primary Contact = true)
2. **Actualizați Înregistrarea**: Setați Contactul principal al companiei la această persoană
<Note>
Aveți grijă cu sincronizările bidirecționale pentru a evita buclele infinite. Folosiți filtre pentru a verifica dacă valoarea chiar s-a schimbat înainte de a actualiza.
</Note>
## Utilizarea codului pentru mapare complexă
### Exemplu: Transformați datele în timpul copierii
**Obiectiv**: Copiați și formatați numărul de telefon de la persoană în oportunitate.
```javascript
export const main = async (params) => {
const { phone } = params;
if (!phone) return { formattedPhone: null };
// Remove non-numeric characters
const digits = phone.replace(/\D/g, '');
// Format as (XXX) XXX-XXXX
const formatted = digits.length === 10
? `(${digits.slice(0,3)}) ${digits.slice(3,6)}-${digits.slice(6)}`
: phone;
return { formattedPhone: formatted };
};
```
## Cele mai bune practici
### Evitați buclele
* Nu creați fluxuri de lucru care se declanșează reciproc la nesfârșit
* Folosiți condiții specifice pe câmpuri
* Adăugați verificări pentru a vedea dacă valoarea chiar s-a schimbat
### Gestionați datele lipsă
* Verificați întotdeauna dacă înregistrarea sursă există înainte de copiere
* Furnizați valori implicite pentru câmpurile opționale
* Folosiți filtre pentru a omite atunci când câmpul sursă este gol
### Performanță
* Grupați actualizările când copiați către multe înregistrări
* Utilizați fluxuri de lucru programate pentru operațiuni de sincronizare în masă
* Luați în considerare utilizarea Iterator pentru actualizări multiple ale înregistrărilor
## Conexe
* [Acțiuni ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-actions)
* [Declanșatoare ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-triggers)

View File

@@ -0,0 +1,202 @@
---
title: Câmpuri de formulă
description: Creează câmpuri de formulă folosind fluxuri de lucru până când va fi disponibil suportul nativ.
---
Douăzeci de domenii nu acceptă încă formulă nativă (vin în 2026), dar puteți obține același rezultat folosind fluxuri de lucru. Această soluție temporară îți permite să calculezi și să completezi automat valorile câmpurilor — de la concatenări simple la logică de business complexă.
## Cazuri de Utilizare Comune
| Caz de utilizare | Exemplu de formulă |
| ------------------------- | ---------------------------------- |
| **Nume complet** | Prenume + " " + Nume |
| **Sumă estimată** | Sumă × Probabilitate |
| **Zile până la scadență** | Data scadenței - Astăzi |
| **Zile în stadiu** | Astăzi - Data intrării în stadiu |
| **Scor lead** | Puncte bazate pe criterii multiple |
<Tip>
Pentru un exemplu complet de urmărire a timpului în stadiile din pipeline, vezi [Urmărește cât timp rămân oportunitățile în fiecare stadiu](/l/ro/user-guide/views-pipelines/how-tos/track-time-in-stage).
</Tip>
## Formulă de bază: Concatenare
### Exemplu: Autocompletare nume complet
**Obiectiv**: Combină automat prenumele și numele într-un câmp de nume complet.
### Configurare
1. **Declanșator**: Înregistrarea este actualizată sau creată (Persoane)
2. **Filtru**: Verifică dacă prenumele sau numele s-a schimbat
3. **Acțiune de cod**:
```javascript
export const main = async (params) => {
const { firstName, lastName } = params;
const fullName = [firstName, lastName]
.filter(Boolean)
.join(' ');
return { fullName };
};
```
4. **Actualizează înregistrarea**: Setează Nume complet la `{{code.fullName}}`
## Formulă numerică: Sumă estimată
### Exemplu: Calculează venitul estimat
**Obiectiv**: Înmulțește suma oportunității cu probabilitatea pentru a obține suma estimată.
Vezi [Cum să afișezi suma estimată în pipeline](/l/ro/user-guide/views-pipelines/how-tos/show-expected-amount-in-pipeline) pentru fluxul de lucru complet.
### Configurare
1. **Declanșator**: Înregistrarea este actualizată (Oportunități, câmpul Sumă SAU Probabilitate)
2. **Acțiune de cod**:
```javascript
export const main = async (params) => {
const { amount, probability } = params;
const expectedAmount = (amount || 0) * (probability || 0) / 100;
return { expectedAmount };
};
```
3. **Actualizează înregistrarea**: Setează Suma estimată la `{{code.expectedAmount}}`
## Formulă de dată: Calculul zilelor
### Exemplu: Zile până la scadența sarcinii
**Obiectiv**: Calculează câte zile rămân până la data scadenței unei sarcini.
### Configurare
1. **Declanșator**: Înregistrarea este actualizată sau creată (Sarcini, câmp Data scadenței)
2. **Acțiune de cod**:
```javascript
export const main = async (params) => {
const { dueDate } = params;
if (!dueDate) {
return { daysUntilDue: null };
}
const due = new Date(dueDate);
const today = new Date();
const diffTime = due - today;
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
return { daysUntilDue: diffDays };
};
```
3. **Actualizează înregistrarea**: Setează Zile până la scadență la `{{code.daysUntilDue}}`
<Note>
Valorile negative indică sarcini întârziate. Poți folosi acest câmp pentru a filtra sau sorta sarcinile după urgență.
</Note>
## Formulă condițională: Scor lead
### Exemplu: Calculează scorul lead pe baza criteriilor
**Obiectiv**: Punctează lead-urile pe baza dimensiunii companiei, industriei și nivelului de implicare.
### Configurare
1. **Declanșator**: Înregistrarea este actualizată (Persoane sau Companii)
2. **Acțiune de cod**:
```javascript
export const main = async (params) => {
const { companySize, industry, hasEmail, hasPhone, source } = params;
let score = 0;
// Company size scoring
if (companySize === 'Enterprise') score += 30;
else if (companySize === 'Mid-Market') score += 20;
else if (companySize === 'SMB') score += 10;
// Industry scoring
const targetIndustries = ['Technology', 'Finance', 'Healthcare'];
if (targetIndustries.includes(industry)) score += 25;
// Contact info scoring
if (hasEmail) score += 10;
if (hasPhone) score += 15;
// Source scoring
if (source === 'Referral') score += 20;
else if (source === 'Website') score += 10;
return { leadScore: score };
};
```
3. **Actualizează înregistrarea**: Setează Scor lead la `{{code.leadScore}}`
## Formulă de text: Extracția domeniului
### Exemplu: Extrage domeniul din e-mail
**Obiectiv**: Extrage și stochează automat domeniul e-mailului.
### Configurare
1. **Declanșator**: Înregistrarea este actualizată (Persoane, câmp E-mail)
2. **Acțiune de cod**:
```javascript
export const main = async (params) => {
const { email } = params;
if (!email) return { domain: null };
const domain = email.split('@')[1]?.toLowerCase();
return { domain };
};
```
3. **Actualizează înregistrarea**: Setează câmpul Domeniu la `{{code.domain}}`
## Cele mai bune practici
### Performanță
* Declanșează doar la modificări relevante ale câmpurilor
* Folosește filtre pentru a omite înregistrările care nu necesită calcul
* Evită calcule complexe în fluxurile de lucru cu volum mare
### Gestionarea erorilor
* Verifică valorile null/undefined înainte de calcule
* Folosește valori implicite când lipsesc datele
* Returnează mesaje de eroare clare când calculele eșuează
### Testare
* Testează cu cazuri-limită (câmpuri goale, valori zero)
* Verifică manual calculele înainte de activare
* Monitorizează rulările fluxurilor de lucru pentru rezultate neașteptate
## Conexe
* [Cum să afișezi suma estimată în pipeline](/l/ro/user-guide/views-pipelines/how-tos/show-expected-amount-in-pipeline)
* [Cum să urmărești timpul în stadiu](/l/ro/user-guide/views-pipelines/how-tos/track-time-in-stage)
* [Acțiuni ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-actions)

View File

@@ -0,0 +1,127 @@
---
title: Notificați colegii despre o notă de revizuit
description: Trimiteți notificări automate prin e-mail când atribuiți unui coleg revizuirea unei note.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
<Note>
**Etichetarea colegilor direct în note nu este încă suportată.** Această funcție este planificată pentru a doua jumătate a anului 2026. Între timp, acest flux de lucru oferă o soluție practică de ocolire.
</Note>
## Provocarea
Doriți să etichetați un coleg într-o notă, astfel încât să primească o notificare pentru a o revizui. În prezent, Twenty nu suportă mențiuni cu @ în note sau sarcini.
## Soluția de ocolire
În loc să etichetați în textul notei, puteți:
1. Creați un câmp de relație **Reviewer** pe obiectul Note
2. Atribuiți recenzentul atunci când creați sau editați nota
3. Faceți un flux de lucru automat trimiteți un e-mail către examinator cu un link către notă
<Warning>
**Limitare**: Această abordare permite atribuirea unui singur recenzent per câmp. Dacă trebuie să notificați mai multe persoane, creați câmpuri de relație suplimentare (de ex., Reviewer 1, Reviewer 2). Aceasta nu scalează bine dacă trebuie să etichetați mulți colaboratori deodată.
</Warning>
## Configurare pas cu pas
### Pasul 1: Creați câmpul Reviewer
<img src="/images/user-guide/workflows/reviewer-field-for-note.png" style={{width:'100%'}} />
1. Accesați **Setări → Model de date → Note**
2. Faceți clic pe **Adaugă câmp**
3. Configurați:
| Setare | Valoare |
| ------------------ | -------------------------------------------- |
| **Name** | Reviewer |
| **Tip** | Relație |
| **Obiect asociat** | Membru al Spațiului de Lucru |
| **Tipul relației** | Multe note → Un membru al spațiului de lucru |
4. Salvați câmpul
### Pasul 2: Creați fluxul de lucru
<VimeoEmbed videoId="1151897168" title="Demonstrație video" />
#### Creați declanșatorul fluxului de lucru
1. Accesați vizualizarea principală și creați un nou flux de lucru
2. Selectați **Record Updated** ca declanșator
3. Alegeți **Note** ca obiect și specificați câmpul Reviewer.
4. Acesta se va declanșa ori de câte ori recenzentul unei note este actualizat.
#### Adăugați un filtru pentru a verifica dacă recenzentul tocmai a fost atribuit
Adăugați o acțiune **Filter** pentru a vă asigura că fluxul de lucru continuă doar atunci când este atribuit un recenzent:
| Condiție | Valoare |
| ------------ | ----------- |
| **Reviewer** | nu este gol |
#### Căutați membrul spațiului de lucru
1. Adăugați o acțiune **Search Records**
2. Selectați **Workspace Member** (sub obiecte avansate)
3. Adăugați un filtru:
| Condiție | Valoare |
| -------- | ----------------------------- |
| **ID** | egal cu `{{note.reviewerId}}` |
Aceasta preia înregistrarea completă a membrului spațiului de lucru, inclusiv adresa de e-mail și numele.
#### Trimiteți e-mailul de notificare
1. Adăugați o acțiune **Send Email**
2. Configurați:
| Câmp | Valoare |
| ----------- | --------------------------------------------------- |
| **Către** | Search Record → First Workspace Member → User Email |
| **Subiect** | O notă are nevoie de revizuirea dvs. |
| **Corp** | Consultați exemplul de mai jos |
**Exemplu de corp al e-mailului:**
```text
Hi {{searchRecord.firstWorkspaceMember.name.firstName}},
You've been assigned to review a note.
View the note here:
https://yourSubDomain.twenty.com/object/note/{{recordIsUpdated.id}}
Best,
Twenty
```
<Note>
Înlocuiți `yourSubDomain` cu subdomeniul real al spațiului dvs. de lucru Twenty.
</Note>
#### Testați și activați
1. Faceți clic pe **Test** pentru a rula manual fluxul de lucru
2. Creați sau editați o notă și atribuiți un recenzent
3. Verificați căsuța de e-mail a recenzentului pentru e-mailul de notificare
4. Activați fluxul de lucru
## Utilizare
După configurare, echipa dvs. poate utiliza acest flux de lucru astfel:
1. Creând o notă nouă (sau editând una existentă)
2. Selectând un coleg în câmpul **Reviewer**
3. Colegul primește automat un e-mail cu un link direct către notă
## Conexe
* [Declanșatoare ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-triggers)
* [Trimiteți e-mailuri din fluxuri de lucru](/l/ro/user-guide/workflows/capabilities/send-emails-from-workflows)
* [Creați câmpuri personalizate](/l/ro/user-guide/data-model/how-tos/create-custom-fields)
* [Creați câmpuri de relație](/l/ro/user-guide/data-model/how-tos/create-relation-fields)

View File

@@ -0,0 +1,106 @@
---
title: Trimiteți alerte prin e-mail pentru sarcini scadente
description: Notificați automat membrii echipei despre sarcinile lor care urmează sau sunt restante.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
<img src="/images/user-guide/workflows/email_tasks_due.png" style={{width:'100%'}} />
Trimiteți mementouri zilnice prin e-mail fiecărui membru al echipei despre sarcinile sale scadente astăzi.
## Prezentare generală
Acest flux de lucru rulează conform unui program și:
1. Preia toți membrii spațiului de lucru
2. Parcurge fiecare membru
3. Găsește sarcinile lor scadente astăzi
4. Formatează și trimite un e-mail personalizat
## Configurare pas cu pas
<VimeoEmbed videoId="1147463514" title="Demonstrație video" />
### Pasul 1: Configurați declanșatorul
1. Accesați **Settings → Workflows** și creați un nou flux de lucru
2. Selectați **On a Schedule** ca declanșator
3. Utilizați o expresie cron pentru rulare zilnică la 8:00 AM: `0 8 * * *`
### Pasul 2: Căutați toți membrii spațiului de lucru
1. Adăugați acțiunea **Search Records**
2. Selectați **Workspace Members** (sub obiecte avansate)
3. Nu sunt necesare filtre — aceasta returnează toți membrii
### Pasul 3: Adăugați un Iterator
1. Adăugați o acțiune **Iterator**
2. Setați array-ul de intrare la membrii spațiului de lucru din pasul anterior
3. Toate acțiunile din interiorul iteratorului vor rula o dată pentru fiecare membru
### Pasul 4: Căutați sarcinile scadente astăzi (în interiorul Iterator)
1. În interiorul iteratorului, adăugați o acțiune **Search Records**
2. Selectați **Tasks** ca obiect
3. Adăugați filtre:
* **Assignee** = membrul curent al spațiului de lucru (din iterator)
* **Due Date** = astăzi
### Pasul 5: Formatați sarcinile în corpul e-mailului (în interiorul Iterator)
Adăugați o acțiune **Code** pentru a formata sarcinile într-o listă lizibilă cu linkuri:
```javascript
export const main = async (params: {
tasksDue?: Array<{ id: string; title: string }> | null | string;
}) => {
const tasksDue =
typeof params.tasksDue === "string"
? JSON.parse(params.tasksDue)
: params.tasksDue;
if (!Array.isArray(tasksDue) || tasksDue.length === 0) {
return {
formattedTasks: "No tasks due today."
};
}
const formattedTasks = tasksDue
.map(
t =>
`${t.title}\nhttps://yourSubDomain.twenty.com/object/task/${t.id}`
)
.join("\n\n");
return { formattedTasks };
};
```
<Note>
Înlocuiți `yourSubDomain` cu subdomeniul real al spațiului dvs. de lucru Twenty.
</Note>
### Pasul 6: Trimiteți e-mail (în interiorul Iterator)
1. Adăugați o acțiune **Send Email** (tot în interiorul iteratorului)
2. Configurați:
| Câmp | Valoare |
| ----------- | ---------------------------------------------------------------------------- |
| **Către** | `{{iterator.currentItem.userEmail}}` (e-mailul membrului spațiului de lucru) |
| **Subiect** | Sarcinile dvs. scadente astăzi |
| **Corp** | `{{code.formattedTasks}}` |
### Pasul 7: Testați și activați
1. Faceți clic pe **Test** pentru a rula manual fluxul de lucru
2. Verificați căsuțele de intrare pentru e-mailuri
3. Activați fluxul de lucru
## Conexe
* [Acțiuni ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-actions)
* [Trimiteți e-mailuri din fluxuri de lucru](/l/ro/user-guide/workflows/capabilities/send-emails-from-workflows)
* [Gestionați array-urile în acțiunile Code](/l/ro/user-guide/workflows/how-tos/advanced-configurations/handle-arrays-in-code-actions)

View File

@@ -0,0 +1,21 @@
---
title: Servicii Profesionale
description: Obține ajutor profesional în dezvoltarea fluxurilor de lucru complexe și a automatizărilor de la echipa Twenty și partenerii certificați.
---
## Când Aveți Nevoie de Ajutor Profesional?
Consultați servicii profesionale pentru:
* Integrări complexe multi-sistem
* Logică avansată de afaceri și reguli de automatizare
* Fluxuri de lucru pentru procesarea datelor la scară largă
* Dezvoltare API personalizată
* Instruirea echipei și optimizarea fluxurilor de lucru
* Când nu aveți resurse interne
## Opțiuni de Servicii
### Parteneri de implementare
Colaborați cu parteneri certificați pentru personalizări avansate. Contactați-ne la [contact@twenty.com](mailto:contact@twenty.com) pentru a ne conecta cu [partenerii noștri de implementare](https://twenty.com/partners).

View File

@@ -0,0 +1,170 @@
---
title: Depanarea fluxului de lucru
description: Probleme frecvente ale fluxurilor de lucru și cum să le rezolvați.
---
## Probleme comune și soluții
### Flux de lucru care nu se declanșează
**Simptome**: Fluxul de lucru nu rulează atunci când vă așteptați.
**Cauze posibile**:
1. **Flux de lucru neactivat**: Asigurați-vă că fluxul de lucru este setat pe "Active", nu pe "Draft"
2. **Condițiile declanșatorului nu sunt îndeplinite**: Verificați că declanșatorul corespunde evenimentului așteptat
3. **Câmp nemonitorizat**: Pentru declanșatoarele "Record is Updated", asigurați-vă că acel câmp specific este urmărit
4. **Permisiuni**: Verificați că aveți permisiunea de a rula fluxuri de lucru
**Soluții**:
* Verificați starea fluxului de lucru în lista fluxurilor de lucru
* Testați cu acțiunea specifică despre care considerați că îl declanșează
* Revizuiți configurarea declanșatorului
* Contactați administratorul dvs. despre permisiuni
### Declanșarea fluxului de lucru prea devreme (câmpuri goale)
**Simptome**: Când creați manual o înregistrare în UI, fluxul de lucru se declanșează înainte de a avea timp să completați toate câmpurile. Fluxul de lucru rulează cu valori ale câmpurilor în mare parte goale.
**De ce se întâmplă asta**: Twenty salvează totul în timp real — nu există moduri separate "edit" vs "read". Când creați o înregistrare, aceasta este salvată imediat, declanșând evenimentul "Record is created" înainte să puteți completa câmpuri suplimentare.
**Când "Record is created" funcționează bine**:
* Înregistrări create prin apeluri API (câmpurile sunt populate într-o singură cerere)
* Înregistrări create prin import
* Crearea automată de înregistrări din alte fluxuri de lucru
**Soluție**: Pentru înregistrările create manual în UI, folosiți **"Record is created or updated"** ca declanșator. Astfel:
* Fluxul de lucru se declanșează după ce utilizatorul a terminat de completat și salvat câmpurile
* Obțineți date complete în loc de valori goale
<Tip>
Dacă doriți ca fluxul de lucru să ruleze doar o singură dată per înregistrare, adăugați o acțiune Filter pentru a verifica un câmp precum `createdAt equals updatedAt` (prima salvare) sau folosiți un câmp checkbox personalizat pentru a urmări dacă fluxul de lucru a rulat deja.
</Tip>
### Acțiuni eșuate
**Simptome**: Fluxul de lucru rulează, dar unele acțiuni eșuează.
**Cauze posibile**:
1. **Date lipsă**: Câmpurile obligatorii sunt goale
2. **Referințe nevalide**: Variabilele din pașii anteriori nu există
3. **Erori API**: Serviciile externe returnează erori
4. **Probleme de permisiuni**: Acțiunea necesită permisiuni pe care nu le aveți
**Soluții**:
* Verificați detaliile rulării fluxului de lucru pentru mesaje de eroare
* Verificați că toate câmpurile obligatorii au valori
* Testați conexiunile API independent
* Revizuiți permisiunile rolurilor
### Erori ale cererilor HTTP
**Simptome**: Acțiunile HTTP Request eșuează sau returnează rezultate neașteptate.
**Coduri de eroare comune**:
* **400**: Cerere incorectă - verificați formatul corpului cererii
* **401**: Neautorizat - verificați cheia API
* **403**: Interzis - verificați permisiunile API
* **404**: Nu a fost găsit - verificați URL-ul punctului final
* **429**: Prea multe cereri - implementați limitarea ratei
* **500**: Eroare de server - problemă a serviciului extern
**Soluții**:
* Verificați URL-ul punctului final API
* Verificați antetele de autentificare
* Testați mai întâi apelul API în afara Twenty
* Adăugați tratare a erorilor în acțiunile Code
### Erori în acțiunile Code
**Simptome**: Codul JavaScript nu reușește să se execute.
**Probleme comune**:
1. **Erori de sintaxă**: Greșeli de tastare sau JavaScript invalid
2. **Variabile nedefinite**: Referire la variabile care nu există
3. **Erori de tip**: Operații pe tipuri de date greșite
4. **Depășiri de timp**: Codul durează prea mult să se execute
**Soluții**:
* Utilizați validarea integrată a editorului de cod
* Testați mai întâi logica codului într-o consolă JavaScript
* Adăugați instrucțiuni console.log pentru depanare
* Simplificați operațiunile complexe
### Emailul nu se trimite
**Simptome**: Acțiunea Send Email nu livrează emailuri.
**Cauze posibile**:
1. **Niciun cont de email conectat**: Verificați Settings → Accounts
2. **Adresă de email invalidă**: Emailul destinatarului are un format incorect
3. **Limite de trimitere**: S-au atins limitele de rată ale furnizorului de email
4. **Filtre de spam**: Emailurile sunt blocate
**Soluții**:
* Verificați conexiunea contului de email
* Validați adresele de email ale destinatarilor
* Verificați limitele furnizorului de email
* Revizuiți conținutul emailului pentru posibile declanșatoare de spam
## Depanarea fluxurilor de lucru
### Utilizarea rulărilor fluxurilor de lucru
1. Accesați editorul de fluxuri de lucru
2. Deschideți panoul **Runs**
3. Găsiți rularea eșuată
4. Faceți clic pentru a vedea detalii pas cu pas
5. Revizuiți mesajele de eroare și datele de ieșire
### Testarea pașilor individuali
1. Pentru acțiunile Code, folosiți butonul **Test**
2. Pentru cererile HTTP, testați endpoint-ul separat
3. Creați înregistrări de test pentru a declanșa fluxuri de lucru
4. Folosiți declanșatoare manuale pentru testare controlată
### Tipare comune de depanare
**Adăugați jurnalizare**:
Folosiți acțiuni Code pentru a înregistra valori intermediare pentru depanare.
**Izolați pașii**:
Testați fiecare pas independent pentru a identifica eșecurile.
**Verificați fluxul de date**:
Verificați că fiecare pas primește datele de intrare așteptate.
## Cele mai bune practici pentru a evita problemele
### Înainte de activare
* Testați temeinic în modul draft
* Validați toate conexiunile API
* Revizuiți cu atenție condițiile declanșatorului
* Documentați comportamentul așteptat
### În timpul dezvoltării
* Folosiți nume descriptive pentru pași
* Adăugați comentarii în acțiunile Code
* Testați cu date realiste
* Planificați pentru cazuri limită
### După activare
* Monitorizați îndeaproape rulările inițiale
* Configurați alerte pentru eșecuri
* Revizuiți în mod regulat istoricul rulărilor
* Mențineți fluxurile de lucru simple atunci când este posibil

View File

@@ -0,0 +1,236 @@
---
title: Întrebări frecvente despre fluxuri de lucru
description: Întrebări frecvente despre fluxurile de lucru din Twenty.
---
<AccordionGroup>
<Accordion title="De ce nu pot activa un flux de lucru?">
Este probabil o problemă de permisiuni. Aveți nevoie de acces la fluxuri de lucru pentru a le crea și activa.
**Soluție**: Contactați administratorul spațiului de lucru pentru a vă acorda acces la fluxuri de lucru în **Setări → Membri → Roluri**.
Dacă nu vedeți deloc secțiunea Fluxuri de lucru în bara laterală, acest lucru confirmă că este o problemă de permisiuni.
</Accordion>
<Accordion title="De ce nu văd butonul fluxului de lucru manual în bara de navigare de sus?">
Fluxurile de lucru manuale apar în bara de navigare doar dacă sunt configurate corect:
1. Fluxul de lucru trebuie să fie **activat** (nu în modul de schiță)
2. Poziționarea în bara de navigare trebuie setată la **Pinned**
3. Pentru declanșatoarele Single/Bulk, trebuie să vă aflați pe pagina obiectului corect
**Pentru a verifica**: Deschideți fluxul de lucru → faceți clic pe declanșator → verificați că "Navbar placement" este setat la "Pinned".
Puteți accesa oricând fluxurile de lucru manuale prin **Cmd + K** (sau **Ctrl + K**), indiferent de setările barei de navigare.
</Accordion>
<Accordion title="Care este diferența dintre declanșatoarele manuale Single, Global și Bulk?">
| Tip | Înregistrări necesare | Rulările fluxului de lucru |
| --- | --------------------- | -------------------------- |
\| **Global** | Niciuna | O dată, fără input de înregistrare |
\| **Single** | Una sau mai multe selectate | O dată pentru fiecare înregistrare selectată |
\| **Bulk** | Una sau mai multe selectate | O dată, cu toate înregistrările ca un array |
* **Global**: Utilizați când fluxul de lucru nu are nevoie de context de înregistrare (de ex., generarea unui raport)
* **Single**: Utilizați când doriți să procesați fiecare înregistrare selectată independent (de ex., trimiteți e-mailuri individuale)
* **Bulk**: Utilizați când aveți nevoie să procesați înregistrările împreună sau să optimizați utilizarea creditelor (necesită acțiunea Iterator)
Consultați [Declanșatoare ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-triggers) pentru detalii.
</Accordion>
<Accordion title="Nu văd un nod If/Else. Ce ar trebui să fac?">
Un nod If/Else explicit nu este încă disponibil, dar se află pe foaia noastră de parcurs.
**Soluție temporară**: Creați mai multe ramuri din pasul dvs., fiecare începând cu o acțiune **Filter**:
```
Step 1
│
├── Branch A: Filter (condition = true) → Actions...
│
└── Branch B: Filter (condition = false) → Actions...
```
Doar ramura în care condiția filtrului este îndeplinită își va executa acțiunile următoare.
Consultați [Cum să utilizați ramurile](/l/ro/user-guide/workflows/capabilities/workflow-branches) pentru un ghid pas cu pas.
</Accordion>
<Accordion title="Rulează ramurile fluxului de lucru în paralel?">
**Da**, ramurile rulează în paralel în mod implicit.
Dacă doriți ca doar o singură ramură să se execute:
* Adăugați o acțiune **Filter** la începutul fiecărei ramuri
* Setați condiții opuse (de ex., Ramura A: status = "Open", Ramura B: status ≠ "Open")
Ramurile care nu îndeplinesc condiția filtrului se opresc din execuție, în timp ce altele continuă.
</Accordion>
<Accordion title="Pot să îmbin din nou ramurile?">
**Da**. După ce ramurile paralele se finalizează, puteți adăuga un pas la care se conectează ambele ramuri.
În editorul de fluxuri de lucru:
1. Finalizați acțiunile din ramuri
2. Adăugați un pas nou după ramuri
3. Trageți conexiuni de la finalul fiecărei ramuri către acest pas nou
Pasul îmbinat se va executa după ce toate ramurile conectate se finalizează.
</Accordion>
<Accordion title="Care este limita rezultatelor pentru Search Records?">
**Search Records returnează maximum 200 de înregistrări.**
Dacă aveți nevoie să procesați mai multe:
* Adăugați filtre mai specifice pentru a reduce rezultatele
* Utilizați fluxuri de lucru programate pentru a procesa în loturi
* Luați în considerare utilizarea API-ului pentru operațiuni în masă
Pentru majoritatea fluxurilor de lucru, 200 de înregistrări sunt suficiente. Dacă atingeți frecvent această limită, luați în considerare restructurarea automatizării.
</Accordion>
<Accordion title="Pot adăuga persoane în CC în e-mailurile fluxurilor de lucru?">
**Încă nu.** Câmpurile CC și BCC pentru acțiunea Send Email se află pe foaia noastră de parcurs.
**Soluție temporară**: Adăugați mai multe acțiuni Send Email pentru a trimite către destinatari suplimentari sau utilizați un HTTP Request pentru a trimite printr-un serviciu extern de e-mail care acceptă CC.
</Accordion>
<Accordion title="Cum folosesc rezultatele din pașii anteriori?">
Fiecare acțiune produce date de ieșire care pot fi utilizate în pașii următori.
**Pentru a face referire la datele din pașii anteriori**:
* Utilizați selectorul de variabile când configurați un câmp
* Sau tastați direct `{{stepName.fieldName}}`
**Exemple**:
* Datele declanșatorului: `{{trigger.object.email}}`
* Rezultatele căutării: `{{searchRecords[0].name}}`
* Rezultatul codului: `{{code.calculatedValue}}`
Treceți cursorul peste orice câmp din configurația acțiunii pentru a vedea variabilele disponibile din pașii anteriori.
</Accordion>
<Accordion title="De ce eșuează Iteratorul?">
**Iterator necesită un input de tip array.** Probleme frecvente:
1. **Inputul nu este un array**: Asigurați-vă că transmiteți rezultate din Search Records sau dintr-o altă acțiune care returnează un array
2. **Array-ul este gol**: Adăugați un filtru înainte de Iterator pentru a verifica `{{searchRecords.length}} > 0`
3. **Variabilă selectată greșit**: Asigurați-vă că selectați array-ul în sine, nu o singură înregistrare
**Configurare corectă**:
1. Search Records (returnează un array)
2. Filter: length > 0
3. Iterator: selectați `{{searchRecords}}`
4. Acțiunile din interiorul iteratorului folosesc `{{iterator.currentItem.fieldName}}`
</Accordion>
<Accordion title="Care este timpul maxim de execuție pentru acțiunile Code?">
Acțiunile Code (funcții logice) au un **timeout implicit de 5 minute** (300 de secunde).
Timeoutul maxim configurabil este de **15 minute** (900 de secunde).
Dacă codul depășește această limită, acțiunea va eșua cu o eroare de timeout.
**Sfaturi pentru a evita timeout-urile**:
* Împărțiți operațiunile mari în bucăți mai mici folosind Iterator
* Evitați calculele grele; utilizați servicii externe prin HTTP Request pentru procesări intensive
* Optimizați codul pentru a reduce timpul de execuție
* Dacă aveți nevoie de procesare mai lungă, luați în considerare utilizarea fluxurilor de lucru programate care procesează datele în loturi
</Accordion>
<Accordion title="Cum citesc rulările fluxului de lucru?">
Rulările fluxului de lucru afișează istoricul execuției și vă ajută să depanați problemele.
**Accesarea rulărilor**:
* În editorul de fluxuri de lucru → panoul **Runs** din dreapta
* Sau accesați **Rulări ale fluxurilor de lucru** în bara laterală
**Înțelegerea unei rulări**:
* **Status**: Running, Completed, Failed, Waiting
* **Pași**: Vedeți ce pași au fost executați și rezultatul lor
* **Erori**: Faceți clic pe pașii eșuați pentru a vedea mesajele de eroare
* **Date**: Vizualizați datele de intrare/ieșire la fiecare pas
Consultați [Rulări ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-runs) pentru detalii.
</Accordion>
<Accordion title="De ce nu văd rulările fluxului meu de lucru?">
Rulările fluxului de lucru ar putea eșua imediat din cauza limitelor de rată. Douăzeci de ani implementează o limită dură de 5 000 de curse pe oră pe spațiu de lucru.
Dacă depășiți această limită, fluxurile de lucru sunt imediat marcate ca eșuate și nu vor apărea în lista de execuții.
**Scenarii comune care ating această limită**:
* Selectarea a mai mult de 5.000 de înregistrări cu un declanșator manual Single
* Mai multe fluxuri de lucru care rulează simultan în spațiul dvs. de lucru
* Declanșatoare automate cu frecvență ridicată (de ex., Record Updated pe un obiect aglomerat)
**Soluții**:
* Utilizați declanșatoare **Bulk** în loc de Single pentru a procesa multe înregistrări într-o singură rulare
* Eșalonați în timp operațiunile mari efectuate în loturi
* Folosiți filtre pentru a reduce frecvența declanșărilor
* Programați fluxurile de lucru intensive în afara orelor de vârf
</Accordion>
<Accordion title="Care sunt limitele de rată pentru fluxurile de lucru?">
Twenty are două limite de rată pentru a asigura stabilitatea sistemului:
| Limită | Valoare | Comportament |
| ------ | ------- | ------------ |
\| **Limită soft** | 100 rulări/minut | Rulările se pun în coadă cu statusul "Not Started", procesate treptat |
\| **Limită hard** | 5.000 rulări/oră | Rulările eșuează imediat |
**Limită soft (100/min)**: Fluxurile dvs. de lucru nu vor eșua — doar așteaptă în coadă și sunt procesate în timp. Puteți declanșa mai mult de 100 de înregistrări; execuția va fi mai lentă.
**Limită hard (5.000/oră)**: Se aplică întregului dvs. spațiu de lucru. Dacă toate fluxurile dvs. de lucru cumulate depășesc 5.000 de rulări într-o oră, rulările suplimentare vor eșua imediat.
**Sfaturi pentru a rămâne în limite**:
* Utilizați declanșatoare Bulk cu Iterator în locul declanșatoarelor Single pentru loturi mari
* Combinați automatizările înrudite în mai puține fluxuri de lucru
* Utilizați fluxuri de lucru programate pentru a distribui încărcarea în timp
</Accordion>
<Accordion title="Pot reîncerca o rulare de flux de lucru eșuată?">
**Nu, momentan nu există o funcționalitate de reîncercare automată.**
Dacă o rulare de flux de lucru eșuează, va trebui să:
1. Examinați eroarea în **Setări → Workflows → [Workflow-ul dvs.] → Runs**
2. Remediați problema (date, configurație sau serviciu extern)
3. Declanșați manual din nou fluxul de lucru pe înregistrarea/înregistrările afectate
**Sfaturi pentru a reduce eșecurile**:
* Adăugați noduri **Filter** pentru a valida datele înaintea acțiunilor
* Utilizați **Search Records** pentru a verifica dacă există înregistrări asociate
* Testați temeinic cu câteva înregistrări înainte de operațiuni în masă
Funcționalitatea de reîncercare automată este pe foaia noastră de parcurs pentru o versiune viitoare.
</Accordion>
<Accordion title="Ar trebui să dezactivez fluxurile de lucru înainte de importurile CSV?">
**Da, dacă fluxurile dvs. de lucru sunt declanșate de crearea sau actualizarea înregistrărilor.**
Când importați date prin CSV, fiecare înregistrare creată sau actualizată poate declanșa fluxuri de lucru. Un import mare (mii de înregistrări) ar putea:
* Atinge limita de 5.000 de rulări/oră
* Consumă un număr semnificativ de credite de flux de lucru
* Trimite e-mailuri sau notificări neașteptate
* Creează sarcini sau înregistrări duplicate
**Înaintea unui import în masă**:
1. Accesați **Setări → Fluxuri de lucru**
2. Identificați fluxurile de lucru declanșate de obiectul pe care îl importați
3. **Dezactivați**-le temporar
4. Rulați importul CSV
5. **Reactivați** fluxurile de lucru când ați terminat
**Alternativă**: Dacă aveți nevoie ca fluxurile de lucru să ruleze pe datele importate, importați în loturi mai mici pentru a rămâne în limitele de rată.
</Accordion>
<Accordion title="Cum îmi curăț aspectul fluxului de lucru?">
Dacă planșa fluxului de lucru arată dezordonată, cu noduri împrăștiate, o puteți organiza automat:
1. Faceți clic dreapta oriunde pe planșa fluxului de lucru
2. Faceți clic pe **Aranjează fluxul de lucru**
Acest lucru va rearanja automat toate nodurile într-un aspect curat și organizat.
</Accordion>
</AccordionGroup>

View File

@@ -0,0 +1,81 @@
---
title: Fluxuri de lucru
description: Aflați cum să creați automatizări în Twenty.
---
## De ce Contează Fluxurile de Lucru
Twenty a fost construit pentru a oferi utilizatorilor săi flexibilitate maximă. În loc să vă forțeze să adaptați procesele de afaceri la funcții rigide și predefinite, fluxurile de lucru vă permit să creați automatizări care să susțină cel mai bine cazurile de utilizare unice ale afacerii dvs.
Fluxurile de lucru sunt funcția in-app a Twenty pentru crearea acestor automatizări. Ele vă oferă blocurile de construcție pentru a crea exact ceea ce are nevoie afacerea dvs., când are nevoie.
## Ce pot face cu fluxurile de lucru?
Recomandăm construirea automatizărilor pentru două scopuri principale:
1. **Automatizări interne pentru a facilita activitatea zilnică a echipei dvs.**: Reduceți numărul de intrări manuale și sarcini repetitive care încetinesc echipa dvs.
2. **Aduceți date în și în afara Twenty**: Conectați Twenty prin apeluri API și webhooks la baza dvs. de date și alte instrumente.
## Crearea primului dvs. flux de lucru
### Pasul 1: Creați un flux de lucru nou
1. Accesați **Workflows**, accesibil sub celelalte obiecte
2. Faceți clic pe **+ Înregistrare nouă**
3. Dați un nume fluxului de lucru
### Pasul 2: Adăugați un declanșator
Fiecare flux de lucru începe cu un declanșator. Alegeți dintre:
* **Evenimente ale înregistrărilor**: Când o înregistrare este creată, actualizată sau ștearsă
* **Programare**: Rulează la momente specifice (zilnic, săptămânal etc.)
* **Manual**: Declanșat de o acțiune a utilizatorului
* **Webhook**: Declanșat de un webhook
<img src="/images/user-guide/workflows/workflow_triggers.png" style={{width:'100%'}} />
### Pasul 3: Adăugați acțiuni
După declanșator, adăugați una sau mai multe acțiuni:
* **Creare înregistrare**: Adăugați înregistrări noi în orice obiect
* **Actualizare înregistrare**: Modificați datele înregistrării existente
* **Ștergere înregistrare**: Eliminați înregistrări din obiecte
* **Căutare înregistrări**: Găsiți înregistrări care corespund criteriilor
* **Upsert înregistrare**: Creați sau actualizați pe baza criteriilor de potrivire
* **Iterator**: Parcurgeți tablouri de înregistrări
* **Filtru**: Controlați care înregistrări continuă
* **Întârziere**: Așteptați înainte de a continua (durată sau dată programată)
* **Trimitere e-mail**: Trimiteți e-mailuri prin contul conectat
* **Cod**: Rulați JavaScript personalizat
* **Solicitare HTTP**: Apelați API-uri externe
* **Formular**: Obțineți date de intrare de la utilizatori în interfața Twenty în momentul execuției
* **Agent AI** (În curând): Rulați sarcini AI inteligente
<img src="/images/user-guide/workflows/workflow_actions.png" style={{width:'100%'}} />
### Pasul 4: Testați și activați
1. Utilizați butonul **Test** pentru a rula fluxul de lucru cu date de probă
2. Examinați rezultatele pentru a vă asigura că funcționează conform așteptărilor
3. Comutați fluxul de lucru pe **Activ** când este gata
## Cele mai bune practici ale fluxurilor de lucru
* **Editați numele pașilor**: Redenumiți pașii fluxului dvs. de lucru pentru a descrie clar ce face fiecare. Acest lucru ajută la întreținere și facilitează transmiterea către colegi
* **Folosiți datele pașilor anteriori**: Puteți utiliza câmpuri din înregistrările returnate de orice pas anterior din fluxul dvs. de lucru
* **Începeți simplu**: Începeți cu fluxuri de lucru de bază și adăugați complexitate în timp, pe măsură ce deveniți mai familiar cu sistemul
* **Planificați înainte de a construi**: Configurați logica fluxului de lucru înainte de a începe construcția pentru a evita blocarea la jumătatea procesului
## Pașii următori
* [Declanșatoare ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-triggers)
* [Acțiuni ale fluxurilor de lucru](/l/ro/user-guide/workflows/capabilities/workflow-actions)
* [Automatizări CRM](/l/ro/user-guide/workflows/how-tos/crm-automations/closed-won-automations)
## Ai nevoie de ajutor?
<Tip>
Vrei ajutor să îți automatizezi fluxurile de lucru? [Găsește un partener certificat de douăzeci de parteneri](https://twenty.com/partners/list?categories=SOLUTIONING\&ref=docs-workflows) pentru a proiecta și construi automatiile tale în sfârșit.
</Tip>