
# Test locale dei webhook con keenauth webhooks listen

`keenauth webhooks listen` ti permette di sviluppare un ricevitore di webhook sulla tua macchina. Legge l'API degli eventi di un ambiente `development` o `staging` e invia ogni nuovo evento a un URL locale, firmato esattamente come una vera consegna di webhook (Standard Webhooks). Non ti serve alcun endpoint pubblico né un tunnel: gli eventi arrivano alla CLI tramite l'API, e la CLI li inoltra sulla tua macchina.

## Utilizzo

```sh
keenauth webhooks listen --forward-to http://localhost:3000/webhooks
```

Il comando stampa per prima cosa, su stderr, un segreto di firma per questa sessione:

```text
Signing secret for this session (shown once; not sent to KeenAuth, not stored): idp_whsec_…
Forwarding new events to http://localhost:3000/webhooks. Press Ctrl-C to stop.
```

Configura il tuo ricevitore con quel segreto mentre il comando è in esecuzione, per esempio come `KEENAUTH_WEBHOOK_SECRET`, e verifica ogni consegna con il verificatore di webhook dell'SDK (vedi [Verifica dei webhook](/docs/sdk/go)). Il segreto viene creato sulla tua macchina solo per questa sessione: non viene mai inviato a KeenAuth, non viene mai memorizzato, e ogni nuova esecuzione ne crea uno nuovo. Non è il segreto di alcun endpoint webhook che hai registrato.

| Flag | Descrizione |
|---|---|
| `--forward-to` | URL locale che riceve gli eventi (obbligatorio). Deve essere un URL `http` o `https` su `localhost` o un indirizzo loopback come `127.0.0.1` o `[::1]`. |
| `--types` | Solo questi tipi di evento, separati da virgola o ripetuti. |
| `--org` | Solo gli eventi di questa organizzazione (`org_…`). |
| `--payload` | `thin` (predefinito) o `full`. `full` include la risorsa e richiede anche l'autorizzazione `users:read`. |
| `--after` | Da dove iniziare: `latest` (predefinito) inoltra solo gli eventi che avvengono da adesso in poi; un cursore di `keenauth events tail` inizia da lì. |
| `--interval` | Tempo tra due controlli quando non ci sono nuovi eventi, da `1s` a `60s`. Predefinito: `5s`. |
| `--output`, `-o` | `table`, `json` o `yaml` per le righe di consegna. Senza il flag la CLI stampa una tabella su un terminale e JSON altrimenti. |

Il comando richiede l'autorizzazione `events:read` e funziona con una chiave API e con una sessione `keenauth login`.

## Cosa riceve il tuo ricevitore

Ogni evento viene inviato come `POST` con il JSON dell'evento come corpo, esattamente come lo ha restituito l'API degli eventi, e con questi header:

| Header | Valore |
|---|---|
| `webhook-id` | L'ID dell'evento (`evt_…`), lo stesso presente nel corpo. |
| `webhook-timestamp` | L'orario della consegna, in secondi Unix. |
| `webhook-signature` | `v1,<HMAC-SHA256 in base64>` di `<webhook-id>.<webhook-timestamp>.<body>` con il segreto della sessione. |
| `content-type` | `application/json` |

Ogni consegna viene tentata una sola volta. Il comando stampa una riga per consegna con l'orario, il tipo di evento, l'ID dell'evento, il codice di stato con cui il tuo ricevitore ha risposto (o l'errore di connessione) e la durata. Un ricevitore che fallisce o non è in esecuzione non interrompe il comando. I reindirizzamenti non vengono seguiti.

## Ambienti

Il comando funziona solo con gli ambienti `development` e `staging`. Con una credenziale di produzione si interrompe prima di inviare qualsiasi richiesta ed esce con codice 3:

- una chiave API per un ambiente di produzione (`idp_sk_live_…` o `idp_rk_live_…`);
- una sessione `keenauth login` il cui ambiente corrente è un ambiente di produzione.

Se il server rifiuta la richiesta perché l'ambiente è di produzione, la CLI stampa la sua risposta di problema, `code: test_feature_not_in_production`, ed esce anch'essa con codice 3.

## Codici di uscita

| Codice | Significato |
|---|---|
| `0` | Arrestato con Ctrl-C. |
| `1` | Un errore del server o un errore di rete verso KeenAuth, oppure non è stato possibile determinare il tipo dell'ambiente corrente. |
| `2` | Errore di utilizzo: `--forward-to` manca, non è un URL locale, oppure un filtro o un intervallo non è valido. Nessuna richiesta è stata inviata. |
| `3` | Una credenziale di produzione, una credenziale mancante, oppure il server ha risposto `401` o `403`. |
| `4` | Il piano non include la funzione (`403` con `plan_feature_unavailable`). |
