API Chat pe site-ul web
Conectați un formular propriu la widgetul de chat sau construiți o interfață de chat proprie cu SDK-ul widgetului, REST, tastare, SSE și activitatea vizitatorilor.
Ultima actualizare la
Widgetul oficial îl instalați în aplicație: consultați Puneți chatul pe site-ul dumneavoastră. Opțiunile snippetului se află la Setările Chatului pe site-ul web. Această pagină este pentru dezvoltatori: SDK-ul widgetului pentru un formular propriu și stratul REST pentru o interfață de chat proprie. Consultați OpenAPI, tagul inbox.
SDK-ul widgetului
După încărcarea scriptului widgetului, window.TillorInbox este disponibil. Cu el transmiteți date de contact de la propriul formular (pagina de contact, detaliu de vânzare, cerere de ofertă). Toate metodele așteaptă până când configurația widgetului este încărcată.
| Metodă | Descriere |
|---|---|
ready() | Promise care se rezolvă imediat ce widgetul este încărcat |
getVisitor() | Citește datele de contact salvate din localStorage și câmpurile widgetului completate; sincron, fără rețea |
setVisitor({ name?, firstName?, lastName?, email?, phone?, message?, customFields? }, options?) | Completează câmpurile chatului fără a trimite |
open() | Deschide fereastra de chat |
close() | Închide fereastra de chat |
toggle() | Deschide sau închide fereastra de chat |
send({ body, name?, firstName?, lastName?, email?, phone?, message?, customFields?, open?, silent?, markSubmitted?, metadata? }) | Trimite un mesaj cu date de contact |
getVisitor() returnează acest obiect:
| Câmp | Descriere |
|---|---|
visitorId | ID-ul acestui vizitator în acest browser (localStorage) |
name | Numele complet (un singur câmp în widget) |
firstName / lastName | Derivate din name (primul cuvânt / restul) |
email, phone | Date de contact |
customFields | Câmpuri suplimentare din setările widgetului |
message | Ciorna din câmpul de mesaj |
detailsSubmitted | Dacă formularul vizitatorului este considerat completat |
Folosiți getVisitor() pentru a precompleta un formular propriu din localStorage (același browser, chiar și după reîmprospătarea paginii).
Opțiuni pentru setVisitor (al doilea argument):
| Opțiune | Implicit | Explicație |
|---|---|---|
open | false | Deschide imediat fereastra de chat |
markSubmitted | false | Ascunde formularul vizitatorului dacă toate câmpurile obligatorii sunt completate |
onlyEmpty | false | Suprascrie doar câmpurile goale |
persist | false | Păstrează datele în localStorage (același browser, chiar și după o filă nouă) |
Opțiuni pentru send:
| Opțiune | Implicit | Explicație |
|---|---|---|
open | false | Deschide fereastra de chat înainte de trimitere |
silent | true dacă open este false | Fără sunet, fără mesaj de eroare în widget; folosiți Promise pentru succes sau eroare |
markSubmitted | true | Datele de contact nu mai trebuie introduse din nou în widget |
metadata | - | Indicii opționale pentru Tillie (nevizibile în fereastra de chat); consultați metadata |
Cu open: false (implicit), butonul de chat rămâne închis. Mesajul ajunge totuși la Tillor; formularul dumneavoastră poate mulțumi sau poate afișa o eroare. Cu open: true, fereastra de chat se deschide, iar vizitatorul vede comportamentul normal de trimitere (sunet, bife, eventuale erori ale widgetului).
Doriți să folosiți un buton propriu în locul butonului plutitor de chat? Setați data-launcher="false" pe snippet și apelați TillorInbox.open().
metadata (formular de rezervare)
Folosiți metadata când aveți un formular propriu pe site și Tillie trebuie să trimită doar o confirmare, fără întrebări suplimentare (de exemplu pentru că fila se închide după aceea).
| Cheie | Tip | Explicație |
|---|---|---|
forceHandover | boolean | Mesaj de confirmare și predare către un coleg, fără întrebări de preluare. Ignoră și pauza AI după un mesaj al echipei (consultați ignoreAiPause) |
ignoreAiPause | boolean | Tillie răspunde și atunci când este în pauză în modul Automat după un mesaj al echipei (30 de minute). Util pentru trimiteri silențioase de formulare; combinați cu forceHandover sau lăsați Tillie să facă preluarea normal |
handoverIntent | "reservation" | "caravan_rental" | "sale" | "other" | Opțional: fluxul pentru predare (implicit: dedus automat din mesaj) |
source | string | Etichetă de integrare opțională pentru echipa dumneavoastră (litere mici, cifre, -, _; max. 64 de caractere) |
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",
},
});Înlocuirea formularului de contact (trimitere silențioasă)
Folosiți această variantă când doriți să păstrați formularul de contact existent, dar să faceți ca mesajele să treacă prin Tillor fără a deschide fereastra 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>Nu trebuie să setați open și silent: fără open: true, fereastra rămâne închisă, iar Tillor tratează apelul ca pe o trimitere silențioasă.
Conectarea formularului de contact (deschiderea chatului)
Transmiteți câmpurile și deschideți fereastra de chat, astfel încât vizitatorul să vadă conversația:
<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>Sau doar completați câmpurile și deschideți fereastra, fără a trimite imediat:
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 },
);O pagină de vânzare cu trimitere directă și deschiderea chatului:
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,
});Sincronizare live în timp ce cineva tastează:
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,
});
});Apelare timpurie (înainte de scriptul widgetului)
Dacă apelați o metodă înainte ca scriptul să fie încărcat, puneți apelul în coadă:
<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>Interfață de chat proprie
Dacă construiți o interfață de chat proprie în locul widgetului, folosiți stratul REST de mai jos.
Autentificare: antetul X-Tillor-Inbox-Widget-Key (valoarea din Setări > Integrări > Widget de chat site web).
Tastare
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: truecând vizitatorul tastează;falsecând câmpul este gol sau vizitatorul se oprește (widgetul trimitefalsedupă aproximativ 4 secunde fără intrare)visitorName/visitorEmail/visitorPhonesunt opționale- Folosiți același
visitorIdca laPOST …/inbox/website/messagesșiGET …/inbox/website/messages
Timp real (SSE)
GET /api/orgs/{orgId}/inbox/website/subscribe?visitorId=vis_…
X-Tillor-Inbox-Widget-Key: iwk_xxx
Accept: text/event-stream| Eveniment | Când |
|---|---|
inbox:website:message-created | Mesaj nou de la echipă sau de la AI |
inbox:website:message-updated | Mesaj al echipei sau al AI modificat sau șters |
inbox:website:typing-changed | data.staffTyping sau data.staffOutboundSenderType se schimbă |
Forma payloadului este aceeași ca la SSE la nivel de organizație (event, data, timestamp). Reconectați-vă după o întrerupere; nu există reluare.
Widgetul oficial folosește SSE ca strat principal și preia din nou GET …/messages la fiecare 5 secunde ca soluție de rezervă (la fiecare 1 secundă cu panoul deschis, când SSE se întrerupe temporar). Astfel, răspunsurile sunt marcate ca livrate cât timp vizitatorul se află pe pagină.
Activitatea vizitatorilor
POST /api/orgs/{orgId}/inbox/website/events
X-Tillor-Inbox-Widget-Key: iwk_xxx
Content-Type: application/jsonevent: chat_closed, tab_hidden sau navigation (la navigare și url). Echipa dumneavoastră vede aceste evenimente ca text informativ gri în conversație, consultați Conversații prin Chat pe site-ul web.
Limite
POST …/inbox/website/messages și POST …/inbox/website/attachments/upload răspund cu 429 când un vizitator sau o rețea trimite prea mult. Corpul conține data.reason = INBOX_WIDGET_RATE_LIMITED și data.retryAfterSeconds. Limite per organizație:
| Rută | Per vizitator (visitorId) | Per rețea (adresă IP) |
|---|---|---|
messages | 10 pe minut, 200 pe zi | 30 pe minut, 600 pe zi |
attachments/upload | 10 pe oră | 50 pe oră |
Așteaptă retryAfterSeconds înainte să încerci din nou și arată-i vizitatorului un mesaj în loc să reîncerci automat.