Flussi: trigger e step di automazione

Crea sequenze email automatizzate che reagiscono a eventi su contatti ed email

Un flusso iscrive automaticamente i contatti e li fa passare attraverso una sequenza di step — invia un'email, attendi, dividi in base a una condizione, aggiorna il contatto, chiama un webhook — in base a un trigger che definisci. I flussi vivono all'interno di un tenant, girano interamente lato server e non richiedono polling: iscrizione e ogni step sono guidati da eventi.

Questa pagina documenta il motore dei flussi così come si comporta davvero in produzione, inclusi quali tipi di trigger sono collegati oggi e quali sono riservati a una release futura. Configurare un flusso su un trigger non ancora attivo non genera errori — semplicemente non iscriverà mai nessuno, in silenzio. Vedi Tipi di Trigger qui sotto.

Come Funziona

Un flusso ha tre parti: un trigger (cosa avvia l'iscrizione), un array di step (cosa succede a un contatto iscritto, in ordine) e uno status (draft, active, inactive).

Succede qualcosa (es. un tag viene aggiunto a un contatto)

Ogni flusso active il cui trigger corrisponde viene trovato

Il contatto viene iscritto (idempotente — lo stesso evento non iscrive mai due volte)

Lo step 0 viene eseguito

Lo step 1 viene eseguito (subito, o dopo il ritardo di uno step wait)

...

L'iscrizione si completa

Sotto il cofano, sono due Cloud Function che comunicano tramite Pub/Sub e Cloud Tasks:

  1. Valutazione del trigger — qualsiasi azione che fa scattare un trigger (es. un cambio di tag) pubblica un messaggio. Una funzione interroga ogni flusso active il cui trigger.type corrisponde, controlla la config del trigger contro l'evento, e crea un'iscrizione per ogni corrispondenza. Gli ID di iscrizione sono deterministici (un hash di tenant + flusso + contatto + contesto del trigger), quindi lo stesso evento non può mai iscrivere due volte lo stesso contatto.
  2. Esecuzione degli step — ogni step gira come un proprio Cloud Task. Uno step wait non tiene aperta una funzione; pianifica il task dello step successivo con un ritardo e ritorna subito. Questo significa che un flusso con un'attesa di 14 giorni non costa nulla mentre attende, e sopravvive a deploy, riavvii, tutto.

Un contatto viene saltato (non fallito) se il suo status è unsubscribed, bounced, o complained al momento dell'invio — controllato di nuovo a ogni step send_email, non solo all'iscrizione.

Tipi di Trigger

TriggerStatoIscrive quando
contact_tag_addedDisponibileUn tag specifico viene aggiunto a un contatto
contact_tag_removedDisponibileUn tag specifico viene rimosso da un contatto
contact_joins_audienceRiservato(lo schema esiste; nulla pubblica ancora questo evento)
email_eventRiservato(lo schema esiste; nulla pubblica ancora questo evento)
manualRiservato(lo schema esiste; non esiste ancora un endpoint di iscrizione)

Solo contact_tag_added e contact_tag_removed iscrivono davvero i contatti oggi. Gli altri tre tipi di trigger sono valori validi che l'API accetta — un flusso che li usa si salva senza problemi, si attiva senza problemi, mostra 0 iscrizioni per sempre, e non ti dice mai perché. Se ti serve "iscrivi quando succede X" e X non è un cambio di tag, fai tu stesso il tagging: aggiorna i tag del contatto tramite PATCH /v1/contacts/:id dal tuo codice nel momento in cui l'evento reale accade, e fai scattare il trigger su quel tag.

Configurazione del trigger

La config del trigger è un oggetto piatto { chiave: valore }, solo valori stringa. Una chiave di config vuota o assente significa "corrispondi a qualsiasi cosa", non "non corrispondere a nulla" — omettila deliberatamente.

Tipo di triggerChiave configComportamento se impostataComportamento se omessa
contact_tag_added / contact_tag_removedtagNameIscrive solo per quel tag esattoIscrive su qualsiasi cambio di tag — quasi mai quello che vuoi
contact_joins_audienceaudienceIdLimita a un'audienceCorrisponde a qualsiasi ingresso in audience
email_eventeventType, emailIdLimita a un tipo di evento e/o una email specificaCorrisponde in modo ampio
{
  "type": "contact_tag_added",
  "config": { "tagName": "waitlist-confirmed" }
}

Crea un Flusso

Creare è in due step: l'API permette solo di dare un nome al flusso in creazione — trigger e step si impostano dopo con PATCH. Rispecchia il builder della dashboard, che crea una bozza vuota nel momento in cui clicchi "Nuovo flow" e ti lascia collegare tutto sul canvas.

1. Crea

curl -X POST https://api.tratto.email/v1/flows \
  -H "Authorization: Bearer tratto_live_..." \
  -H "Content-Type: application/json" \
  -d '{"name": "Nurturing waitlist"}'
{ "data": { "id": "flow_8f3ZqXnryVtC5k2Wm7B9e4" } }

2. Configura trigger + step

curl -X PATCH https://api.tratto.email/v1/flows/flow_8f3ZqXnryVtC5k2Wm7B9e4 \
  -H "Authorization: Bearer tratto_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "trigger": {
      "type": "contact_tag_added",
      "config": { "tagName": "waitlist-confirmed" }
    },
    "steps": [
      { "id": "s0", "type": "send_email", "config": { "templateId": "tmpl_welcome", "subject": "Sei dentro", "from": "[email protected]", "fromName": "La tua azienda" } },
      { "id": "s1", "type": "wait", "config": { "delay": "2", "unit": "hours" } },
      { "id": "s2", "type": "send_email", "config": { "templateId": "tmpl_nurture_1", "subject": "Cosa stiamo costruendo", "from": "[email protected]", "fromName": "La tua azienda" } }
    ]
  }'

Un flusso viene creato in draft e ci resta — senza iscrivere nessuno — finché non lo attivi. Massimo 20 step per flusso. Gli id degli step sono stringhe a tua scelta; devono solo essere univoci all'interno del flusso.

Tipi di Step

Il config di ogni step è { chiave: stringa }, come i trigger — l'API non converte i tipi, quindi numeri e booleani entrano come stringhe.

send_email

Chiave configObbligatoriaNote
templateIdSì, per renderizzare qualcosaID di un template — vedi Template
subjectConsigliataSe omessa, resta vuota
fromConsigliataSe omessa, resta vuota — i destinatari vedranno un mittente vuoto
fromNameNoNome visualizzato abbinato a from
{ "id": "s0", "type": "send_email", "config": { "templateId": "tmpl_abc123", "subject": "Benvenuto", "from": "[email protected]", "fromName": "La tua azienda" } }

Variabili disponibili nel template: email, firstName, lastName del contatto, e ogni chiave nei customFields del contatto vengono passate automaticamente come {{token}} — non serve dichiararle sullo step. Se un contatto ha customFields: { "position": "42" }, un template contenente {{position}} renderizza 42 per quell'invio, senza configurazione aggiuntiva.

wait

Chiave configObbligatoriaNote
delayUn intero positivo, come stringa, es. "2"
unitNo, default minutesUno tra seconds, minutes, hours, days
{ "id": "s1", "type": "wait", "config": { "delay": "14", "unit": "days" } }

Il puntatore di step dell'iscrizione avanza subito; è il task dello step successivo a essere ritardato. Controllare un'iscrizione a metà attesa mostra correttamente che è già sullo step successivo, solo non ancora dovuto.

branch

Valuta una condizione sui campi del contatto stesso (non customFields — campi di primo livello come status) e salta a un indice di step diverso in base al risultato.

Chiave configObbligatoriaNote
conditionFieldNome di un campo sul documento del contatto
conditionOperatorNo, default equalsequals, not_equals, exists, not_exists, contains
conditionValuePer equals/not_equals/containsValore da confrontare
trueNextStepNo, default lo step successivoIndice di step a cui saltare se la condizione è vera
falseNextStepNo, default termina il flussoIndice di step a cui saltare se la condizione è falsa
{
  "id": "s2",
  "type": "branch",
  "config": {
    "conditionField": "status",
    "conditionOperator": "equals",
    "conditionValue": "subscribed",
    "trueNextStep": "3",
    "falseNextStep": "5"
  }
}

trueNextStep/falseNextStep sono indici nell'array steps (come stringhe), non ID di step — pianifica l'ordine dell'array prima di collegare i branch.

Lo step branch del builder nella dashboard espone al momento una coppia campo/valore semplificata che non corrisponde alle chiavi di config qui sopra. Configura gli step branch via API finché il builder non viene aggiornato.

update_contact

Chiave configObbligatoriaNote
actionNo, default set_fieldset_field, add_tag, remove_tag
field, valuePer set_fieldImposta un campo arbitrario sul contatto
tagPer add_tag/remove_tagNome del tag da aggiungere o rimuovere
{ "id": "s3", "type": "update_contact", "config": { "action": "add_tag", "tag": "nurtured" } }

webhook_call

Notifica un URL esterno. Il corpo della richiesta è fisso — { "tenantId", "enrollmentId", "stepId" } — non è un template che compili tu.

Chiave configObbligatoriaNote
urlDeve essere http/https e un indirizzo pubblico — IP privati/riservati (127.0.0.1, 10.x, 192.168.x, ecc.) sono rifiutati
methodNo, default POSTQualsiasi metodo HTTP
secretNoSe impostato, firma la richiesta con X-Tratto-Signature (HMAC-SHA256) — stesso schema dei webhook normali
{ "id": "s4", "type": "webhook_call", "config": { "url": "https://tuaapi.com/hooks/flow-completed", "secret": "whsec_..." } }

Timeout di 10 secondi; i fallimenti vengono loggati ma non fermano il flusso.

Attivare, Disattivare, Modificare

# Attiva — inizia a iscrivere
curl -X POST https://api.tratto.email/v1/flows/flow_abc123/activate \
  -H "Authorization: Bearer tratto_live_..."

# Disattiva — ferma le nuove iscrizioni, quelle in corso continuano
curl -X POST https://api.tratto.email/v1/flows/flow_abc123/deactivate \
  -H "Authorization: Bearer tratto_live_..."

Non puoi fare PATCH degli steps di un flusso active — disattiva prima, modifica, riattiva. trigger e name si possono ancora cambiare mentre è attivo.

Elenca, Recupera, Elimina

curl https://api.tratto.email/v1/flows \
  -H "Authorization: Bearer tratto_live_..."

curl https://api.tratto.email/v1/flows/flow_abc123 \
  -H "Authorization: Bearer tratto_live_..."

curl -X DELETE https://api.tratto.email/v1/flows/flow_abc123 \
  -H "Authorization: Bearer tratto_live_..."

Eliminare un flusso active è bloccato allo stesso modo in cui lo è modificarne gli step — disattiva prima.

Testare un Flusso

Non esiste oggi una scorciatoia di iscrizione manuale via API (vedi Tipi di Trigger). Per testare un flusso contact_tag_added/contact_tag_removed end to end:

  1. Attiva il flusso.
  2. Crea o riusa un contatto di test.
  3. Aggiungi il tag esatto per cui il trigger è configurato, via PATCH /v1/contacts/:id.
  4. Controlla GET /v1/flows/flow_abc123enrollments dovrebbe incrementare, e il contatto di test dovrebbe ricevere il primo step send_email entro pochi secondi.

Perché Costruire un Flusso

Qualsiasi cosa del tipo "quando succede X a un contatto, fai Y nel tempo" — senza dover scrivere e ospitare tu la logica di scheduling.

Nurturing di iscrizione / waitlist. Tagga un contatto waitlist-confirmed nel momento in cui completa il double opt-in, e lascia che un flusso mandi subito un'email di benvenuto, poi un breve drip (cosa stai costruendo, perché è prezzato in un certo modo, un'anteprima prodotto, un'offerta early-access) distanziato di giorni o settimane — è esattamente lo schema su cui gira la waitlist di Tratto stessa.

Re-engagement / win-back. Esegui un tuo controllo di inattività (ultima apertura email, ultimo login, qualsiasi segnale che dica "sparito") su uno schedule, tagga i contatti corrispondenti inactive-30d, e lascia che un flusso mandi una sequenza di recupero — un primo tocco, poi uno sconto o un aggiornamento prodotto, poi una notifica finale "smetteremo di scriverti" abbinata a uno step update_contact che li disiscrive se ancora non hanno interagito.

Checklist di onboarding. Tagga un contatto quando si iscrive al tuo prodotto; fai un drip di qualche giorno con "hai già provato X", ognuna che punta a una feature diversa, con step wait che danno il tempo di andare davvero a provarla prima del prossimo sollecito.

Passaggio alle vendite su alto intento. Tagga un contatto pricing-page-viewed-3x (dal tuo tracking) e usa uno step webhook_call per avvisare un canale Slack o il CRM nel momento in cui succede — il flusso diventa il trigger per un processo umano, non solo altra email.

Igiene dei dati. Tagga i contatti che entrano in uno stato specifico (trial-expired, payment-failed) e usa step update_contact per normalizzare un campo lifecycle_stage, così la segmentazione altrove nel prodotto (audience, campagne) resta coerente senza un passaggio di pulizia manuale.

Best Practice

Progetta intorno all'unico trigger davvero attivo. Finché contact_joins_audience/email_event/manual non sono collegati, ogni flusso parte di fatto da un cambio di tag. Prendi l'abitudine di taggare i contatti dal tuo codice applicativo nei momenti che contano — è quello il vero punto di ingresso.

Imposta tagName esplicitamente. Un trigger su tag vuoto corrisponde a ogni cambio di tag su ogni contatto. Compilalo sempre.

Dai ai flussi nomi che descrivono cosa fanno, non cosa sono. Follow-up post-acquisto 7 giorni, non Flusso 3.

Disattiva prima di modificare gli step. Non puoi evitarlo — lo impone l'API — quindi prendi l'abitudine presto invece di trovarti l'errore a metà modifica.

Distanzia gli invii con criterio. Gli step wait sono gratuiti e asincroni — non c'è pressione di costo per comprimere una sequenza. Dai ai contatti il tempo di leggere e agire su un'email prima che arrivi la successiva.


Prossimi Passi

  • Tracciare le email inviate dai flussi? Configura i Webhook
  • Inviare via API direttamente? Vedi Invia Email
  • Costruire i template che un flusso invia? Vai a Template
  • Gestire i tag dei contatti? Vedi Contatti

Modifica questa pagina su GitHub

Ultimo aggiornamento