Технические подробности
Протокол, коды ошибок, доступность и состояние, стоящее за каждым обещанием.
Эта страница для тех, кому нужны подробности. Всё здесь измерено или прочитано в исходном коде; оценок на глаз нет.
Как загружается виджет
В два этапа. Сначала небольшой загрузчик, который рисует кнопку и больше ничего не делает. Сам чат загружается лишь при одном из пяти триггеров: браузер простаивает (не позднее трёх секунд), мышь или палец над кнопкой, команда со страницы, сигнал затруднений от MousePlayer или push-сигнал, например от вашего service worker.
Причина есть: большинство посетителей никогда не открывает чат. Для них он не должен задерживать загрузку страницы; действующие триггеры задаются в теге скрипта.
- Загрузчик: 3,48 кБ при передаче нашим CDN с gzip
- Весь виджет: 85,5 кБ при такой же передаче и только после срабатывания триггера
- До появления кнопки: 11–21 мс
- Сдвиг макета: 0,0000 — место резервируется до появления элементов
Для сравнения — тоже измерено, все три сжаты brotli: загрузчик Crisp — 2 876 Б, Intercom — 3 161 Б. Наши 3 069 Б находятся между ними, а не на порядки ниже. Кто утверждает иначе, не измерял.
Он не мешает сайту
Виджет находится в закрытом shadow DOM. Ваши стили не проникают в него, его стили не проникают в страницу, даже если задать * { box-sizing: border-box } или использовать CSS-фреймворк, который переопределяет всё.
Он работает при строгой Content Security Policy без единого сообщения в консоли: без eval, веб-шрифтов и пикселей отслеживания. Стили задаются через создаваемые таблицы стилей, на которые style-src не распространяется. Поэтому кнопке, окну чата, турам по продукту и консоли операторов на вашем сайте не нужен unsafe-inline: измерено с style-src 'self' и даже style-src 'none' — ноль нарушений, полное оформление. Измерено в актуальном Chromium; старые браузеры без создаваемых таблиц стилей (например, Safari до 16.4) используют элемент <style>, который строгая политика блокирует.
Ноль запросов к другим серверам. Всё приходит из reactive.chat или, при собственном домене, с вашего адреса; изображения вроде логотипа и аватаров — с указанных вами адресов.
Протокол
Соединение использует WebSocket; там, где сеть не пропускает WebSocket, — обычные HTTPS-запросы (Server-Sent Events или длинный опрос). Протокол версионируется и определяет 31 код ошибки, 26 для виджета, остальные для панели операторов и поиска по сайту. У каждого предписанное действие клиента (повтор сразу, после ожидания, после переподключения, не повторять), у некоторых также код закрытия. Ошибка вне списка обрабатывается как временная серверная: повтор после ожидания, а после пяти попыток сообщение считается недоставленным и его можно отправить снова — без бесконечного цикла.
Переподключение с растущей задержкой. При обрыве сообщения попадают в буфер и отправляются после восстановления связи. Каждое имеет ID; сервер распознаёт повторы и не сохраняет их дважды.
Доступность
Разработано с учётом WCAG 2.2 AA:
- Фокус удерживается в открытом окне, ESC закрывает его, фокус возвращается на прежнее место
- Новые сообщения озвучиваются через
aria-live - Контраст текста и поверхности вычисляется, а не предполагается — см. ниже
- Полное управление клавиатурой, видимая рамка фокуса
Контраст вычисляется
Вы задаёте цвет. Поверхность получает именно его. Текст на ней корректируется до коэффициента 4,5:1 — требования WCAG для обычного текста.
Измерено на 178 цветах, в двух темах и трёх сочетаниях, то есть 1 068 точках данных: ни одной ниже 4,5:1, худшее значение — 4,50:1.
В этом отличие от других сервисов: там виджет можно настроить так, что его никто не сможет прочитать.
Персональные данные
Маскирование выполняется в двух местах: в браузере посетителя до выхода данных с устройства и снова на сервере до сохранения. Распознаются номера карт (с проверкой Луна), IBAN, электронная почта, телефоны, налоговые номера и номера удостоверений личности. Номера заказов и клиентов не меняются.
Два места нужны потому, что одного недостаточно: браузерное маскирование можно отключить, сервер видит лишь то, что пришло.
Правила
Когда виджет обращается к посетителю, задаётся декларативным списком правил, а не условием в коде. По умолчанию поставляются шесть правил (длительное пребывание на странице, раздражённый клик, ошибка JavaScript, затруднение с формой, намерение купить, уход с оформления заказа); раздражённый клик, затруднение с формой и намерение купить обнаруживаются только вместе с MousePlayer. Собственные правила можно добавить в аккаунте. На Free действует одно активное обращение на проект.
Разница практическая: изменение правила — это настройка в аккаунте, а не развёртывание кода.
Интеграции
Вебхуки и Slack готовы. Для более чем 30 других сервисов подключение подготовлено; большинство проверено с имитациями внешних сервисов, но никогда не работало с настоящим сервисом, и страница интеграций в аккаунте это отмечает.
Серверный API (REST и MCP) читает разговоры, сообщения, проекты, посетителей, события и правила, записывает сообщения и события и регистрирует вебхуки. Список посетителей и MCP можно отключить для отдельных проектов.
Каждая интеграция проходит через очередь с предохранителем: если сторонний сервис зависает, после повторных сбоев он на время пропускается. Сообщение чата никогда из-за него не задерживается — это важнейшее правило этого уровня.
Что не завершено
Чтобы это не выяснялось при интеграции:
- Мост MousePlayer использует опрос, потому что MousePlayer ещё не выдаёт согласованные события сам.
- Вложения, A/B-тесты и собственный домен работают в бета-режиме: они работают и измерены, но ещё могут измениться.
- Каналы электронной почты, Telegram, SMS, WhatsApp, Messenger и Instagram проверены с имитациями, пока не с настоящими аккаунтами. Если ответ через канал окончательно не доставлен, сейчас это не отображается в разговоре.
Подробнее в документации
Взаимодействие виджета, сервера и подключения: Архитектура и порядок работы. Подключение, резервный канал HTTP и переподключение: Транспорт. Все главы: Документация.
Обновлено: