Разработчикам
Как установить виджет, идентифицировать авторизованных пользователей и какие параметры он принимает.
1. Установка виджета
Вставьте этот код перед закрывающим тегом </body>на каждой странице вашего сайта. Идентификатор data-siteвозьмите из вкладки Виджет.
<script src="https://widget.chait.ru/widget.js" data-site="ВАШ_SITE_ID" async></script>
Куда вставлять на популярных платформах:
Тильда+
- Настройки сайта → «Ещё» → «HTML-код для вставки внутрь head/body».
- Вставьте код в поле для кода перед закрывающим тегом body.
- Сохраните и опубликуйте страницы заново — код применяется при публикации.
WordPress+
- Проще всего — любой плагин вставки кода в подвал сайта, например WPCode: поле «Footer».
- Вручную: Внешний вид → Редактор тем → файл footer.php, строка перед закрывающим тегом body.
- Тему правьте только дочернюю — иначе обновление шаблона сотрёт код.
1С-Битрикс+
- Файл шаблона сайта: /bitrix/templates/<ваш шаблон>/footer.php, перед закрывающим тегом body.
- Через админку: Настройки → Настройки продукта → Сайты → Шаблоны сайта → нижняя часть шаблона.
- После правки сбросьте кеш сайта, иначе страницы отдадутся старые.
Битрикс24-сайты+
- В редакторе сайта добавьте в подвал блок «HTML-код» и вставьте код туда.
- Либо в настройках сайта найдите поле для своего HTML-кода (обычно там же, где счётчики аналитики).
- Сохраните и опубликуйте сайт.
Другой сайт или CMS+
- Код нужен один раз в общем шаблоне — в подвале, который выводится на всех страницах.
- В настройках сайта найдите поле для своего HTML-кода: его называют «Счётчики», «Скрипты», «Код в подвале».
- Такого поля нет — отправьте код тому, кто делал сайт: это одна строка перед закрывающим тегом body.
Скрипт загружается асинхронно и не блокирует страницу. Когда виджет отметится, канал «Сайт (виджет)» в панели сменит статус на «подключён».
2. Идентификация пользователей (HMAC)
Если на сайте есть авторизация, передайте виджету, кто именно пишет. Тогда переписка привяжется к пользователю и будет доступна ему с любого устройства, а оператор увидит имя, e-mail и ваши атрибуты.
Чтобы никто не мог выдать себя за чужого пользователя, идентификатор подписывается на вашем бэкенде: считаете HMAC-SHA256 от idпользователя, ключ — секрет сайта (hmac_secret в настройках сайта в панели). Секрет держите только на сервере, не публикуйте в браузере.
Шаг 1. Посчитайте подпись на бэкенде
import { createHmac } from "node:crypto";
const hmac = createHmac("sha256", process.env.CHAT_HMAC_SECRET)
.update(String(user.id))
.digest("hex");
// отдаём hmac на фронт вместе с остальным профилем пользователя<?php
$hmac = hash_hmac('sha256', (string) $user_id, $hmac_secret);
// $hmac_secret — секретный ключ сайта из панели
?>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 | нет | Имя пользователя. |
| нет | 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 и вебхуки.