Vai al contenuto
Documentazione

Inviare lead e passaggi ai tuoi strumenti con i webhook

Invia nuovi lead, passaggi e richieste di live chat, moduli inviati, appuntamenti prenotati e richieste di reso da intoCHAT al tuo server, a Zapier, Make o n8n come JSON firmato: eventi, contenuti, firme e nuovi tentativi.

Un webhook invia un evento del tuo agente a un indirizzo che scegli tu, come richiesta JSON firmata in POST, nel giro di pochi secondi. Usalo per portare i nuovi lead nel tuo CRM o per avviare un'automazione. Funziona con il tuo server e con gli strumenti di automazione che accettano webhook in entrata, come Zapier, Make o n8n: usi il trigger dello strumento per i webhook in entrata. Le app di intoCHAT per Zapier e Make sono pronte e diventano disponibili una volta pubblicate nelle directory di app di questi strumenti; vedi Zapier e Make. Per ricevere questi eventi come messaggi in un canale Slack non serve un webhook: usa le notifiche Slack.

Eventi

EventoNome nella dashboardInviato quando
lead.createdNew leadviene salvato un nuovo contatto, dal modulo lead o dai contatti che il visitatore ha scritto in chat.
handoff.requestedHand-off requestedl'agente ha inviato una conversazione al tuo team via email. Vedi Passaggio via email.
form.submittedForm submittedun visitatore ha inviato uno dei tuoi moduli in chat.
booking.createdMeeting bookedun visitatore ha prenotato un appuntamento dalla chat. Vedi Prenotazione con Cal.com o Calendly.
live_chat.requestedLive chat requestedl'agente ha chiesto al tuo team di intervenire nella chat, perché un visitatore ha chiesto di parlare con una persona mentre qualcuno del tuo team era online. Vedi Live chat.
return.requestedReturn requestedun visitatore ha chiesto di restituire o cambiare articoli di un ordine verificato dall'agente. Vedi Stato degli ordini e resi.

lead.created viene inviato una volta per contatto. Un visitatore che torna e invia di nuovo gli stessi dati non genera un nuovo evento, e nemmeno una chat che aggiunge un numero di telefono a un contatto già salvato in quella chat.

handoff.requested viene inviato solo se l'email al tuo team è partita davvero. Anche i passaggi dal Playground lo inviano, con "test": true. Se hai collegato i ticket helpdesk, viene inviato quando il ticket è stato creato o la creazione non è riuscita, di solito qualche secondo dopo, e contiene il ticket quando c'è.

form.submitted viene inviato una volta per ogni invio. Un modulo si può inviare una sola volta per conversazione, e un invio non genera mai lead.created, anche se il modulo chiede un indirizzo email.

booking.created viene inviato una volta per prenotazione, dopo che Cal.com o Calendly l'ha accettata e intoCHAT l'ha salvata. Una prenotazione non genera mai lead.created. Le prenotazioni dal Playground sono prenotazioni reali e lo inviano anche loro, senza indicazione di prova. Le modifiche fatte in seguito in Cal.com o Calendly, come una cancellazione, non inviano alcun evento.

live_chat.requested viene inviato una volta per richiesta, quando l'agente chiede al tuo team di intervenire, che qualcuno intervenga o no. Un visitatore che chiede di nuovo dopo che la richiesta è scaduta o la live chat è terminata ne genera una nuova. Il Playground non richiede mai la live chat, quindi non invia mai questo evento.

return.requested viene inviato una volta per richiesta di reso, quando intoCHAT l'ha salvata. Ogni conversazione può inviare una richiesta per ordine, quindi chiedere di nuovo per lo stesso ordine non invia nulla. Anche le richieste dal Playground lo inviano, senza indicazione di prova.

Aggiungere un webhook

  1. Apri l'agente e vai alla scheda Leads. Webhooks si trova verso il fondo della scheda, sopra Slack alerts.
  2. Fai clic su Add webhook.
  3. In Endpoint URL incolla l'indirizzo che il tuo server o il tuo strumento fornisce per i webhook in entrata.
  4. In Events to send lascia selezionati gli eventi che ti servono: New lead, Hand-off requested, Form submitted, Meeting booked, Live chat requested e Return requested. Per un nuovo webhook sono selezionati tutti e sei. Un webhook aggiunto in precedenza mantiene i suoi eventi: clicca su Edit e seleziona Form submitted, Meeting booked, Live chat requested o Return requested se deve riceverli.
  5. Lascia attivo Active e fai clic su Add webhook.
  6. Copia il segreto di firma che compare, conservalo dove il tuo ricevitore può leggerlo e fai clic su I've saved it.
  7. Fai clic su Send test event per controllare il collegamento. Il risultato compare sotto i pulsanti.

L'indirizzo deve iniziare con https:// e puntare a un server pubblico. Gli indirizzi di reti private o interne, come localhost o 192.168.1.10, vengono rifiutati al salvataggio e controllati di nuovo prima di ogni invio. Ogni agente può avere fino a 5 webhook.

I webhook che Zapier, Make o il tuo codice hanno registrato tramite la REST API non rientrano nei 5; vedi Webhook creati dalle integrazioni. Non vi rientrano nemmeno i webhook dei singoli moduli; vedi Un webhook per un solo modulo.

Per mettere in pausa un webhook senza perdere le impostazioni, disattivalo: mostrerà Paused. Gli eventi che avvengono durante la pausa non vengono inviati, nemmeno dopo. Un invio in attesa di un nuovo tentativo fallisce al tentativo successivo; quando il webhook è di nuovo attivo, puoi inviarlo di nuovo. Edit modifica indirizzo ed eventi. Remove elimina il webhook e la sua cronologia degli invii.

Webhook creati dalle integrazioni

Un'integrazione può registrare un webhook sul tuo agente tramite la REST API, con una delle tue chiavi API. Le app per Zapier e Make lo fanno quando attivi uno Zap o aggiungi un trigger istantaneo a uno scenario.

Questi webhook compaiono nel riquadro Webhooks insieme agli altri, con un'etichetta che indica da dove vengono: via Zapier, via Make o via API. Vengono inviati, firmati, ritentati e registrati come i webhook che aggiungi tu, e su di essi puoi usare Send test event, Recent deliveries, l'interruttore Active e New secret.

  • Non hanno il pulsante Edit: indirizzo ed eventi appartengono allo Zap, allo scenario o al codice che li ha creati, e modificarli qui lo romperebbe.
  • Remove ne elimina uno. Lo Zap o lo scenario resta attivo ma non riceve più eventi; disattivalo anche lì, oppure disattivalo e riattivalo per registrare un nuovo webhook.
  • L'integrazione rimuove da sola il suo webhook quando disattivi lo Zap o elimini il trigger.
  • Revocare la chiave API che li ha creati li elimina. Vedi Revocare una chiave.
  • Un agente può averne fino a 25, oltre ai 5 che aggiungi tu.

Un webhook per un solo modulo

Un modulo in chat può avere un webhook tutto suo, che riceve solo gli eventi form.submitted di quel modulo. Lo aggiungi e lo gestisci nell'editor del modulo nella scheda Actions, in Webhook for this form, non nel riquadro Webhooks.

  • Ha il suo segreto di firma, mostrato una sola volta, e viene inviato, firmato, ritentato e registrato esattamente come i webhook di questa pagina, con la stessa struttura esterna e gli stessi dati di form.submitted.
  • Invia solo form.submitted, solo per il suo modulo. I suoi eventi non si possono cambiare, e un evento di prova funziona come descritto più sotto.
  • Non conta nei 5 webhook dell'agente e non compare nel riquadro Webhooks.
  • I webhook dell'agente iscritti a Form submitted continuano a ricevere gli invii di tutti i moduli, compresi quelli di un modulo con un webhook proprio. Ogni webhook riceve un invio separato, con un proprio ID.
  • Eliminare il modulo elimina il suo webhook e la cronologia degli invii.

Il segreto di firma

Ogni webhook ha il suo segreto di firma, che inizia con whsec_. Compare per intero una sola volta, subito dopo aver aggiunto il webhook o creato un nuovo segreto. In seguito il riquadro ne mostra solo gli ultimi quattro caratteri.

Se perdi il segreto o pensi che qualcun altro lo conosca, fai clic su New secret. Il vecchio segreto smette subito di funzionare, quindi passa immediatamente quello nuovo al tuo ricevitore.

Che cosa viene inviato

Ogni invio è una richiesta POST con un corpo JSON e queste intestazioni:

IntestazioneValore
Content-Typeapplication/json
User-AgentintoCHAT-Webhooks/1.0
X-IntoChat-EventIl nome dell'evento, per esempio lead.created
X-IntoChat-DeliveryL'ID dell'invio. Resta uguale a ogni nuovo tentativo.
X-IntoChat-TimestampQuando è stato inviato questo tentativo, in secondi Unix
X-IntoChat-Signaturesha256= seguito dalla firma; vedi sotto

Il corpo ha sempre la stessa struttura esterna. id è l'ID dell'invio, lo stesso valore di X-IntoChat-Delivery:

{
  "id": "DELIVERY_ID",
  "event": "lead.created",
  "created_at": "2026-10-07T09:30:00.000Z",
  "agent": { "id": "AGENT_ID", "name": "Acme Assistant" },
  "data": { }
}

Dati di lead.created

CampoContenuto
leadIdL'ID del lead
agentId, agentNameL'agente che ha raccolto il lead
emailL'indirizzo email, oppure null
phoneIl numero di telefono, oppure null
nameIl nome inserito nel modulo, oppure null. Un nome non viene mai preso da un messaggio in chat.
customFieldsLe risposte ai tuoi campi personalizzati, come elenco di { "id", "label", "value" }. Vuoto se non ce ne sono.
sourceform o chat
conversationIdLa conversazione da cui viene il lead, oppure null
collectedAtQuando il lead è stato salvato, come orario ISO 8601 in UTC
identitySolo per un visitatore verificato con la verifica dell'identità: { "userId", "name", "email" }. Altrimenti è assente.

Dati di handoff.requested

CampoContenuto
conversationIdLa conversazione passata al team
visitorEmailL'indirizzo indicato dal visitatore per la risposta
summaryCiò di cui il visitatore ha bisogno, con le parole dell'agente
pageLa pagina in cui è iniziata la chat, oppure null
countryIl codice del paese del visitatore, di due lettere, oppure null
requestedAtQuando è stato inviato il passaggio, come orario ISO 8601 in UTC
testtrue per un passaggio dal Playground, altrimenti false
ticketSolo quando i ticket helpdesk hanno aperto un ticket per questo passaggio: { "provider", "id", "url" }, dove provider è zendesk, freshdesk o hubspot, id è il numero del ticket come stringa e url lo apre nel tuo helpdesk. Altrimenti è assente.

Dati di form.submitted

CampoContenuto
submissionIdL'ID dell'invio
formId, formNameIl modulo inviato
agentId, agentNameL'agente che ha mostrato il modulo
answersLe risposte del visitatore, come elenco di { "id", "label", "value" }, nell'ordine del modulo. I campi facoltativi lasciati vuoti non ci sono.
conversationIdLa conversazione in cui è stato inviato il modulo
submittedAtQuando è stato salvato l'invio, come orario ISO 8601 in UTC
identitySolo per un visitatore verificato con la verifica dell'identità: { "userId", "name", "email" }. Altrimenti è assente.

Dati di booking.created

CampoContenuto
bookingIdL'ID della prenotazione in intoCHAT
providerIl calendario: calcom o calendly
providerBookingIdL'ID della prenotazione in Cal.com, oppure l'URI dell'invitato in Calendly, per esempio https://api.calendly.com/scheduled_events/…/invitees/…
agentId, agentNameL'agente con cui è stato prenotato l'appuntamento
eventTypeId, eventTypeUri, eventTitleIl tipo di evento prenotato: eventTypeId è il numero di Cal.com e eventTypeUri è l'URI di Calendly. L'altro è null.
startAt, endAtQuando inizia e finisce l'appuntamento, come orari ISO 8601 in UTC
timeZoneIl fuso orario del visitatore, per esempio Europe/Berlin, oppure UTC se il suo browser non ne ha indicato uno
attendeeName, attendeeEmailIl nome e l'indirizzo email inseriti dal visitatore
providerStatusaccepted, oppure pending se devi prima confermare la prenotazione in Cal.com. Le prenotazioni Calendly sono sempre accepted.
conversationIdLa conversazione in cui è stato prenotato l'appuntamento
createdAtQuando è stata salvata la prenotazione, come orario ISO 8601 in UTC
identitySolo per un visitatore verificato con la verifica dell'identità: { "userId", "name", "email" }. Altrimenti è assente.

Dati di live_chat.requested

CampoContenuto
conversationIdLa conversazione in cui il visitatore ha chiesto una persona
visitorMessageL'ultimo messaggio del visitatore, accorciato a 500 caratteri con … alla fine se è più lungo
pageLa pagina in cui è iniziata la chat, oppure null
countryIl codice del paese del visitatore, di due lettere, oppure null
requestedAtQuando l'agente ha chiesto al tuo team di intervenire, come orario ISO 8601 in UTC

L'evento non dice se qualcuno è intervenuto. Chi ha preso in carico la chat, e quando, si vede nella casella Live chat e nella trascrizione.

Dati di return.requested

CampoContenuto
returnRequestIdL'ID della richiesta in intoCHAT
providerIl negozio: shopify o woocommerce
orderName, orderIdL'ordine come lo mostra il tuo negozio, per esempio #1042, e il suo ID nel negozio
emailL'indirizzo email dell'ordine. Il visitatore ha dimostrato di conoscerlo, oppure lo ha passato la verifica dell'identità del tuo sito.
kindreturn o exchange
itemsGli articoli, ognuno come { "title", "quantity" }. Il titolo include la variante quando il prodotto è stato ordinato in più varianti, per esempio Wool scarf - Blue.
reasonIl motivo, con le parole del visitatore
statusrequested
agentId, agentNameL'agente con cui è stata fatta la richiesta
conversationIdLa conversazione in cui è stata fatta la richiesta
createdAtQuando è stata salvata la richiesta, come orario ISO 8601 in UTC

Nel tuo negozio non è stato approvato né modificato nulla. Gestisci il reso lì, poi segnalo come gestito nell'elenco Returns della scheda Leads.

I nomi dei campi di tutti gli eventi usano il camelCase.

Evento di prova

Send test event invia una richiesta con "event": "test" e questi dati: { "message": "This is a test event from intoCHAT. Your webhook is set up correctly." }. Parte qualunque siano gli eventi scelti, anche con il webhook in pausa, e viene tentata una sola volta. Dato che i suoi dati sono diversi da quelli degli eventi reali, uno strumento che associa i campi partendo da un esempio ha bisogno di un evento reale, per esempio un lead che invii tu stesso dal tuo sito.

Verificare la firma

Controlla ogni richiesta prima di fidarti. X-IntoChat-Signature è sha256= seguito dall'HMAC-SHA256 in esadecimale di timestamp, punto e corpo grezzo, cioè ${timestamp}.${rawBody}, con il segreto di firma del webhook come chiave. Il timestamp è il valore di X-IntoChat-Timestamp.

  • Calcola la firma sul corpo esattamente come arriva, prima di interpretare il JSON.
  • Confronta in tempo costante.
  • Rifiuta i timestamp vecchi, così una richiesta intercettata non può essere riprodotta. L'esempio qui sotto accetta 5 minuti.

Questo esempio Node.js è lo stesso che trovi in Verify signatures nel riquadro Webhooks, con un pulsante Copy:

const crypto = require("crypto")

// rawBody: the request body exactly as received, before JSON parsing.
function verifyIntoChatWebhook(rawBody, headers, secret) {
  const timestamp = headers["x-intochat-timestamp"]
  const signature = headers["x-intochat-signature"] || ""

  // Reject anything older than 5 minutes, so a captured request can't be replayed.
  const age = Math.abs(Date.now() / 1000 - Number(timestamp))
  if (!timestamp || !(age <= 300)) return false

  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(timestamp + "." + rawBody)
    .digest("hex")

  const a = Buffer.from(signature)
  const b = Buffer.from(expected)
  return a.length === b.length && crypto.timingSafeEqual(a, b)
}

Se il tuo strumento non può verificare le firme, tratta l'indirizzo del webhook come una password: chiunque lo conosca può inviargli richieste.

Rispondere e gestire i duplicati

  • Rispondi con un qualsiasi stato 2xx entro 10 secondi. Tutto il resto conta come errore: un altro codice di stato, nessuna risposta in tempo, un errore di connessione o di certificato.
  • I reindirizzamenti non vengono seguiti. Una risposta 3xx conta come errore, quindi inserisci l'indirizzo finale.
  • Lo stesso evento può arrivare più di una volta, per esempio se il tuo server l'ha salvato ma ha risposto troppo tardi. Usa X-IntoChat-Delivery, o l'id nel corpo, per ignorare un invio già gestito.
  • Per lo stesso evento ogni webhook riceve un invio separato, con un proprio ID.

Nuovi tentativi

  • Il primo tentativo parte subito dopo l'evento. Se fallisce, seguono fino a due nuovi tentativi rapidi nel giro di pochi secondi.
  • Se falliscono anche questi, l'invio mostra Retrying e un'attività pianificata riprova più tardi. I tentativi si fermano dopo 6 in tutto o 24 ore dopo l'evento, a seconda di cosa arriva prima. L'invio viene quindi segnato come Failed.
  • L'attività pianificata al momento gira una volta al giorno. In pratica, un invio che fallisce ancora dopo i tentativi rapidi riceve uno o due tentativi in più, entro circa un giorno dall'evento.
  • Un invio verso un indirizzo che risulta puntare a una rete privata fallisce subito, senza nuovi tentativi.
  • Ogni nuovo tentativo mantiene l'ID dell'invio e viene firmato di nuovo con un nuovo timestamp.

Invii recenti

Fai clic su Recent deliveries sotto un webhook per vedere i suoi ultimi 20 invii. Ognuno mostra lo stato (Sending, Retrying, Delivered o Failed), l'evento, l'ora, il numero di tentativi e lo stato HTTP. Un invio in attesa di riprova mostra quando è previsto il prossimo tentativo, e uno non riuscito mostra l'errore, per esempio No response within 10 seconds.

Un invio fallito ha un pulsante Resend che lo ritenta una volta, subito. Gli invii vengono eliminati dopo 30 giorni.

Passi successivi

Visualizza come Markdown