> ## Documentation Index
> Fetch the complete documentation index at: https://knowledge.flowella.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook in uscita

> Sottoscrivete eventi di messaggi, conversazioni, opt-out e modelli, verificate le firme HMAC, gestite i retry ed evitate elaborazioni duplicate.

I webhook in uscita consentono ai vostri sistemi di reagire agli eventi di Flowella quasi in tempo reale, senza interrogare l'API. Si configura un URL e un elenco di tipi di eventi e Flowella invia un payload JSON firmato a tale URL ogni volta che si verifica uno di questi eventi.

## Configurazione di un webhook

È necessario il ruolo **Owner** o **Admin**.

<Steps>
  <Step title="Aprire Impostazioni → Webhooks">
    Nell'app Flowella, andare su **Impostazioni → Webhooks**.
  </Step>

  <Step title="Aggiungere un webhook">
    Fare clic su **Aggiungi webhook**, incollare l'URL HTTPS pubblico del proprio endpoint e scegliere i tipi di evento che si desidera ricevere.
  </Step>

  <Step title="Salvare il segreto di firma">
    Flowella genera un segreto di firma unico per il webhook. Copiatelo: lo userete per verificare le richieste in arrivo.
  </Step>

  <Step title="Inviare un test">
    Fare clic su **Invia test** per inviare immediatamente un payload `webhook.test`. Verificare che l'endpoint lo abbia ricevuto e abbia risposto con un 2xx.
  </Step>
</Steps>

## Tipi di evento

È possibile sottoscrivere uno qualsiasi di questi eventi di prodotto:

| Evento                    | Quando si attiva                                                                        |
| ------------------------- | --------------------------------------------------------------------------------------- |
| `message.received`        | È arrivato un messaggio WhatsApp in entrata da un contatto                              |
| `message.sent`            | Flowella ha accettato il messaggio in uscita e lo ha inviato a Meta                     |
| `message.delivered`       | Meta ha confermato che il messaggio è stato consegnato al dispositivo del destinatario  |
| `message.read`            | Il destinatario ha aperto il messaggio                                                  |
| `message.failed`          | Meta ha restituito un errore per il messaggio                                           |
| `conversation.opened`     | Una conversazione è passata allo stato aperto                                           |
| `conversation.closed`     | Una conversazione è stata chiusa                                                        |
| `optout.created`          | Un contatto si è dissociato da un canale specifico                                      |
| `template.status_updated` | Meta ha modificato lo stato di un modello (approvato, rifiutato, in pausa, disattivato) |

`webhook.test` viene inviato solo quando si fa clic su **Invia test**, senza sottoscriverlo esplicitamente.

## Formato della richiesta

Flowella invia un corpo JSON al vostro URL con queste intestazioni:

```http theme={null}
POST https://your-endpoint.example.com/flowella
Content-Type: application/json
User-Agent: Flowella-Webhooks/1
X-Flowella-Signature: <hex digest>
```

I payload sono limitati a **256 KB**. Gli oggetti più grandi sono riassunti: utilizzare l'API per recuperare l'intero record per ID, se necessario.

La forma del corpo varia a seconda dell'evento, ma comprende sempre:

```json theme={null}
{
  "event": "message.delivered",
  "timestamp": "2025-01-15T14:30:00.000Z",
  "organizationId": "clxxxxxxxxxxxxxxxxxxxxxxxx",
  "data": { "...event-specific fields..." }
}
```

## Verifica delle firme

Ogni richiesta include un'intestazione `X-Flowella-Signature`. Il valore è il digest esadecimale **HMAC-SHA256** del corpo della richiesta **raw UTF-8**, codificato con il segreto di firma del webhook.

Verificare prima dell'elaborazione:

```js theme={null}
import { createHmac, timingSafeEqual } from "node:crypto";

function verify(rawBody, signatureHeader, secret) {
  const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
  const a = Buffer.from(expected, "hex");
  const b = Buffer.from(signatureHeader, "hex");
  return a.length === b.length && timingSafeEqual(a, b);
}
```

```python theme={null}
import hmac, hashlib

def verify(raw_body: bytes, signature_header: str, secret: str) -> bool:
    expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature_header)
```

<Warning>
  Firmare sempre i byte **raw body** prima che qualsiasi parsing JSON o middleware riformatti il payload. Se il framework reserializza JSON, la firma non corrisponderà.
</Warning>

## Risposte, tentativi e timeout

* **Timeout**: Flowella attende fino a **10 secondi** per la risposta dell'endpoint.
* **Successo**: qualsiasi risposta di `2xx` viene considerata come una consegna riuscita.
* **Ripetizioni**: le consegne non riuscite vengono ritentate fino a **3 tentativi** con backoff.
* **Autodisabilitazione**: se un webhook accumula **10 fallimenti consecutivi**, Flowella lo disattiva. Sarà necessario riattivarlo da **Impostazioni → Webhooks** dopo aver sistemato l'endpoint.

L'endpoint deve restituire il più velocemente possibile, rinviando qualsiasi elaborazione pesante a una coda in background sul proprio lato.

## Idempotenza

I webhook possono essere ritentati, quindi lo stesso evento logico può arrivare più di una volta. Per elaborare in modo sicuro:

* Utilizzare la `data.id` dell'evento (o una chiave derivata come `event + data.messageId`) come chiave di idempotenza.
* Mantenere una cache di breve durata delle chiavi elaborate (qualche ora è sufficiente per i tentativi).
* Trattare i duplicati come no-op.

## Elencare e gestire le consegne

**Impostazioni → Webhooks** mostra i tentativi di consegna recenti per ogni webhook, inclusi:

* Timestamp
* Tipo di evento
* Stato della risposta
* Un corpo di risposta troncato (fino a \~1 KB) per il debugging

Se un webhook viene disattivato a causa di ripetuti fallimenti, la stessa pagina consente di riattivarlo.

## Sviluppo locale

Il modo più semplice per sviluppare localmente con i webhook è quello di inoltrare un tunnel pubblico (ad esempio, ngrok o Cloudflare Tunnel) al proprio server di sviluppo e puntare l'URL del webhook all'host del tunnel. Usare **Invia test** per lanciare i payload su richiesta senza attendere l'attività reale di WhatsApp.

<Tip>
  Avete bisogno di reagire a eventi che non sono presenti nell'elenco? Comunicatecelo all'indirizzo [support](https://flowella.io/support): aggiungiamo eventi man mano che i clienti li richiedono.
</Tip>

## Correlato

<CardGroup cols={2}>
  <Card title="Impostazioni → Webhooks" icon="webhook" href="/it/settings/webhooks">
    Configurare endpoint, segreti di firma e tentativi nell'app.
  </Card>

  <Card title="Introduzione all'API" icon="code" href="/it/api-reference/introduction">
    Autorizzazione, errori, paginazione e limiti di velocità per l'API REST.
  </Card>

  <Card title="Chiavi API" icon="key" href="/it/settings/api-keys">
    Creare e ruotare i token bearer di cui l'endpoint può avere bisogno.
  </Card>

  <Card title="Eventi di notifica" icon="bell" href="/it/app/notification-events">
    Gli stessi eventi vengono trasmessi nel feed in-app e nelle e-mail.
  </Card>
</CardGroup>
