Skip to Content

API della chat del sito web

Collega un modulo tuo al widget di chat o crea una tua interfaccia di chat con l'SDK del widget, REST, digitazione, SSE e attività dei visitatori.

Ultimo aggiornamento il

Il widget ufficiale lo installi nell'app: vedi Mettere la chat sul tuo sito web. Le opzioni dello snippet sono in Impostazioni della Chat sul sito web. Questa pagina è per gli sviluppatori: l'SDK del widget per un modulo tuo e il livello REST per una interfaccia di chat tua. Vedi OpenAPI, tag inbox.

SDK del widget

Dopo il caricamento dello script del widget, window.TillorInbox è pronto. Con esso passi i dati di contatto dal tuo modulo (pagina contatti, dettaglio di una vendita, richiesta di preventivo). Tutti i metodi aspettano che la configurazione del widget sia caricata.

MetodoDescrizione
ready()Promise che si risolve non appena il widget è caricato
getVisitor()Legge i dati di contatto salvati da localStorage e i campi del widget compilati; sincrono, senza rete
setVisitor({ name?, firstName?, lastName?, email?, phone?, message?, customFields? }, options?)Compila i campi della chat senza inviare
open()Apre la finestra della chat
close()Chiude la finestra della chat
toggle()Apre o chiude la finestra della chat
send({ body, name?, firstName?, lastName?, email?, phone?, message?, customFields?, open?, silent?, markSubmitted?, metadata? })Invia un messaggio con i dati di contatto

getVisitor() restituisce questo oggetto:

CampoDescrizione
visitorIdID di questo visitatore in questo browser (localStorage)
nameNome completo (un solo campo nel widget)
firstName / lastNameRicavati da name (prima parola / resto)
email, phoneDati di contatto
customFieldsCampi aggiuntivi dalle impostazioni del widget
messageBozza nel campo del messaggio
detailsSubmittedSe il modulo del visitatore risulta compilato

Usa getVisitor() per precompilare un modulo tuo da localStorage (stesso browser, anche dopo un aggiornamento della pagina).

Opzioni per setVisitor (secondo argomento):

OpzionePredefinitoSpiegazione
openfalseApre subito la finestra della chat
markSubmittedfalseNasconde il modulo del visitatore se tutti i campi obbligatori sono compilati
onlyEmptyfalseSovrascrive solo i campi vuoti
persistfalseConserva i dati in localStorage (stesso browser, anche dopo una nuova scheda)

Opzioni per send:

OpzionePredefinitoSpiegazione
openfalseApre la finestra della chat prima dell'invio
silenttrue se open è falseNessun suono, nessun messaggio di errore nel widget; usa la Promise per successo o errore
markSubmittedtrueDopo l'invio i dati di contatto non devono essere reinseriti nel widget
metadata-Suggerimenti facoltativi per Tillie (non visibili nella finestra della chat); vedi metadata

Con open: false (predefinito) il pulsante della chat resta chiuso. Il messaggio arriva comunque a Tillor; il tuo modulo può ringraziare o mostrare un errore. Con open: true si apre la finestra della chat e il visitatore vede il normale comportamento di invio (suono, spunte, eventuali errori del widget).

Vuoi usare un pulsante tuo invece del pulsante di chat flottante? Imposta data-launcher="false" sullo snippet e chiama TillorInbox.open().

metadata (modulo di prenotazione)

Usa metadata quando hai un modulo tuo sul sito web e Tillie deve inviare solo una conferma, senza domande successive (ad esempio perché la scheda si chiude subito dopo).

ChiaveTipoSpiegazione
forceHandoverbooleanMessaggio di conferma e passaggio a un collega, senza domande di raccolta dati. Ignora anche la pausa dell'AI dopo un messaggio del team (vedi ignoreAiPause)
ignoreAiPausebooleanTillie risponde anche quando è in pausa in modalità Automatico dopo un messaggio del team (30 minuti). Utile per l'invio silenzioso di moduli; combinalo con forceHandover oppure lascia che Tillie faccia normalmente la raccolta dati
handoverIntent"reservation" | "caravan_rental" | "sale" | "other"Facoltativo: flusso per il passaggio (predefinito: dedotto automaticamente dal messaggio)
sourcestringEtichetta di integrazione facoltativa per il tuo team (lettere minuscole, cifre, -, _; max. 64 caratteri)
await TillorInbox.send({
  name: "Jan Janssens",
  email: "jan@voorbeeld.be",
  phone: "+32 3 779 81 64",
  body: structuredBookingMessage,
  silent: true,
  metadata: {
    forceHandover: true,
    handoverIntent: "reservation",
    source: "website_booking_form",
  },
});

Sostituire il modulo di contatto (invio silenzioso)

Usa questo quando vuoi mantenere il modulo di contatto esistente, ma far passare i messaggi da Tillor senza aprire la finestra della chat.

<form id="site-contact-form">
  <input name="name" type="text" required />
  <input name="email" type="email" required />
  <input name="phone" type="tel" />
  <textarea name="message" required></textarea>
  <button type="submit">Verstuur</button>
  <p id="contact-status" hidden></p>
</form>

<script>
  document.getElementById("site-contact-form").addEventListener("submit", async (event) => {
    event.preventDefault();
    const form = event.currentTarget;
    const status = document.getElementById("contact-status");
    const data = new FormData(form);

    try {
      await TillorInbox.send({
        name: String(data.get("name") ?? ""),
        email: String(data.get("email") ?? ""),
        phone: String(data.get("phone") ?? ""),
        body: String(data.get("message") ?? ""),
      });
      status.textContent = "Bedankt, we nemen snel contact op.";
      status.hidden = false;
      form.reset();
    } catch (error) {
      status.textContent = error instanceof Error ? error.message : "Versturen mislukt.";
      status.hidden = false;
    }
  });
</script>

Non devi impostare open e silent: senza open: true la finestra resta chiusa e Tillor tratta la chiamata come invio silenzioso.

Collegare il modulo di contatto (aprire la chat)

Passare i campi e aprire la finestra della chat, così il visitatore vede la conversazione:

<form id="site-contact-form">
  <input name="name" type="text" required />
  <input name="email" type="email" required />
  <input name="phone" type="tel" />
  <textarea name="message" required></textarea>
  <button type="submit">Verstuur</button>
</form>

<script>
  document.getElementById("site-contact-form").addEventListener("submit", (event) => {
    event.preventDefault();
    const form = event.currentTarget;
    const data = new FormData(form);
    void TillorInbox.send({
      name: String(data.get("name") ?? ""),
      email: String(data.get("email") ?? ""),
      phone: String(data.get("phone") ?? ""),
      body: String(data.get("message") ?? ""),
      open: true,
    });
  });
</script>

Oppure compilare solo i campi e aprire la finestra, senza inviare subito:

void TillorInbox.setVisitor(
  {
    name: "Jan Janssens",
    email: "jan@voorbeeld.be",
    phone: "+32 3 779 81 64",
    message: "Ik heb een vraag over de stacaravan te koop.",
  },
  { markSubmitted: true, open: true },
);

Una pagina di vendita con invio immediato e apertura della chat:

void TillorInbox.send({
  name: "Jan Janssens",
  email: "jan@voorbeeld.be",
  phone: "+32 3 779 81 64",
  body: "Ik heb interesse in deze stacaravan.",
  open: true,
});

Sincronizzare in tempo reale mentre qualcuno digita:

const form = document.getElementById("site-contact-form");
form.addEventListener("input", () => {
  void TillorInbox.setVisitor({
    name: form.name.value,
    email: form.email.value,
    phone: form.phone.value,
    message: form.message.value,
  });
});

Chiamare in anticipo (prima dello script del widget)

Se chiami un metodo prima che lo script sia caricato, metti la chiamata in coda:

<script>
  window.TillorInbox = window.TillorInbox || { q: [] };
  window.TillorInbox.q.push([
    "setVisitor",
    { name: "Jan", email: "jan@voorbeeld.be" },
    { open: true },
  ]);
</script>
<script src="https://tillor.eu/inbox-widget.js" data-org-id="org_abc123" data-widget-key="iwk_xxx" async defer></script>

Interfaccia di chat propria

Se crei un'interfaccia di chat tua invece del widget, usa il livello REST qui sotto.

Autenticazione: header X-Tillor-Inbox-Widget-Key (valore da Impostazioni > Integrazioni > Chat sul sito web).

Digitazione

POST /api/orgs/{orgId}/inbox/website/typing
X-Tillor-Inbox-Widget-Key: iwk_xxx
Content-Type: application/json

{
  "visitorId": "vis_…",
  "active": true,
  "visitorName": "Jan",
  "visitorEmail": "jan@voorbeeld.nl",
  "visitorPhone": "+32470123456"
}
  • active: true quando il visitatore digita; false quando il campo è vuoto o il visitatore smette (il widget invia false dopo circa 4 secondi senza input)
  • visitorName / visitorEmail / visitorPhone sono facoltativi
  • Usa lo stesso visitorId di POST …/inbox/website/messages e GET …/inbox/website/messages

Tempo reale (SSE)

GET /api/orgs/{orgId}/inbox/website/subscribe?visitorId=vis_…
X-Tillor-Inbox-Widget-Key: iwk_xxx
Accept: text/event-stream
EventoQuando
inbox:website:message-createdNuovo messaggio del team o dell'AI
inbox:website:message-updatedMessaggio del team o dell'AI modificato o eliminato
inbox:website:typing-changeddata.staffTyping o data.staffOutboundSenderType cambia

La forma del payload è la stessa dell'SSE dell'organizzazione (event, data, timestamp). Riconnettiti dopo un'interruzione; non c'è ripresa.

Il widget ufficiale usa SSE come livello primario e richiede di nuovo GET …/messages ogni 5 secondi come fallback (ogni 1 secondo con il pannello aperto quando SSE si interrompe per un momento). In questo modo le risposte vengono contrassegnate come consegnate finché il visitatore è sulla pagina.

Attività dei visitatori

POST /api/orgs/{orgId}/inbox/website/events
X-Tillor-Inbox-Widget-Key: iwk_xxx
Content-Type: application/json

event: chat_closed, tab_hidden o navigation (con la navigazione anche url). Il tuo team vede questi eventi come testo informativo grigio nella conversazione, vedi Conversazioni tramite Chat sul sito web.

Limiti

POST …/inbox/website/messages e POST …/inbox/website/attachments/upload rispondono 429 quando un visitatore o una rete invia troppo. Il corpo contiene data.reason = INBOX_WIDGET_RATE_LIMITED e data.retryAfterSeconds. Limiti per organizzazione:

PercorsoPer visitatore (visitorId)Per rete (indirizzo IP)
messages10 al minuto, 200 al giorno30 al minuto, 600 al giorno
attachments/upload10 all'ora50 all'ora

Aspetta retryAfterSeconds prima di riprovare e mostra un avviso al visitatore invece di riprovare automaticamente.

Vedi anche

Questa pagina è stata utile?

In questa pagina