Виджет на сайте
Виджет — единственное, что ставится на страницы вашего сайта. Всё остальное происходит на нашей стороне: сообщение уходит менеджерам, ответ возвращается в панель чата.
Если вы здесь впервые, начните с быстрого старта — эта страница про подробности.
Сниппет
Готовая строка со всеми подставленными значениями лежит в кабинете: проект → «Код для сайта». Выглядит она так:
<script src="https://widget.globask.com/widget/widget.js" data-globask-key="pk_ваш_ключ"></script>
Вставьте её перед закрывающим </body> на всех страницах сайта — человек
пишет с той страницы, на которой у него возник вопрос, а не с главной. Адрес
страницы приходит менеджеру вместе с обращением.
Что нужно знать про этот скрипт:
pk_…— публичный ключ проекта, а не секрет. Он и должен лежать в исходном коде страницы. От установки вашего чата на чужой сайт защищает не он, а список доменов.- Он почти ничего не стоит странице. Весит около 7 КБ в gzip и рисует
кнопку сам, не дожидаясь ответа сервера. Сниппет ставится перед
</body>, поэтому отрисовке страницы не мешает; если вам нужнее поставить его выше, добавьтеasync— виджету это не вредит. - Панель чата создаётся только по клику. До первого открытия на странице нет ни iframe, ни его содержимого. Исключения два: посетитель, который уже писал вам (иначе ответ пришёл бы в никуда), и посетитель с неотправленным сообщением — его надо дослать.
- Двойная установка не удваивает чат. Сниппет нередко попадает на страницу дважды — через тему сайта и через диспетчер тегов разом. Второй запуск с тем же ключом мы игнорируем.
Домены сайта
В кабинете (проект → «Настройки») перечислены домены, на которых виджету разрешено работать. Виджет заработает на них и на их поддоменах; на всех прочих — не заработает вовсе.
Это не формальность: публичный ключ виден в исходном коде каждой страницы, и без списка доменов чужой сайт мог бы поставить ваш чат себе, а обращения с него приходили бы вашим менеджерам.
«https://» и путь вводить можно — мы оставим только домен.
Если на сайте настроен CSP
Content-Security-Policy виджету не мешает, но его нужно пустить — тремя директивами на наш адрес:
script-src https://widget.globask.com;
frame-src https://widget.globask.com;
connect-src https://widget.globask.com;
Каждая отвечает за свой шаг, и пропуск любой ломает виджет молча, без ошибки на странице:
- без
script-srcне загрузится сам сниппет; - без
frame-srcкнопка появится, а чат по клику не откроется — эту забывают чаще всего; - без
connect-srcкнопка останется в цвете по умолчанию: загрузчик спрашивает оформление у нас ещё до того, как посетитель что-то нажал.
unsafe-inline в style-src не нужен: стили кнопки ставятся через CSSOM.
В старых браузерах, которые его не поддерживают (Safari до 16.4), загрузчик
возвращается к обычному тегу <style> — там при строгой политике кнопка
будет без оформления, но чат продолжит работать.
Открывать чат своей кнопкой
Клик по любому элементу с классом globask-open или атрибутом
data-globask-open открывает чат. Это работает всегда, независимо от
настроек, и не требует ни строчки JavaScript:
<a href="#" class="globask-open">Написать нам</a>
Клик по вложенному элементу — иконке или span внутри кнопки — тоже
считается: мы ищем ближайшего родителя.
Если наша кнопка на странице не нужна и чат должен открываться только вашими элементами, выберите в кабинете (проект → «Внешний вид») пункт «Своим элементом сайта». Тогда виджет не добавляет на страницу свою кнопку.
Счётчик непрочитанных
Если менеджер ответил, пока чат у посетителя закрыт, наша кнопка
показывает значок с числом новых ответов. У вашего элемента такого значка
нет. Вместо него мы ставим на все элементы с классом globask-open или
атрибутом data-globask-open атрибут data-globask-unread с тем же числом
(больше девяти — «9+») и снимаем его, когда посетитель открывает чат.
Показать число — ваша часть работы, достаточно одного правила CSS:
.globask-open[data-globask-unread]::after {
content: attr(data-globask-unread);
}
Без него посетитель не узнает, что ему ответили. Ответ не пропадёт: он лежит в чате и будет виден, как только посетитель чат откроет. Но на странице ничего не изменится, и повода открыть чат у посетителя не будет. Письмом ответ тоже не придёт, пока посетитель на сайте: письмо получает только тот, кто оставил почту и ушёл со страницы.
Управление из скриптов сайта
Виджет выставляет наружу window.globask с тремя методами:
window.globask.open();
window.globask.close();
window.globask.toggle();
Объект появляется после загрузки скрипта, поэтому вызывать его из кода, который выполняется раньше, нельзя — проверьте, что он есть:
window.globask?.open();
Имена globask-open, data-globask-open, data-globask-unread и
window.globask — часть публичного контракта: мы их не переименуем.
Туда же относится фрагмент адреса #globask-open: страница, открытая с ним,
разворачивает чат сама, а сам фрагмент из адреса убирается. По таким ссылкам
посетитель возвращается из письма с ответом менеджера — но пользоваться ими
можно и вам, например в рассылке.
Что менеджер узнает о посетителе
Если сайт знает о человеке больше нас — тариф, номер заказа, город из его
профиля, — положите это в window.globask.user, и менеджер увидит значения
в карточке рядом с перепиской:
<script>
window.globask = window.globask || {};
window.globask.user = {
Тариф: 'Pro',
Заказов: 12,
Оптовик: true,
};
</script>
<script
src="https://widget.globask.com/widget/widget.js"
data-globask-key="pk_ваш_ключ"
></script>
Правила простые:
- Меняйте объект целиком. Значения перечитываются при каждом открытии
чата и при каждом присваивании
window.globask.user = {…}— вход и выход в одностраничном приложении без перезагрузки доедут до следующего сообщения. Правка одного поля (window.globask.user.Тариф = 'Lite') мимо нас проходит незамеченной: присваивайте новый объект. Пользователь вышел — присвойте{}, и прежние значения сотрутся. - Только строки, числа и
true/false. Вложенные объекты и массивы показать строкой в карточке нельзя, поэтому они отбрасываются — как иNaNс бесконечностями. Булево менеджер увидит словами «да» и «нет». - Не больше десяти полей, название до 40 символов, значение до 200. Лишнее отсекается молча.
- Порядок скриптов не важен: наш загрузчик дописывает свои методы к
тому, что уже лежит в
window.globask, а не заменяет объект.
Важно понимать, откуда эти значения берутся: их задаёт страница в браузере
посетителя, а значит, их можно подделать из консоли разработчика. Менеджеру
они показываются отдельным блоком — в кабинете с пометкой «со страницы
сайта», в Telegram списком «Доп. параметры» по команде /info — как
подсказка, а не как выписка из вашей базы. Если вашему серверу нужно
значение, которому можно верить, — подпишите его, как описано ниже.
Те же значения получает и ваш сервер: в API и в
вебхуках они приходят в identity.attributes, свежими на
момент каждого сообщения посетителя.
Как сделать значение проверяемым
Если ваш бот по сообщению из чата делает что-то от имени пользователя —
списывает баланс, запускает платную операцию, — верить uid на слово нельзя:
вписать в консоли чужой идентификатор стоит одной строки. Подпишите его на
своём сервере, а проверяйте там же, получив событие. Мы значение не
разбираем — только храним и возвращаем.
При отрисовке страницы:
$exp = time() + 12 * 3600; // подпись живёт дольше сессии на странице
$sig = substr(rtrim(strtr(base64_encode(
hash_hmac('sha256', "{$uid}.{$exp}", $secret, true)
), '+/', '-_'), '='), 0, 22);
$user = ['uid' => $uid, 'uid_sig' => "{$exp}.{$sig}"]; // → window.globask.user
При получении события — на PHP:
$attrs = $event['data']['identity']['attributes'] ?? [];
[$exp, $sig] = explode('.', (string) ($attrs['uid_sig'] ?? ''), 2) + [null, null];
$expected = substr(rtrim(strtr(base64_encode(
hash_hmac('sha256', ($attrs['uid'] ?? '').'.'.$exp, $secret, true)
), '+/', '-_'), '='), 0, 22);
$trusted = $sig !== null && (int) $exp > time() && hash_equals($expected, $sig);
или на Node.js:
import { createHmac, timingSafeEqual } from 'node:crypto';
function trusted({ uid, uid_sig }, secret) {
const [exp, sig] = String(uid_sig ?? '').split('.');
if (!uid || !sig || Number(exp) * 1000 < Date.now()) return false;
const expected = createHmac('sha256', secret)
.update(`${uid}.${exp}`)
.digest('base64url')
.slice(0, 22);
return (
sig.length === expected.length &&
timingSafeEqual(Buffer.from(sig), Buffer.from(expected))
);
}
Три правила, без которых подпись не защищает:
- Проверяйте на каждом сообщении, а не один раз на диалог. Разговор привязан к браузеру, а не к человеку: на общем компьютере следующим напишет уже другой пользователь.
- Подписывайте
uidвместе со сроком, а не одно значение: иначе подсмотренная однажды подпись действует вечно. - Отбрасывайте повторы событий по заголовку
X-Globask-Deliveryдо того, как что-то списать: повторная доставка после таймаута — штатная ситуация (подробнее).
Помимо этого менеджер и так видит: с какой страницы человек написал, откуда пришёл на сайт, по какой рекламной метке, с какого устройства, последние десять просмотренных страниц, город по IP и местное время. Сам IP-адрес мы не сохраняем.
Что видит посетитель в переписке
Кроме самих сообщений панель показывает несколько вещей, о которых стоит знать заранее — их спрашивают.
Отметки у своего сообщения. Одна галочка значит, что сообщение доставлено менеджерам. Вторая — что его прочитали: менеджер открыл диалог в кабинете или ответил, в том числе из темы в Telegram — ответ подтверждает, что прочитано всё написанное до него. А вот если менеджер прочитал сообщение в Telegram и не ответил, второй галочки не будет: узнать о таком прочтении неоткуда, а показывать его по факту доставки было бы обманом. Подробнее — где отвечают менеджеры.
«Печатает ответ…» — когда менеджер набирает ответ в кабинете. Из Telegram такого сигнала тоже нет.
Подпись сервиса — строка со ссылкой на нас в подвале панели. Сейчас она показывается всем и не отключается; снятие подписи — из тех возможностей, что появятся с платными тарифами.
Подпись автора. Посетитель видит публичное имя менеджера — то, что менеджер сам указал в кабинете. Не указал — будет обезличенный «Оператор»; так же подписан и ответ из Telegram от того, кто ещё не привязал свой аккаунт. Настоящие имена и почта сотрудников наружу не уходят никогда.
Пометка автоответа. Сообщение, отправленное автоматически, подписано так, чтобы его не приняли за живого человека. Уведомление из вашей системы через API подписывается именем проекта — это не автоответ, а самое нужное сообщение в переписке.
Просьба оставить почту. Появляется под автоответом — то есть только там, где ответить сразу некому, — полем ввода внутри переписки. Анкеты до начала разговора у виджета нет и не будет: она отсекает обращения ради контактов, которые без разговора ничего не стоят.
Зачем адрес: если посетитель уйдёт со страницы, ваш ответ придёт ему письмом со ссылкой обратно в тот же чат. Пока чат открыт, писем нет. Пропустить просьбу можно одним нажатием, отказ запоминается. В письме есть ссылка «Не присылать письма» — она удаляет адрес.
Просьба включается и переформулируется там же, где автоответ (проект → «Автоответы»).
Внешний вид
Настраивается в кабинете (проект → «Внешний вид») и применяется без правки сниппета:
| Что | Значение |
|---|---|
| Цвет | ваш #rrggbb или один из пресетов; вся палитра панели строится от него |
| Заголовок панели | до 40 символов |
| Приветствие | до 200 символов, показывается в пустом чате |
| Сторона | справа или слева |
| Форма кнопки | круг, скруглённый квадрат или квадрат |
| Размер кнопки | 48, 56 или 64 пикселя |
| Отступы от края | 0…200 px по горизонтали и вертикали |
| Чем открывается | нашей кнопкой или элементом сайта |
Цвет текста на кнопке и в шапке мы считаем сами — светлый или почти-чёрный, смотря что читается поверх вашего.
Кнопка «Подобрать по моему сайту» читает цвет, который вы уже объявили своим:
метатег theme-color, theme_color в манифесте, цвет плитки Windows или
иконки Safari. Найденное подставляется в поле — сохраняете вы сами. Если
ничего не нашлось, значит на сайте этих объявлений нет: это частый случай,
и цвет проще взять из брендбука.
Отступы нужны, когда угол уже занят: своей кнопкой «наверх», панелью согласия с cookie, чужим виджетом. Панель чата следует за кнопкой сама. На телефоне отступ больше 40 px не применяется — иначе кнопка ушла бы за край экрана; там же учитывается системная полоса внизу iPhone.
Отдельно настраивается автоответ (проект → «Автоответы»): что написать посетителю в нерабочее время и что — если менеджеры молчат дольше заданного числа минут. Расписание и оба текста ваши. Там же — просьба оставить почту: её можно выключить или переписать своими словами.
Что дальше
- Где отвечают менеджеры — куда попадают обращения и что умеет кабинет.
- Серверное API — выгрузка переписки и отправка сообщения посетителю со своего сервера.
- Вебхуки — события диалогов в реальном времени, без опроса.