Skip to Content

API du chat du site web

Reliez votre propre formulaire au widget de chat ou créez votre propre interface de chat avec le SDK du widget, REST, la saisie, le SSE et l'activité des visiteurs.

Dernière mise à jour le

Vous installez le widget officiel dans l'application : voir Mettre le chat sur votre site. Les options du snippet se trouvent sur Paramètres du chat du site. Cette page s'adresse aux développeurs : le SDK du widget pour votre propre formulaire et la couche REST pour une interface de chat personnalisée. Voir OpenAPI, tag inbox.

SDK du widget

Après le chargement du script du widget, window.TillorInbox est disponible. Il vous permet de transmettre des coordonnées depuis votre propre formulaire (page de contact, détail d'une vente, demande de devis). Toutes les méthodes attendent que la configuration du widget soit chargée.

MéthodeDescription
ready()Promise résolue dès que le widget est chargé
getVisitor()Lit les coordonnées enregistrées dans localStorage et les champs du widget remplis ; synchrone, sans réseau
setVisitor({ name?, firstName?, lastName?, email?, phone?, message?, customFields? }, options?)Remplit les champs du chat sans envoyer
open()Ouvre la fenêtre de chat
close()Ferme la fenêtre de chat
toggle()Ouvre ou ferme la fenêtre de chat
send({ body, name?, firstName?, lastName?, email?, phone?, message?, customFields?, open?, silent?, markSubmitted?, metadata? })Envoie un message avec les coordonnées

getVisitor() renvoie cet objet :

ChampDescription
visitorIdID de ce visiteur dans ce navigateur (localStorage)
nameNom complet (un seul champ dans le widget)
firstName / lastNameDéduits de name (premier mot / reste)
email, phoneCoordonnées
customFieldsChamps supplémentaires issus des paramètres du widget
messageBrouillon dans le champ de message
detailsSubmittedIndique si le formulaire du visiteur est considéré comme rempli

Utilisez getVisitor() pour préremplir votre propre formulaire depuis localStorage (même navigateur, aussi après un rafraîchissement de la page).

Options pour setVisitor (deuxième argument) :

OptionPar défautExplication
openfalseOuvrir directement la fenêtre de chat
markSubmittedfalseMasquer le formulaire du visiteur si tous les champs obligatoires sont remplis
onlyEmptyfalseN'écraser que les champs vides
persistfalseConserver les données dans localStorage (même navigateur, aussi après un nouvel onglet)

Options pour send :

OptionPar défautExplication
openfalseOuvrir la fenêtre de chat avant l'envoi
silenttrue si open vaut falsePas de son, pas de message d'erreur dans le widget ; utilisez la Promise pour le succès ou l'échec
markSubmittedtrueLes coordonnées n'ont plus besoin d'être saisies à nouveau dans le widget
metadata-Indications facultatives pour Tillie (non visibles dans la fenêtre de chat) ; voir metadata

Avec open: false (par défaut), le bouton de chat reste fermé. Le message part bien vers Tillor ; votre propre formulaire peut remercier ou afficher une erreur. Avec open: true, la fenêtre de chat s'ouvre et le visiteur voit le comportement d'envoi habituel (son, coches, éventuelles erreurs du widget).

Vous voulez utiliser votre propre bouton à la place du bouton de chat flottant ? Mettez data-launcher="false" sur le snippet et appelez TillorInbox.open().

metadata (formulaire de réservation)

Utilisez metadata lorsque vous avez votre propre formulaire sur le site et que Tillie doit uniquement envoyer une confirmation, sans questions de suivi (par exemple parce que l'onglet se ferme ensuite).

CléTypeExplication
forceHandoverbooleanMessage de confirmation et transfert à un collègue, sans questions d'admission. Ignore aussi la pause de l'IA après un message de l'équipe (voir ignoreAiPause)
ignoreAiPausebooleanTillie répond aussi lorsqu'elle est en pause en mode Automatique après un message de l'équipe (30 minutes). Pratique pour un envoi de formulaire silencieux ; combinez avec forceHandover ou laissez Tillie mener l'admission normalement
handoverIntent"reservation" | "caravan_rental" | "sale" | "other"Facultatif : flux pour le transfert (par défaut : déduit automatiquement du message)
sourcestringLibellé d'intégration facultatif pour votre équipe (minuscules, chiffres, -, _ ; 64 caractères max.)
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",
  },
});

Remplacer le formulaire de contact (envoi silencieux)

Utilisez ceci si vous voulez garder le formulaire de contact existant, mais faire passer les messages par Tillor sans ouvrir la fenêtre de 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>

Vous n'avez pas besoin de définir open ni silent : sans open: true, la fenêtre reste fermée et Tillor traite l'appel comme un envoi silencieux.

Relier le formulaire de contact (ouvrir le chat)

Transmettre les champs et ouvrir la fenêtre de chat, pour que le visiteur voie la conversation :

<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>

Ou seulement remplir les champs et ouvrir la fenêtre, sans envoyer tout de suite :

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 },
);

Une page de vente avec envoi direct et ouverture du 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,
});

Synchroniser en direct pendant que quelqu'un tape :

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,
  });
});

Appeler tôt (avant le script du widget)

Si vous appelez une méthode avant que le script soit chargé, mettez l'appel en file d'attente :

<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>

Interface de chat personnalisée

Si vous créez votre propre interface de chat à la place du widget, vous utilisez la couche REST ci-dessous.

Authentification : en-tête X-Tillor-Inbox-Widget-Key (valeur issue de Paramètres > Intégrations > Chat du site web).

Saisie

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 lorsque le visiteur tape ; false lorsque le champ est vide ou que le visiteur arrête (le widget envoie false après environ 4 secondes sans saisie)
  • visitorName / visitorEmail / visitorPhone sont facultatifs
  • Utilisez le même visitorId que pour POST …/inbox/website/messages et GET …/inbox/website/messages

Temps réel (SSE)

GET /api/orgs/{orgId}/inbox/website/subscribe?visitorId=vis_…
X-Tillor-Inbox-Widget-Key: iwk_xxx
Accept: text/event-stream
ÉvénementQuand
inbox:website:message-createdNouveau message de l'équipe ou de l'IA
inbox:website:message-updatedMessage de l'équipe ou de l'IA modifié ou supprimé
inbox:website:typing-changeddata.staffTyping ou data.staffOutboundSenderType change

Le format du payload est le même que pour le SSE de l'organisation (event, data, timestamp). Reconnectez-vous après une coupure ; il n'y a pas de reprise.

Le widget officiel utilise le SSE comme couche principale et récupère GET …/messages toutes les 5 secondes en solution de repli (toutes les secondes avec le panneau ouvert lorsque le SSE se coupe un instant). Ainsi, les réponses sont marquées comme remises tant que le visiteur est sur la page.

Activité des visiteurs

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

event : chat_closed, tab_hidden ou navigation (pour la navigation, aussi url). Votre équipe voit ces événements sous forme de texte d'information grisé dans la conversation, voir Conversations via le chat du site.

Limites

POST …/inbox/website/messages et POST …/inbox/website/attachments/upload répondent 429 quand un visiteur ou un réseau envoie trop. Le corps contient data.reason = INBOX_WIDGET_RATE_LIMITED et data.retryAfterSeconds. Limites par organisation :

RoutePar visiteur (visitorId)Par réseau (adresse IP)
messages10 par minute, 200 par jour30 par minute, 600 par jour
attachments/upload10 par heure50 par heure

Attends retryAfterSeconds avant de réessayer, et affiche un message au visiteur au lieu de réessayer automatiquement.

Voir aussi

Cette page t'a-t-elle été utile ?

Sur cette page