Szczegóły techniczne
Protokół, kody błędów, dostępność i stan każdej obietnicy.
Ta strona jest dla tych, którzy chcą wiedzieć dokładnie. Wszystko tutaj jest zmierzone albo odczytane z kodu źródłowego — nic nie jest szacowane.
Jak ładuje się widget
Dwa etapy. Najpierw mały loader, który rysuje przycisk i nic więcej. Sam czat jest dociągany dopiero wtedy, gdy zadziała jeden z pięciu wyzwalaczy — kliknięcie w przycisk, polecenie ze strony, reguła, przewijanie albo licznik czasu.
Jest ku temu powód: większość odwiedzających nigdy nie otwiera czatu. Dla nich nie powinno ładować się nic, czego nie potrzebują.
- Loader: 2,83 kB (brotli)
- Cały widget: 59,2 kB gzip, 51,8 kB brotli
- Zanim przycisk będzie widoczny: 11–21 ms
- Przesunięcie układu: 0,0000 — miejsce jest zarezerwowane, zanim cokolwiek się pojawi
Dla porównania, również zmierzone: loader Crispa waży 2 876 B, Intercomu 3 161 B. Z 2 827 B jesteśmy na ich poziomie, a nie o rzędy wielkości niżej. Kto twierdzi inaczej, nie mierzył.
Nie przeszkadza Waszej stronie
Widget żyje w zamkniętym shadow DOM. Wasze style go nie dosięgną, jego style
nie dosięgną Waszej strony — nawet jeśli ustawicie
* { box-sizing: border-box } albo używacie frameworku CSS, który wszystko
przedefiniowuje.
Działa pod ścisłą Content Security Policy bez ani jednego komunikatu w
konsoli: żadnego eval, żadnej czcionki z sieci, żadnego piksela śledzącego.
Style ustawia przez konstruowalne arkusze stylów, których style-src nie
obejmuje. Przycisk, okno czatu, przewodniki po produkcie i **konsola agenta
na Waszej stronie** nie potrzebują więc unsafe-inline — zmierzone przy
style-src 'self', a nawet przy style-src 'none': zero naruszeń, pełne style.
Zmierzone w aktualnym Chromium; starsze przeglądarki bez konstruowalnych
arkuszy stylów (np. Safari przed 16.4) używają zastępczego elementu <style>,
który ścisła polityka blokuje.
Zero zapytań do obcych serwerów. Wszystko pochodzi z adresu, spod którego osadzacie widget.
Protokół
Połączenie działa przez WebSocket. Protokół jest wersjonowany i zna **25 kodów błędów** — każdy z ustaloną reakcją klienta (powtórzyć, nie powtarzać, zamknąć). Błąd spoza listy jest traktowany jak „nie powtarzać": lepiej jedna wiadomość za mało niż nieskończona pętla.
Ponowne łączenie z rosnącym odstępem. Gdy połączenie padnie, wiadomości trafiają do bufora i wychodzą, gdy tylko wróci. Każda wiadomość ma identyfikator; serwer rozpoznaje powtórzenia i nie zapisuje ich dwa razy.
Dostępność
Zbudowane zgodnie z WCAG 2.2 AA:
- Pułapka fokusu w otwartym oknie, ESC zamyka, fokus wraca tam, gdzie był
- Nowe wiadomości są zapowiadane przez
aria-live - Kontrast tekstu do tła jest przeliczany, a nie zakładany — patrz niżej
- W pełni obsługiwalne z klawiatury, widoczny pierścień fokusu
Kontrast jest przeliczany
Podajecie kolor. Tło przyjmuje dokładnie ten kolor. Tekst na nim jest przesuwany tak długo, aż osiągnie stosunek 4,5:1 — wymóg WCAG dla zwykłego tekstu.
Zmierzone na 178 kolorach w dwóch motywach i trzech parach, czyli 1 068 punktów pomiarowych: ani jeden poniżej 4,5:1, najgorsza wartość 4,50:1.
To jest różnica wobec innych dostawców: tam widget da się ustawić tak, że nikt go już nie przeczyta.
Dane osobowe
Maskowanie odbywa się w dwóch miejscach — w przeglądarce odwiedzającego, zanim cokolwiek opuści jego komputer, i jeszcze raz na serwerze, zanim cokolwiek zostanie zapisane. Rozpoznawane są numery kart (z kontrolą Luhna), IBAN-y, adresy e-mail, numery telefonów i długie ciągi cyfr.
Dwa miejsca, bo jedno nie wystarcza: to w przeglądarce da się wyłączyć, to na serwerze widzi tylko to, co dotrze.
Reguły
To, kiedy widget się odzywa, jest zapisane w deklaratywnej liście reguł — a nie w warunku w kodzie. Pięć reguł jest domyślnych (kliknięcie ze złości, błąd JavaScriptu, zamiar zakupu, zamiar wyjścia, bezczynność), własne można dodać.
Różnica jest praktyczna: zmiana reguły to zmiana jednej linii, a nie wdrożenie.
Integracje
Webhook i Slack są gotowe. Dla pozostałych dostawca jest w kodzie, ale większość nie działała jeszcze z prawdziwą usługą.
Każda integracja działa przez kolejkę z bezpiecznikiem: gdy usługa trzeciej strony się zawiesi, po kilku nieudanych próbach jest na jakiś czas pomijana. Wiadomość na czacie nigdy przez to nie czeka — to najważniejsza reguła w tej warstwie.
Czego jeszcze nie ma
Żeby nikt nie odkrył tego dopiero przy wdrażaniu:
- Most do MousePlayera odpytuje aktywnie, bo MousePlayer nie wysyła jeszcze uzgodnionych zdarzeń sam z siebie.
- API REST i interfejs agenta są zaczęte, nie skończone.
Stan na: