# Webhook in entrata

> Come un altro sistema (CRM, modulo, ERP, n8n, Zapier) avvia un workflow della community chiamando un indirizzo di Memberfy. Creare, ruotare e revocare l'indirizzo, il token nell'intestazione, la firma HMAC con esempi in curl e Node, come viene trovata la persona, le variabili dell'attivatore, le risposte e le consegne.

Il **webhook in entrata** è il percorso inverso dei [webhook](/api/webhooks): invece di Memberfy che avvisa un altro sistema, è un altro sistema (un CRM, un modulo, un ERP, un'automazione in n8n o in Zapier) a chiamare un indirizzo di Memberfy e ad avviare un [workflow](/notificacoes/workflows) per una persona della community. Per esempio: il CRM chiude una vendita e la persona riceve la serie di benvenuto del cliente.

## Creare l'indirizzo

*Ruolo: proprietario o amministratore.*

1. In **Amministrazione › Workflow**, apri il workflow e trascina il blocco di attivatore **Webhook** (*Webhook ricevuto*) nel disegno. Ogni workflow ha un solo attivatore.
2. In **Chi è la persona**, indica dove si trova la persona nel JSON della chiamata: **Per e-mail** o **Per memberId**, e il **Percorso nel JSON** (campi separati da punti, come `contact.email`, senza indici di elenco).
3. In **Valori da usare nei passi**, se vuoi, mappa fino a 20 valori del JSON (**Nome** e percorso).
4. **Salva** il workflow e, nel pannello dell'attivatore, **Crea indirizzo**.

La finestra mostra l'**Indirizzo**, il **Token** e il **Segreto di firma (HMAC)** una sola volta: *"Salvali ora: il token e il segreto si vedono solo questa volta."* Dopo, il pannello mostra solo la parte finale del token e del segreto.

- **Ruota** crea un token e un segreto nuovi, che valgono subito; il sistema che chiama l'indirizzo attuale smette di funzionare finché non riceve quelli nuovi.
- **Revoca** disattiva subito l'indirizzo: le chiamate vengono rifiutate.

## Chiamare l'indirizzo

Fai una `POST` con il corpo in JSON (`Content-Type: application/json`, fino a 64 KB) a `https://api.memberfy.net/api/workflow-hooks`, con:

| Intestazione | Cos'è |
|---|---|
| `X-Memberfy-Hook-Token` | Il token dell'attivatore. Mandalo sempre nell'intestazione: nell'indirizzo (`/api/workflow-hooks/{token}`) funziona anche, ma finisce nei log |
| `X-Memberfy-Signature` | La firma, `t=<unix>,v1=<hex>` (vedi sotto) |
| `X-Memberfy-Delivery-Id` | Un identificativo unico della chiamata (fino a 64 lettere, cifre, `-` e `_`). Se si ripete entro 10 minuti, la chiamata viene rifiutata |

### La firma (HMAC)

Con **Richiedi la firma (HMAC)** attivo (l'impostazione predefinita), solo chi ha il segreto può avviare il workflow. La firma è obbligatoria quando il percorso dell'attivatore invia contenuti (e-mail, messaggio, commento, reazione o Slack): senza, il workflow non si attiva.

Per firmare:

1. `t` è l'ora attuale in secondi (Unix). Vale **5 minuti** in più o in meno.
2. Calcola l'HMAC-SHA256, in esadecimale, con il segreto, su `t`, un punto e il **corpo grezzo**, esattamente i byte che vanno nella chiamata: `"<t>.<corpo>"`.
3. Manda `X-Memberfy-Signature: t=<t>,v1=<hmac>`.

**curl:**

```bash
SECRET='il-segreto-dell-attivatore'
TOKEN='il-token-dell-attivatore'
BODY='{"customer":{"email":"maria@memberfy.net"},"plan":{"name":"Anual"}}'
T=$(date +%s)
SIG=$(printf '%s.%s' "$T" "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -hex | sed 's/^.* //')

curl -X POST https://api.memberfy.net/api/workflow-hooks \
  -H 'Content-Type: application/json' \
  -H "X-Memberfy-Hook-Token: $TOKEN" \
  -H "X-Memberfy-Signature: t=$T,v1=$SIG" \
  -H "X-Memberfy-Delivery-Id: crm-$(date +%s%N)" \
  --data "$BODY"
```

**Node:**

```js
const crypto = require('crypto');

async function startWorkflow(payload) {
  const body = JSON.stringify(payload); // firma esattamente ciò che va nella chiamata
  const t = Math.floor(Date.now() / 1000);
  const v1 = crypto
    .createHmac('sha256', process.env.MEMBERFY_HOOK_SECRET)
    .update(`${t}.${body}`)
    .digest('hex');

  const res = await fetch('https://api.memberfy.net/api/workflow-hooks', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Memberfy-Hook-Token': process.env.MEMBERFY_HOOK_TOKEN,
      'X-Memberfy-Signature': `t=${t},v1=${v1}`,
      'X-Memberfy-Delivery-Id': crypto.randomUUID(),
    },
    body,
  });
  return res.status; // 202 quando accettata
}

startWorkflow({ customer: { email: 'maria@memberfy.net' }, plan: { name: 'Anual' } });
```

## La persona e le variabili

- Memberfy cerca la persona **dopo** aver risposto, per e-mail o per `memberId` nel percorso configurato. Deve essere membro della community; altrimenti la consegna risulta *Persona non trovata*.
- Vengono salvati solo i valori mappati, nell'esecuzione della persona; il resto del corpo viene scartato.
- Ogni valore diventa la variabile `{{gatilho_<nome>}}`, per esempio `{{gatilho_plano}}`. Vale nel testo dei messaggi, dei commenti e di Slack e **nel corpo** delle e-mail, mai nell'oggetto né dentro i link.
- **Quante volte la persona entra** vale come per qualsiasi attivatore, e ogni persona entra al massimo **5 volte al giorno** tramite il webhook di ogni workflow.
- Una chiamata che porta l'intestazione `X-Memberfy-Run-Id` di un'esecuzione dello stesso workflow (un sistema esterno che rimanda indietro la chiamata fatta dal workflow) viene ignorata, per non creare un ciclo. I post su Slack di un workflow portano questa intestazione.

## Risposte

| Stato | Quando |
|---|---|
| `202` | Token e firma validi. La risposta è la stessa che la persona venga trovata o no; il risultato compare nelle consegne |
| `401` | Firma assente, errata o fuori dai 5 minuti |
| `404` | Token sconosciuto, revocato o di un workflow eliminato |
| `409` | `X-Memberfy-Delivery-Id` ripetuto entro 10 minuti |
| `413` | Corpo oltre 64 KB |
| `429` | Più di 60 chiamate al minuto o 5 mila al giorno sullo stesso indirizzo; attendi il `Retry-After` |
| `503` | Il controllo delle ripetizioni non è disponibile al momento; riprova |

## Consegne

Nel pannello dell'attivatore, **Consegne** elenca ogni chiamata ricevuta, con il risultato: **Avviato**, **In coda**, **Persona non trovata**, **Workflow spento**, **Già entrata**, **Limite giornaliero della persona**, **Senza firma** o **Chiamata ripetuta (loop)**.

## Con l'assistente (MCP)

Il proprietario e l'amministratore creano l'indirizzo (`create_workflow_webhook`: il token e il segreto compaiono una volta), lo ruotano e lo revocano (`rotate_workflow_webhook` e `revoke_workflow_webhook`, con conferma); il team consulta l'indirizzo (`get_workflow_webhook`, mai il token) e le consegne (`list_workflow_webhook_deliveries`). Vedi [Strumenti · Community e struttura](/mcp/ferramentas-comunidade#workflow).

## Correlati

- [Workflow](/notificacoes/workflows)
- [Webhook](/api/webhooks)
- [Zapier, Make e n8n](/integracoes/zapier-make-n8n)
