Dokumentacja
Wszystko, czego potrzebuje wdrożeniowiec
Jedna strona: snippet, API przeglądarkowe, taksonomia zdarzeń, CSP i SRI, proxy first-party, API serwerowe, webhooki, szablon GTM i SDK mobilne.
Instalacja snippetu
Jedyny skrypt, który wkleja się do sklepu, to loader. Ładuje się asynchronicznie, nie zawiera sekretów i sam dobiera wersję trackera zgodnie z ustawieniami sklepu.
<script async src="https://www.alabot.app/sdk/v1/ala-loader.js" data-site-key="pk_live_00000000000000000000000000000000"></script>Jeśli menedżer tagów nie pozwala ustawić atrybutów, klucz można przekazać w adresie skryptu.
<script async src="https://www.alabot.app/sdk/v1/ala-loader.js?k=pk_live_00000000000000000000000000000000"></script>Obsługiwane atrybuty
- data-site-key
- Klucz publiczny sklepu w formacie pk_live_… lub pk_test_…. Wymagany; loader kończy pracę, gdy klucz nie pasuje do wzorca.
- ?k=
- Alternatywa dla data-site-key: ten sam klucz przekazany jako parametr adresu skryptu.
- data-endpoint
- Origin proxy first-party. Ustawiony przejmuje zarówno adres API, jak i adres, spod którego ładowane są pozostałe moduły.
- data-debug="true"
- Włącza logi diagnostyczne loadera w konsoli przeglądarki. Do użytku na środowiskach testowych.
- nonce / data-nonce
- Nonce polityki CSP. Loader przepisze go na skrypty, które sam dołącza (tracker, czat, nagrania).
Loader pobiera publiczną konfigurację sklepu, honoruje wyłącznik awaryjny i dopiero potem dołącza tracker. Brak dostępu do skryptu nie blokuje renderowania sklepu.
Teksty widgetu — nazwę w nagłówku, powitanie zapasowe czy etykiety przycisków — można nadpisać w panelu sklepu w ustawieniach czatu; loader pobiera je razem z konfiguracją, a puste pola zostają przy domyślnych tekstach Ali.
API przeglądarkowe Ala.*
Globalny obiekt Ala jest tworzony natychmiast, jeszcze przed załadowaniem trackera — wywołania wykonane wcześniej trafiają do kolejki i są odtwarzane w kolejności po starcie.
Ala.ready(function () {
Ala.identify("customer-1024", { segment: "vip" });
Ala.setProductContext({ productId: "SKU-123", price: 399, currency: "PLN" });
Ala.setCart({ items: [{ productId: "SKU-123", quantity: 1, price: 399 }], subtotal: 399, currency: "PLN" });
Ala.track("size_guide_opened", { productId: "SKU-123" });
Ala.on("intervention", function (intervention) { console.log(intervention.type); });
});- Ala.ready(cb)
- Uruchamia callback, gdy runtime jest gotowy. Wywołany później działa natychmiast.
- Ala.track(type, props?)
- Zdarzenie własne. Nazwa jest walidowana i automatycznie poprzedzana prefiksem custom:.
- Ala.page(props?)
- Ręczne zgłoszenie odsłony — przydatne w aplikacjach SPA z nietypowym routingiem.
- Ala.identify(customerId, traits?, userHash?)
- Łączy sesję z identyfikatorem klienta sklepu; opcjonalnie przyjmuje cechy oraz podpis weryfikujący tożsamość.
- Ala.reset()
- Kończy bieżącą tożsamość i sesję, np. po wylogowaniu klienta ze sklepu.
- Ala.setCart(cart)
- Aktualizuje kontekst koszyka: pozycje, wartość, waluta, rabaty, próg darmowej dostawy.
- Ala.setProductContext(product | null)
- Ustawia kontekst oglądanego produktu; null czyści kontekst przy wyjściu z karty.
- Ala.purchase(purchase)
- Zgłasza zakup po stronie klienta. Źródłem prawdy o zamówieniach pozostaje API serwerowe.
- Ala.setConsent(consent)
- Ustawia zgody dla modułów: analityka, nagrania, czat, personalizacja, marketing.
- Ala.on(event, cb)
- Podpina nasłuch zdarzenia SDK.
- Ala.off(event, cb)
- Odpina wcześniej podpięty nasłuch.
- Ala.open()
- Otwiera okno czatu programowo.
- Ala.close()
- Zamyka okno czatu programowo.
- Ala.debug(enabled)
- Włącza lub wyłącza logi diagnostyczne w trakcie działania.
- Ala.addToCart = (productId, variantId?, quantity?) => {}
- Opcjonalny hak sklepu. Gdy go zdefiniujesz, przycisk „Dodaj do koszyka” w czacie wywoła Twoją funkcję.
- Ala.config
- Publiczna konfiguracja sklepu widziana przez SDK — bez sekretów i bez danych panelu.
Zdarzenia
Taksonomia jest wspólna dla SDK i serwera. Zdarzenia spoza listy trafiają do rejestru jako wykryte i można je opisać w panelu.
Zdarzenia ecommerce
Te nazwy rozpoznaje silnik analityczny. Jeśli sklep ma wdrożoną warstwę danych GA4, adapter mapuje standardowe zdarzenia automatycznie — bez dodatkowego kodu.
- view_item_list
- select_item
- view_item
- view_category
- add_to_cart
- remove_from_cart
- view_cart
- begin_checkout
- add_payment_info
- purchase
- refund
Nasłuchy Ala.on
Zdarzenia magistrali SDK: informują stronę o tym, co dzieje się wewnątrz asystentki.
- Ala.on("ready", cb)
- Runtime jest gotowy; callback dostaje obiekt Ala.
- Ala.on("intervention", cb)
- Silnik reguł wskazał interwencję do pokazania (np. otwarcie czatu lub podpowiedź).
- Ala.on("consent", cb)
- Zmienił się stan zgód dla modułów SDK.
- Ala.on("session", cb)
- Rozpoczęła się nowa sesja wizytora.
- Ala.on("config", cb)
- Konfiguracja sklepu zmieniła się od momentu załadowania SDK.
- Ala.on("replay", cb)
- Sygnał modułu nagrań — np. żądanie rozpoczęcia zapisu sesji.
Ala.track dopisuje prefiks custom:, więc własne zdarzenia nigdy nie kolidują z taksonomią systemową.
CSP i SRI
Jeśli sklep ma Content Security Policy, dopisz dyrektywy poniżej. Nie wymagamy 'unsafe-inline' ani 'unsafe-eval'.
script-src 'self' https://www.alabot.app;
connect-src 'self' https://www.alabot.app;
style-src 'self' https://www.alabot.app;
img-src 'self' data: https://res.cloudinary.com;Przy polityce opartej na nonce przekaż wartość w atrybucie skryptu loadera. Loader ustawi ten sam nonce na skryptach trackera, czatu i nagrań, które dołącza dynamicznie.
Subresource Integrity
Build SDK liczy skrót sha384 każdego pliku i zapisuje go w manifeście wersji. Dlatego nie publikujemy hashy w dokumentacji: zmieniają się przy każdym wydaniu, a manifest jest zawsze aktualny.
- Pobierz manifest wersji, na której stoi Twój sklep.
- Odczytaj pole integrity dla pliku ala-loader.js.
- Dodaj atrybuty integrity oraz crossorigin="anonymous" do tagu skryptu.
- Przy aktualizacji wersji SDK odczytaj hash ponownie — pliki wersjonowane są niezmienne, ale nowa wersja ma nowe skróty.
curl -s https://www.alabot.app/sdk/1.0.0/manifest.jsonProxy first-party
W trybie first-party skrypt i API są serwowane z Twojej domeny. Ogranicza to blokowanie przez rozszerzenia prywatności i upraszcza politykę bezpieczeństwa sklepu.
- Wybierz jeden prefiks na swojej domenie, np. /ala/.
- Skonfiguruj reverse proxy z tego prefiksu na ścieżkę /api/v1/proxy/ aplikacji.
- Aplikacja przepisuje /api/v1/proxy/sdk/* na pliki SDK, a /api/v1/proxy/api/v1/* na publiczne API.
- W panelu sklepu ustaw host proxy w polu konfiguracji SDK — snippet wyświetlany w panelu zacznie używać Twojej domeny.
- W snippecie dodaj atrybut data-endpoint wskazujący ten sam prefiks.
location /ala/ {
proxy_pass https://www.alabot.app/api/v1/proxy/;
proxy_set_header Host $host;
}<script async src="https://shop.example/ala/sdk/v1/ala-loader.js"
data-site-key="pk_live_…"
data-endpoint="https://shop.example/ala"></script>Proxy musi przekazywać nagłówki żądania bez zmian. Pliki SDK są wersjonowane i mogą być cache’owane bezterminowo; odpowiedzi API nie mogą być cache’owane.
API serwerowe
Backend sklepu jest źródłem prawdy o zamówieniach. Jednym żądaniem można przesłać do stu zdarzeń typu purchase, refund i identify.
POST https://www.alabot.app/api/v1/server-events- Authorization: Bearer sk_live_…
- Klucz tajny sklepu. Nigdy nie umieszczaj go w kodzie wykonywanym w przeglądarce.
- Content-Type: application/json
- Treść żądania jest dokumentem JSON.
- X-Ala-Signature: t=<unix>,v1=<hex>
- Opcjonalny podpis żądania. Gdy nagłówek jest obecny, musi być poprawny; tolerancja znacznika czasu to 5 minut.
- X-Correlation-Id: <id>
- Opcjonalny identyfikator korelacji. Wraca w odpowiedzi i ułatwia powiązanie logów po obu stronach.
{
"events": [
{
"type": "purchase",
"orderId": "1042",
"anonymousId": "8f1c0b3a-6a1d-4f6e-9a1f-0f4b2c7d9e10",
"customerId": "customer-1024",
"revenue": 499.00,
"tax": 93.31,
"shipping": 0,
"currency": "PLN",
"status": "paid",
"items": [{ "productId": "SKU-123", "quantity": 1, "unitPrice": 499.00 }]
},
{ "type": "refund", "orderId": "1042", "amount": 499.00, "reason": "return" },
{
"type": "identify",
"anonymousId": "8f1c0b3a-6a1d-4f6e-9a1f-0f4b2c7d9e10",
"customerId": "customer-1024",
"email": "customer@example.com"
}
]
}curl -X POST https://www.alabot.app/api/v1/server-events \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-d @events.jsonZamówienie jest deduplikowane po identyfikatorze, więc powtórzone wysłanie tego samego zdarzenia nie zdubluje sprzedaży. Kwoty podaje się w jednostkach głównych waluty.
Webhooki wychodzące
Endpoint sklepu może subskrybować zdarzenia biznesowe. Każde żądanie jest podpisane, a nieudane dostarczenia są ponawiane według stałego harmonogramu.
- conversation.started
- Rozpoczęła się nowa rozmowa z asystentką.
- handoff.requested
- Rozmowa czeka na operatora.
- lead.created
- Asystentka zebrała dane kontaktowe od wizytora.
- high_intent.detected
- Sesja przekroczyła próg intencji zakupowej ustawiony w regułach.
- discount.offered
- Zaproponowano rabat po sprawdzeniu progu marży.
- purchase.attributed
- Zamówienie zostało przypisane do wcześniejszej interakcji z asystentką.
- automation.triggered
- Uruchomiła się automatyzacja skonfigurowana w panelu.
Weryfikacja podpisu
Podpis liczony jest z sekretu endpointu nad ciągiem złożonym ze znacznika czasu, kropki i surowej treści żądania. Porównuj wartości w sposób odporny na pomiar czasu i sprawdzaj świeżość znacznika.
import { createHmac, timingSafeEqual } from "node:crypto";
const header = request.headers["x-ala-signature"]; // t=1758067200,v1=9f86d0…
const parts = Object.fromEntries(header.split(",").map((p) => p.trim().split("=")));
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) <= 300;
const expected = createHmac("sha256", endpointSecret).update(`${parts.t}.${rawBody}`).digest("hex");
const valid = fresh && timingSafeEqual(Buffer.from(expected, "hex"), Buffer.from(parts.v1, "hex"));- Ponowienia: 1 minuta, 5 minut, 15 minut, 1 godzina, 4 godziny, 12 godzin.
- Po wyczerpaniu prób dostarczenie trafia do martwej kolejki i jest widoczne w panelu.
- Po serii kolejnych niepowodzeń endpoint jest automatycznie pauzowany.
- Akceptowane są wyłącznie adresy https; adresy w sieciach prywatnych są odrzucane.
- Limit czasu pojedynczej próby to 10 sekund, a odczytywana odpowiedź jest ograniczona rozmiarem.
- Sekret endpointu można zrotować w panelu — nowy sekret zwracany jest jednorazowo.
Szablon Google Tag Manager
Zamiast wklejać skrypt do szablonu sklepu, można zaimportować gotowy szablon niestandardowy i wypełnić dwa pola.
- Pobierz plik szablonu i zaimportuj go w GTM: Szablony → Szablony tagów → Nowy → Importuj.
- Utwórz tag z tego szablonu i wklej klucz publiczny sklepu.
- Jeśli używasz proxy first-party, uzupełnij pole origin skryptów wartością ze strony instalacji w panelu.
- Ustaw regułę uruchomienia na wszystkie strony i opublikuj kontener.
- Zgody i mapowanie zdarzeń ecommerce konfigurujesz w GTM — nic nie trzeba dopisywać w szablonie sklepu.
Szablon przekazuje klucz w adresie skryptu, bo menedżer tagów nie ustawia atrybutów data-* na wstrzykiwanym tagu.
SDK mobilne (Expo)
Pakiet dla aplikacji React Native obsługuje te same punkty końcowe co SDK przeglądarkowe i udostępnia osobnego klienta dla aplikacji operatorskiej.
- AlaTracker
- AlaChat
- AlaClient
npm install @alaaibot/sdk-expoimport AsyncStorage from "@react-native-async-storage/async-storage";
import { AlaTracker, AlaChat } from "@alaaibot/sdk-expo";
const tracker = new AlaTracker({ siteKey: "pk_live_…", apiBase: "https://www.alabot.app", storage: AsyncStorage });
await tracker.start();
tracker.screen("ProductDetail", { productId: "SKU-123" });
const chat = new AlaChat(tracker);
await chat.open();AlaTracker i AlaChat używają klucza publicznego sklepu. AlaClient służy aplikacji operatorskiej i uwierzytelnia się tokenem sesji pracownika przechowywanym w bezpiecznym magazynie urządzenia.