Меню руководств

Виджет для сайта

Виджет — это чат, который посетители видят на вашем сайте. Он загружает опубликованного вами бота и ведёт весь диалог в браузере. Без языковой модели, без запросов к сторонним сервисам, размер после сжатия — около 22 КБ. Чат с оператором загружается из отдельного файла, только когда вы его включаете.

Установка

Вставьте эту строку перед </body> на каждой странице, где должен появляться бот. В панели управления на странице Установка эта строка уже содержит ваш ключ.

HTML
<script src="https://cdn.kavchat.com/v1/kavchat.js" data-key="pk_live_..." async></script>

Публичный ключ (pk_live_...) можно размещать на странице. Секретный ключ (sk_live_...) нельзя размещать на странице ни в коем случае.

Атрибуты

АтрибутПо умолчаниюОписание
data-keyОбязательныйВаш публичный ключ.
data-apihttps://api.kavchat.comАдрес API.
data-localeЯзык браузераЯзык интерфейса виджета (кнопок, формы, уведомлений): he, en, ar, ru, es, fr, de, pt, it, tr. Если перевода на этот язык нет, используется язык бота. Содержимое сценария всегда отображается так, как вы его написали. Для he и ar используется направление справа налево.
data-user-tokenНетТокен идентификации пользователя, вошедшего в систему. См. Идентификация пользователей.
data-user-nameНетОтображается в приветствии ({name}) и заранее подставляется в форму обращения.
data-openfalseПри значении "true" чат открывается сразу после загрузки.
HTML
<script
  src="https://cdn.kavchat.com/v1/kavchat.js"
  data-key="pk_live_..."
  data-locale="he"
  data-user-token="<identity JWT>"
  data-user-name="Dana"
  data-open="false"
  async></script>

JavaScript API

Скрипт создаёт window.Kavchat:

JavaScript
Kavchat.init({
  publicKey: 'pk_live_...',
  apiBase: 'https://api.kavchat.com', // optional
  locale: 'he',                       // optional
  userToken: '<identity JWT>',        // optional
  userName: 'Dana',                   // optional
  open: false,                        // optional
  onScreen(screen, targetId) {},      // optional: "screen" buttons in your scripts
  onEvent(event) {},                  // optional: ready, unavailable, open, close, effect, ticket
});
Kavchat.open();
Kavchat.close();
Kavchat.toggle();
Kavchat.setUser({ token: '<identity JWT>', name: 'Dana' }); // on login; setUser(null) on logout
Kavchat.offset({ bottom: 80 });       // lift the launcher, e.g. above a cookie banner; offset(null) resets
Kavchat.destroy();

Вызывать init не нужно, если в теге скрипта указан data-key. Повторный вызов init заменяет работающий виджет.

Вызов API до загрузки скрипта

У тега скрипта указан async, поэтому ваш код может выполниться раньше. Создайте очередь и добавляйте в неё вызовы. После загрузки виджет выполнит их по порядку. init всегда выполняется первым, а его настройки имеют приоритет над атрибутами тега.

HTML
<script>
  window.Kavchat = window.Kavchat || { q: [] };
  Kavchat.q.push(['init', { publicKey: 'pk_live_...', onScreen: function (s, id) { location.href = '/' + s + '/' + id; } }]);
  Kavchat.q.push(['setUser', { token: '<identity JWT>', name: 'Dana' }]);
</script>
<script src="https://cdn.kavchat.com/v1/kavchat.js" async></script>

Каждый элемент очереди имеет вид [methodName, ...args]. После загрузки скрипта Kavchat.q.push(...) продолжает работать и выполняет вызов сразу, поэтому один и тот же код подходит для обоих случаев.

Место для cookie-баннера

Если на сайте есть элемент, закреплённый внизу экрана, например cookie-баннер, вы можете поднять над ним кнопку, окно и облачка. Для этого есть два способа: CSS-переменная --kavchat-bottom или команда Kavchat.offset, которая принимает число в пикселях или значение длины, например 5rem. Смещение прибавляется к высоте, заданной в панели управления. Когда баннер закроется, удалите переменную или вызовите offset(null). Оба способа работают и на сайте со строгой политикой CSP. На телефоне окно открывается на весь экран и не смещается.

CSS
/* while your cookie banner is shown */
body.cookie-banner-open { --kavchat-bottom: 80px; }
JavaScript
// works before or after the widget script loads
window.Kavchat = window.Kavchat || { q: [] };
Kavchat.q.push(['offset', { bottom: banner.offsetHeight + 12 }]);

// after the visitor makes a choice
Kavchat.q.push(['offset', null]);

События

Функция onEvent получает одно из следующих событий:

typeПоляКогда происходит
readyversion, offlineБот загружен из сети или из сохранённой копии, если сети нет.
unavailablereason? ('quota')Бот выключен, доступен только тестовым пользователям или квота исчерпана. Ничего не отображается.
open, closeОкно открылось или закрылось.
effecteffectКнопка запросила открытие формы обращения, ссылки или экрана.
ticketid, numberСоздано обращение.
livestate, idИзменилось состояние чата с оператором: queued, active, closed или ticket.
JavaScript
Kavchat.init({
  publicKey: 'pk_live_...',
  onEvent(event) {
    if (event.type === 'ready') console.log('Bot version', event.version, event.offline ? '(offline copy)' : '');
    if (event.type === 'ticket') console.log('Request opened', event.number);
  },
});

Действия в сценарии

  • Обращение: открывает форму обращения внутри чата. К обращению прикладывается переписка.
  • Ссылка: открывает ссылки https: и tel: в новой вкладке (rel="noopener noreferrer"). Ссылки других типов не открываются.
  • Экран: вызывает вашу функцию onScreen(screen, targetId). Без неё кнопка на сайте ничего не делает.

Список экранов в редакторе

Один раз укажите экраны, которые умеет открывать приложение, в параметре screens метода Kavchat.init. SDK сам отправит список в Kavchat, и редактор сценариев предложит эти экраны по названиям в выпадающем списке вместо поля для свободного ввода. Редактор также запросит идентификатор элемента, если он нужен экрану, и предупредит о кнопке, ведущей на экран, которого нет в списке. Вводить список экранов вручную в панели управления не нужно.

JavaScript
Kavchat.init({
  publicKey: 'pk_live_...',
  screens: [
    { id: 'orders', label: 'My orders' },
    { id: 'product', label: 'Product page', needsTarget: true }, // the button also carries a product id
  ],
  onScreen(screen, targetId) {
    location.href = targetId ? `/${screen}/${targetId}` : `/${screen}`;
  },
});
  • id — значение, которое получает onScreen: латинские буквы, цифры, _, . и -, до 40 символов. label — название, которое видит администратор, до 60 символов. Можно указать до 100 экранов. Некорректные записи и повторяющиеся идентификаторы пропускаются.
  • needsTarget: кнопка также передаёт идентификатор элемента (например, товара), который поступает в onScreen как targetId.
  • Список отправляется в фоновом режиме после загрузки версии, только если он изменился или раз в неделю. Ошибка отправки не отображается, повторная попытка выполняется при следующем запуске. Пользователь ничего не видит.
  • Зарегистрированные экраны отображаются в панели управления в разделе «Бот», «Настройки», «Экраны приложения». Для каждого экрана указаны платформы, которые о нём сообщили. Экран, удалённый из приложения, можно удалить и там.

Идентификация ваших пользователей

Чтобы привязать диалоги и обращения к идентификатору пользователя в вашей системе или показывать бота только тестовым пользователям, подпишите JWT на сервере и передайте его через data-user-token или userToken. Когда пользователь входит в систему или выходит из неё, вызывайте Kavchat.setUser(...). Виджет отправляет токен в заголовке Authorization: Bearer <token> при каждом запросе. Пользователь, вошедший в систему, может создать обращение, не оставляя email или телефон. Как создать токен: Идентификация пользователей.

Политика CSP

Виджет работает на сайте со строгой CSP без 'unsafe-inline' и 'unsafe-eval'. Достаточно разрешить два наших источника:

CSP
script-src https://cdn.kavchat.com;
connect-src https://api.kavchat.com;

Стили загружаются в виде constructable stylesheets внутри Shadow DOM, поэтому менять style-src не нужно. Если у бота есть собственное изображение или в сценариях используются изображения, добавьте в img-src сервер, с которого они загружаются. Виджет ничего не загружает из других источников и не открывает iframe.

Чат с оператором

На сайте ничего настраивать не нужно. Когда вы включаете чат с операторами в панели управления, виджет загружает дополнительный файл kavchat-live.js из той же папки и той же версии, что и kavchat.js. На сайтах без чата с операторами этот файл вообще не загружается.

  • Выбор: рядом с «Обратиться в поддержку» появляется вариант «Чат с оператором», но только после того, как сервер подтвердит наличие свободного оператора. В нерабочее время или когда все операторы заняты, отображается только форма обращения. Рядом указана краткая причина и время возвращения команды, если оно известно. Когда месячная квота исчерпана, форма отображается без пояснения.
  • Запрос: гости оставляют email или телефон на случай, если ни один оператор не освободится вовремя. Можно также добавить имя и первое сообщение. Если открыто несколько отделов, нужно выбрать один. Идентифицированным пользователям (userToken) не нужно указывать контактные данные. Если ни один оператор не может принять чат, открывается форма обращения с уже введёнными данными.
  • Ожидание: отображается надпись «Ожидаем оператора» с обратным отсчётом заданного вами времени ожидания, а также кнопки «Оставить сообщение вместо чата» и «Завершить чат». Писать можно уже во время ожидания. Когда время истекает, чат автоматически превращается в обращение. Посетитель видит номер обращения и пояснение, что ни один оператор не освободился вовремя.
  • Диалог: имя оператора, сообщения, индикатор набора текста, перевод на другого оператора и завершение чата. Всё, что приходит с сервера, отображается как обычный текст, без HTML и ссылок. Программы чтения с экрана озвучивают новые сообщения, а если окно закрыто, на плавающей кнопке появляется точка.
  • В реальном времени: соединение устанавливается через Server-Sent Events. При обрыве связи виджет пытается подключиться снова с постепенно растущими интервалами и получает всё пропущенное. Поэтому сообщения не теряются и не отображаются дважды. В сетях, блокирующих такое соединение, виджет переходит на повторные запросы (long-poll). У каждого сообщения есть идентификатор, поэтому повторная попытка не создаёт дубликат. Неотправленное сообщение помечается, и его можно отправить повторно нажатием.
  • Перезагрузка: токен доступа к чату хранится в localStorage с привязкой к публичному ключу и диалогу, но никогда не попадает в адрес страницы. Он действует до 12 часов или до завершения чата. Поэтому после перезагрузки или перехода на другую страницу восстанавливается весь диалог: сначала часть с ботом, затем часть с оператором.
  • Без preflight: запросы отправляются без специальных заголовков, а тело запроса содержит JSON, передаваемый как text/plain.

Ответы ИИ (Premium)

На сайте ничего настраивать не нужно. Когда вы включаете ответы ИИ в панели управления (со своим ключом провайдера ИИ), вопрос, на который нет ответа ни в одном сценарии, отправляется в Kavchat. Во время ожидания, до 20 секунд, чат показывает, что бот печатает. Ответ отображается как обычный текст с небольшой меткой «Ответ ИИ» на языке интерфейса. Под ним появляются кнопка связанной темы, если она есть, и кнопка «Обратиться в поддержку».

Если ответа нет, запрос завершился ошибкой, занял слишком много времени или превысил лимит (10 ответов на диалог каждые 15 минут), чат показывает обычное сообщение «Не удалось найти ответ». Вопрос по-прежнему попадает в отчёт о вопросах без ответа, а ответы ИИ сохраняются в истории диалога, как и любые другие сообщения.

Как работает виджет

  • Изоляция: всё отображается внутри Shadow DOM. Ваш CSS не влияет на виджет, а CSS виджета не влияет на страницу.
  • Кэш: опубликованный бот сохраняется в localStorage с привязкой к публичному ключу вместе со своим ETag. При каждой загрузке отправляется заголовок If-None-Match. Если ничего не изменилось, сервер отвечает кодом 304. Когда сети нет, виджет использует сохранённую копию и показывает уведомление об этом.
  • Диалоги: случайный идентификатор диалога хранится в sessionStorage, поэтому при переходе между страницами продолжается тот же диалог.
  • Чат с оператором: открытый чат сохраняется в localStorage и восстанавливается на следующей странице.
  • Данные: сведения о ходе диалога отправляются примерно через 2 секунды после каждого действия, а также когда страница становится скрытой.
  • Значок Kavchat: отображается на всех тарифах. На Premium его можно скрыть в настройках бота.
  • Доступность: окно представляет собой диалог с меткой. Фокус переходит в него и возвращается обратно, Esc закрывает окно. Кнопки реализованы как настоящие кнопки, новые сообщения бота озвучиваются, а анимация сокращается, если посетитель выбрал такую настройку.

Установка из npm

В одностраничном приложении можно включить виджет в сборку вместе с вашим кодом вместо загрузки через тег скрипта:

Terminal
yarn add @kavchat/widget
# or: npm install @kavchat/widget
JavaScript
import { createWidget } from '@kavchat/widget';

const widget = createWidget({ publicKey: 'pk_live_...' });
await widget.ready;
widget.open();