Документация
Установка занимает пять минут и не требует программиста. Разделы ниже нужны, только если вы хотите большего: узнавания авторизованных клиентов и проверки их состояния в вашем API.
Установка виджета
- 01 Подтвердите почту До подтверждения бот выключен намеренно: иначе спам-регистрация получала бы рабочий виджет на наш ключ к модели.
- 02 Загрузите базу знаний Вкладка «База знаний», перетаскивание файлов .md, .txt или .zip. Индексация идёт в фоне, её состояние видно в списке статей.
- 03 Укажите домен сайта Настройки, поле «Разрешённые домены». С доменов не из списка виджет не откроется.
- 04 Вставьте строку на сайт Скопируйте её из кабинета и поставьте перед закрывающим тегом body. Ключ в строке публичный, прятать его не нужно.
<script
src="https://knowdesk.ru/widget/embed.js"
data-bot-key="pk_live_xxxxxxxxxxxx"
async></script>
Узнавание авторизованного клиента
Если посетитель уже вошёл на ваш сайт, передайте его идентификатор вместе с подписью. Бот перестанет спрашивать то, что вы уже знаете, а диагностика сможет обращаться в ваш API от имени именно этого клиента.
Подпись считается на вашем сервере секретным ключом бота и в браузер в открытом виде не попадает. Ключ лежит в кабинете: Настройки → Дополнительно → Узнавание клиента, кнопка «Показать ключ». Без подписи данные считаются непроверенными и в вызовы API не подставляются.
Что ставит на страницу ваш сайт
Объект читается не в момент загрузки скрипта, а когда посетитель первый раз открывает чат, — поэтому в одностраничном приложении его можно поставить и после строки установки, когда данные пользователя дойдут с вашего API. Порядок неважен, важно только успеть до первого открытия чата.
Дальше объект уже не перечитывается: смена значения в открытой
вкладке ничего не изменит до перезагрузки страницы. Если у клиента
меняется то, что вы кладёте в attributes — скажем,
он переключился на другой проект, — страницу нужно перезагрузить.
<script>
window.knowdeskIdentity = {
external_id: "14822", // обязателен
email: "client@example.com",
name: "Иван Петров", // в подпись не входит
expires_at: 1755262800, // unix-время, обычно +1 час
attributes: { license: "SOFT-2231", plan: "pro" },
signature: "<посчитана на вашем сервере>"
};
</script>
Как считается подпись
HMAC-SHA256 в шестнадцатеричном виде от строки, собранной через
вертикальную черту: идентификатор, почта, срок годности, дальше
атрибуты в виде имя=значение, отсортированные
по возрастанию имени.
14822|client@example.com|1755262800|license=SOFT-2231|plan=pro
Пример на PHP
<?php
// Ключ из кабинета: Настройки → Дополнительно → Узнавание клиента.
// В браузер он не отдаётся никогда.
$secret = 'ваш ключ подписи';
$externalId = (string) $user->id;
$email = (string) ($user->email ?? '');
$expiresAt = time() + 3600;
// Необязательные атрибуты: то, что бот может подставить в диагностику.
$attributes = [
'license' => 'SOFT-2231',
'plan' => 'pro',
];
ksort($attributes); // порядок обязан совпасть с нашим
$parts = [$externalId, $email, (string) $expiresAt];
foreach ($attributes as $name => $value)
{
$parts[] = $name.'='.$value;
}
$signature = hash_hmac('sha256', implode('|', $parts), $secret);
?>
<script>
window.knowdeskIdentity = <?= json_encode([
'external_id' => $externalId,
'email' => $email,
'name' => $user->name,
'expires_at' => $expiresAt,
'attributes' => $attributes,
'signature' => $signature,
], JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP) ?>;
</script>
Из-за чего подпись не сходится
- Почта и срок годности входят в подпись всегда, даже пустые. Нет почты — в строке остаётся пустое место между двумя чертами, а не пропущенное поле.
- Имя в подпись не входит — оно ни на что не влияет и подделка его ничего не даёт.
- Атрибуты сортируются по имени. Порядок ключей в объекте JavaScript не гарантирован, а подпись обязана совпасть побайтово.
- Значения атрибутов — строки. Булево пишется
как
trueилиfalse, число — как текст; вложенные объекты и массивы отбрасываются, поэтому подписывать их нельзя. - Пустой список атрибутов ничего не добавляет к строке. Подписи, посчитанные до того, как вы начали передавать атрибуты, остаются рабочими.
- Срок годности проверяется по нашим часам. Просроченная подпись — это отказ, а не молчаливое понижение до анонима.
Ограничения запроса: до 20 атрибутов, значение до 190 символов. Смена ключа в кабинете обнуляет все выданные подписи сразу.
Куда попадают переданные данные
Почта, имя и идентификатор видны оператору в карточке обращения, под заголовком «Клиент», с отметкой «Узнан вашим сайтом».
А вот attributes сами по себе не делают ничего:
атрибут связывается с диагностическим полем по ключу на вкладке
«Диагностика» — заведите поле с тем же ключом
(sid, license) и укажите, что значение
приходит из подписанных данных. Тогда бот перестанет спрашивать
его у клиента и подставит в вызов вашего API, а оператор увидит
значение в карточке обращения, в блоке «Данные для диагностики».
Пока такого поля нет, переданный атрибут просто никуда не идёт.
Отдельной настройкой чат можно открывать только тем, чьи данные пришли с верной подписью. Это удобно для личных кабинетов, где отвечать анонимам незачем.
Диагностика через ваш API
Настройка идёт в четыре шага и живёт на вкладке «Диагностика».
- Спецификация. Загрузите файл OpenAPI или укажите ссылку на него. Внешние ссылки внутри спецификации отклоняются до разбора: резолвер, свободно ходящий по чужим адресам, это дыра с интерфейсом загрузки файла.
- Безопасные операции. Отметьте те, которыми боту можно пользоваться. По умолчанию не отмечено ничего, и это правильное умолчание.
- Диагностические поля. Опишите, что бот должен узнать у клиента: название для клиента, ключ для связи с параметром, подсказку «где это взять», пример значения и шаблон проверки.
- Привязка к клиенту. Если значение известно из проверенной подписи, укажите это. Такой параметр исчезнет из схемы инструмента, и подставить туда чужой идентификатор станет физически невозможно.
Когда значения не хватает, бот не идёт в сеть, а возвращает структурированную ошибку и спрашивает клиента. Отдельный инструмент «задать вопрос» здесь не нужен и вреден.
API обращений
Тариф Pro. Нужен, когда обращения должны жить не только в чате: список запросов в личном кабинете вашего сайта, форма «написать в поддержку» на вашей вёрстке, выгрузка в вашу отчётность. Запрос, созданный через API, попадает в ту же очередь операторов и к тому же боту — отдельной сущности «заявка» у нас нет.
Ключ выпускается в кабинете: Настройки → API. Показывается он один раз — у нас хранится только хеш. Ключ живёт на вашем сервере: он открывает всю переписку аккаунта, поэтому кросс-доменные запросы из браузера мы не разрешаем намеренно.
# обращения одного клиента, свежие сверху
curl -H "Authorization: Bearer kd_ВАШ_КЛЮЧ" \
"https://knowdesk.ru/api/v1/conversations?external_id=14822"
# новый запрос от клиента
curl -X POST -H "Authorization: Bearer kd_ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{"external_id":"14822","message":"Не приходит письмо со счётом"}' \
"https://knowdesk.ru/api/v1/conversations"
Что умеет
GET /api/v1/conversations— список с фильтрами:external_id(обращения одного человека),status,open,escalated,search,created_from,created_to,updated_since.GET /api/v1/conversations/{id}— карточка запроса: заголовок, статус, взят ли оператором.GET /api/v1/conversations/{id}/messages— переписка. Курсорafter— этоseq, а не время: по времени сообщения теряются.POST /api/v1/conversations— новый запрос. Обязательно толькоmessage.POST /api/v1/conversations/{id}/messages— реплика клиента в существующий запрос.
Что стоит знать заранее
- Внутренние заметки операторов наружу не уходят. Они лежат в той же ленте, что и переписка, и в ответах API их нет ни при каких параметрах.
external_idсвязывает каналы. Человек, писавший в чат на сайте, и он же, заведший запрос из личного кабинета, — один посетитель с одной историей.external_ref— ваш номер заявки и ключ повтора. Отправка той же ссылки второй раз вернёт уже созданный диалог с кодом 200 вместо 201, а не заведёт второй.escalate: trueотправляет запрос сразу человеку, минуя бота. Без него отвечает бот и передаёт разговор оператору по обычным правилам.- Каждый созданный запрос — диалог в вашем тарифе. Сверх лимита он всё равно создаётся и доходит до оператора, но бот на него не отвечает.
Лимиты и защита
Проверка домена от расхода бюджета не защищает: заголовок подделывается вне браузера. Поэтому кроме неё работают счётчики на посетителя и на адрес.
- Длина сообщения
- 4000 символов
- Сообщений с одного посетителя в час
- 30
- Сообщений с одного посетителя в сутки
- 200
- Сообщений с одного адреса в час
- 120
Сверх этого действуют лимиты тарифа: месячные диалоги и суточные сообщения. Подробности на странице тарифов.
Соберите бота за пять минут
Тариф Free без карты и без срока: сто диалогов в месяц, чтобы проверить продукт на своих настоящих вопросах.