Разработчикам

Как установить виджет, идентифицировать авторизованных пользователей и какие параметры он принимает.

1. Установка виджета

Вставьте этот код перед закрывающим тегом </body>на каждой странице вашего сайта. Идентификатор data-siteвозьмите из вкладки Виджет.

<script src="https://widget.chait.ru/widget.js" data-site="ВАШ_SITE_ID" async></script>

Куда вставлять на популярных платформах:

Тильда+
  1. Настройки сайта → «Ещё» → «HTML-код для вставки внутрь head/body».
  2. Вставьте код в поле для кода перед закрывающим тегом body.
  3. Сохраните и опубликуйте страницы заново — код применяется при публикации.
WordPress+
  1. Проще всего — любой плагин вставки кода в подвал сайта, например WPCode: поле «Footer».
  2. Вручную: Внешний вид → Редактор тем → файл footer.php, строка перед закрывающим тегом body.
  3. Тему правьте только дочернюю — иначе обновление шаблона сотрёт код.
1С-Битрикс+
  1. Файл шаблона сайта: /bitrix/templates/<ваш шаблон>/footer.php, перед закрывающим тегом body.
  2. Через админку: Настройки → Настройки продукта → Сайты → Шаблоны сайта → нижняя часть шаблона.
  3. После правки сбросьте кеш сайта, иначе страницы отдадутся старые.
Битрикс24-сайты+
  1. В редакторе сайта добавьте в подвал блок «HTML-код» и вставьте код туда.
  2. Либо в настройках сайта найдите поле для своего HTML-кода (обычно там же, где счётчики аналитики).
  3. Сохраните и опубликуйте сайт.
Другой сайт или CMS+
  1. Код нужен один раз в общем шаблоне — в подвале, который выводится на всех страницах.
  2. В настройках сайта найдите поле для своего HTML-кода: его называют «Счётчики», «Скрипты», «Код в подвале».
  3. Такого поля нет — отправьте код тому, кто делал сайт: это одна строка перед закрывающим тегом body.

Скрипт загружается асинхронно и не блокирует страницу. Когда виджет отметится, канал «Сайт (виджет)» в панели сменит статус на «подключён».

2. Идентификация пользователей (HMAC)

Если на сайте есть авторизация, передайте виджету, кто именно пишет. Тогда переписка привяжется к пользователю и будет доступна ему с любого устройства, а оператор увидит имя, e-mail и ваши атрибуты.

Чтобы никто не мог выдать себя за чужого пользователя, идентификатор подписывается на вашем бэкенде: считаете HMAC-SHA256 от idпользователя, ключ — секрет сайта (hmac_secret в настройках сайта в панели). Секрет держите только на сервере, не публикуйте в браузере.

Шаг 1. Посчитайте подпись на бэкенде

Node.js
import { createHmac } from "node:crypto";

const hmac = createHmac("sha256", process.env.CHAT_HMAC_SECRET)
  .update(String(user.id))
  .digest("hex");

// отдаём hmac на фронт вместе с остальным профилем пользователя
PHP
<?php
$hmac = hash_hmac('sha256', (string) $user_id, $hmac_secret);
// $hmac_secret — секретный ключ сайта из панели
?>
Python
import hmac, hashlib

digest = hmac.new(
    hmac_secret.encode(),      # секретный ключ сайта из панели
    str(user_id).encode(),
    hashlib.sha256,
).hexdigest()

Шаг 2. Передайте профиль виджету

Задайте window.chatWidgetUser доподключения widget.js — подставьте посчитанный на сервере hmac:

<script>
  window.chatWidgetUser = {
    id: "42",                       // обязателен для идентификации
    hmac: "<hmac-из-вашего-бэкенда>", // HMAC-SHA256 от id ключом сайта
    name: "Иван Петров",
    email: "ivan@example.com",
    description: "Pro",
    company_name: "ООО «Ромашка»",
    custom_attributes: { plan: "pro", ltv: 12000 },
  };
</script>
<script src="https://widget.chait.ru/widget.js" data-site="ВАШ_SITE_ID" async></script>

Секрет каждого сайта можно перегенерировать в его настройках — после ротации обновите подпись у себя на бэкенде.

3. Параметры виджета

Атрибуты data-* у тега скрипта:

АтрибутОбяз.Описание
data-siteдаИдентификатор проекта из панели. Определяет, к какому чату подключается виджет.
data-titleнетЗаголовок окна чата. Переопределяет значение из настроек сайта (мгновенно, до ответа конфига).
data-placeholderнетТекст-подсказка в поле ввода. По умолчанию «Напишите сообщение…».
data-apiнетБаза API. По умолчанию — origin, с которого загружен widget.js. Менять не нужно.

Поля профиля window.chatWidgetUser

ПолеОбяз.Описание
idдаИдентификатор пользователя в вашей системе. Без него идентификация не работает.
hmacда*HMAC-SHA256(id) секретным ключом сайта. Нужен, чтобы связать посетителя с его перепиской между устройствами.
nameнетИмя пользователя.
emailнетE-mail пользователя.
descriptionнетКороткая пометка (например, тариф «Pro»).
company_nameнетНазвание компании.
custom_attributesнетПроизвольные пары ключ-значение — видны оператору в карточке диалога.

* hmac обязателен для привязки переписки между устройствами. Без него профиль всё равно покажется оператору, но диалог останется локальным для браузера.

Оформление

Заголовок, плейсхолдер, акцентный цвет и скрытие на мобильных задаются во вкладкеВиджети подтягиваются автоматически — дублировать в коде не нужно. Тема (светлая/тёмная) подстраивается под сайт: виджет следует классу.dark на странице и системной теме пользователя.

4. Управление из JavaScript

После загрузки виджет добавляет в window объектChatWidget:

// Открыть / закрыть / переключить чат программно
window.ChatWidget.open();
window.ChatWidget.close();
window.ChatWidget.toggle();
window.ChatWidget.isOpen(); // true, если панель открыта

// Открыть с готовым вопросом от имени посетителя
window.ChatWidget.open({ message: "Хочу обсудить тариф Бизнес" });
// …или скрыто: вопрос уходит боту, в переписке посетитель видит только ответ
window.ChatWidget.open({ message: "Что входит в тариф?", hideMessage: true });
// …или просто подставить текст в поле ввода, без отправки
window.ChatWidget.open({ prefill: "Здравствуйте! " });

// Отправить сообщение, не раскрывая окно
window.ChatWidget.sendMessage("Здравствуйте!");

// Профиль пользователя (identify — синоним setUser)
window.ChatWidget.identify({ id: "42", hmac: "…", name: "Иван" });
// Произвольные атрибуты в карточку посетителя (нужен подписанный профиль с hmac)
window.ChatWidget.setContext({ plan: "pro", cart_total: 5400 });

// Подписка на события; on возвращает функцию отписки
const off = window.ChatWidget.on("handoff", (e) => console.log("позвали оператора", e));

// Убрать виджет со страницы (SPA-переходы)
window.ChatWidget.destroy();

// Короткий алиас для открытия (например, на кнопке «Написать нам»)
window.openChat();

События виджета

Каждое событие уходит тремя каналами сразу: подпискаChatWidget.on(…), DOM-событие на window и, если на сайте стоит GTM, — dataLayer(имя события chait_<событие>). В dataLayer уходят только служебные поля: текст переписки в аналитику не передаётся.

СобытиеКогда
readyВиджет загрузился, методы ChatWidget доступны. Ловится только через window (подписаться через on() уже поздно).
openОкно чата открылось.
closeОкно чата закрылось.
messageСообщение отправлено (direction: "out") или получено от бота/оператора (direction: "in").
handoffДиалог передан живому оператору — по кнопке «Позвать оператора» или по решению бота. Один раз на диалог.
// Подписка методом виджета (возвращает функцию отписки)
window.ChatWidget.on("message", (d) => console.log(d.direction, d.text));

// То же событие на window — слушателя можно повесить до загрузки виджета
window.addEventListener("chait:handoff", (e) => console.log(e.detail));

// В GTM события приходят сами, если dataLayer объявлен до виджета:
// { event: "chait_handoff", conversation_id: 123, reason: "button" }

5. API и вебхуки

Читайте диалоги и лиды через REST API и получайте события на свой сервер вебхуками. Токен и вебхук создаются в панели проекта, во вкладке «Разработчикам».

REST API v1

База: https://api.chait.ru. Авторизация — Authorization: Bearer <токен>. Ответы отдаются только по вашим проектам.

МетодПутьОписание
GET/api/v1/conversationsСписок диалогов. Параметры: site_id, status (open|resolved), since (unix-время), limit (≤100), offset.
GET/api/v1/conversations/:id/messagesСообщения диалога (только ваши проекты). Параметры: limit, offset.
GET/api/v1/leadsПосетители, оставившие контакт (e-mail или телефон). Параметры: site_id, since, limit, offset.
curl -H "Authorization: Bearer cht_ваш_токен" \
  "https://api.chait.ru/api/v1/conversations?status=open&limit=50"
curl -H "Authorization: Bearer cht_ваш_токен" \
  "https://api.chait.ru/api/v1/conversations/123/messages"
curl -H "Authorization: Bearer cht_ваш_токен" \
  "https://api.chait.ru/api/v1/leads?since=1784000000"

События вебхуков

СобытиеКогда
conversation.createdОткрыт новый диалог.
message.createdПосетитель отправил сообщение.
lead.createdПосетитель оставил контакт (e-mail/телефон).
conversation.escalatedДиалог передан живому оператору (ИИ позвал человека).

Тело запроса — JSON { event, created_at, data }:

{
  "event": "lead.created",
  "created_at": 1784122593,
  "data": {
    "conversation_id": 123,
    "site_id": "ВАШ_SITE_ID",
    "visitor_id": "v_abc",
    "contact": "ivan@example.com",
    "email": "ivan@example.com",
    "phone": null,
    "name": "Иван"
  }
}

Проверка подписи

Каждый запрос несёт заголовок X-Chait-Signature =sha256=<hex>, где hex — это HMAC-SHA256 от сырого тела запроса, ключ — секрет вебхука сайта. Событие также дублируется в заголовкеX-Chait-Event. Считайте подпись от СЫРОГО тела (до разбора JSON) и сравните:

import { createHmac, timingSafeEqual } from "node:crypto";

// secret — «Секрет подписи» из настроек вебхука сайта в панели
// raw — СЫРОЕ тело запроса (строкой, до JSON.parse)
const expected = "sha256=" + createHmac("sha256", secret).update(raw).digest("hex");
const got = req.headers["x-chait-signature"];
const ok = got && timingSafeEqual(Buffer.from(expected), Buffer.from(got));
if (!ok) return res.status(401).end();

Доставка — с одной повторной попыткой и таймаутом 5 секунд. Отвечайте кодом 2xx; долгую обработку выносите в фон.

Нужна помощь с интеграцией? Напишите нам прямо в чате на этой странице или во вкладкеВиджет найдите секретный ключ.

Где взять свой site id

Вместо ВАШ_SITE_ID подставьте идентификатор своего проекта. Он появится в панели после регистрации — там же готовый код с ним, секрет для HMAC, токены API и вебхуки.