# JS API и события

> Как открыть чат, задать вопрос за посетителя, сказать, кто он, и узнать, что разговор ушёл к людям.

Ваша страница может управлять `<tolkly-chat>` через методы элемента и слушать три события. Для
обычной установки это не нужно.

## Как получить элемент
Методы появляются, когда скрипт объявит элемент. Дождитесь этого:

```js
await customElements.whenDefined('tolkly-chat')
const chat = document.querySelector('tolkly-chat')
chat.open()
```

## Методы
| Метод | Что делает |
|---|---|
| `open({ focus })` | Открывает чат. Если нужно, сначала загружает окно. По умолчанию фокус переходит в чат; с `focus: false` он остаётся на месте. |
| `close()` | Сворачивает чат. У чата с `inline` ничего не делает. |
| `ask(text)` | Открывает чат, если он закрыт, и отправляет `text` от имени посетителя. Возвращает promise. Ничего не делает, если `text` пустой или ещё приходит прошлый ответ. Сервер принимает до 1000 символов. |
| `identify(token)` | Сообщает чату, кто посетитель, токеном, который подписал ваш сервер. Вызывайте после входа на сайт ([подпись посетителя](https://tolkly.io/docs/ru/identity.md#pass-the-token)). |
| `identify({ id, name, email, phone, fields })` | Сообщает чату, кто посетитель, без подписи. Операторы увидят пометку «Не проверено». Общей истории между устройствами у такого посетителя не будет. Обязателен только `id`. |
| `reset()` | Вызывайте при выходе. Чат забывает посетителя и разговор, сохранённый в этом браузере, и начинает заново. Также перестаньте выводить `data-identity`. |

## Подсказанные вопросы
`suggestions` — это свойство, а не атрибут. В нём вопросы, которые чат предлагает до первого
сообщения. Заданные страницей, они заменяют на ней вопросы из «Виджета»: например, вопрос про одно
направление обмена на его странице.

```js
chat.suggestions = ['How long does a withdrawal take?', 'Which documents do you need?']
chat.suggestions = null // снова вопросы из «Виджета»
```

Чат берёт до 6 вопросов, пустые пропускает. Они видны только до первого сообщения посетителя.
Вопросы, заданные страницей, в отчёте не считаются, вопросы из «Виджета» — считаются
([Частые вопросы](https://tolkly.io/docs/ru/widget.md#suggestions)).

## События
Все три события всплывают и проходят через shadow root (`composed`). Поэтому их можно слушать на
`document`:

```js
document.addEventListener('tolkly:handoff', (event) => {
  const { reason, tokens } = event.detail
  console.log('handed to people:', reason, tokens)
})

document.addEventListener('tolkly:resolved', (event) => {
  console.log('the visitor says this answer helped:', event.detail.answerId)
})
```

### `tolkly:handoff`
Разговор уходит к людям. Событие срабатывает в этой вкладке, когда:

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

Событие не срабатывает, когда:

- бот отказывается отвечать;
- бот только предлагает позвать человека;
- посетитель переходит по ссылке `handoff`;
- подключается оператор;
- разговор восстанавливается при загрузке страницы.

`detail.tokens` — номера заявок и хэши транзакций из вопроса:
`{ kind: 'order' | 'tx', value: string }[]`. `detail.reason` — одно из значений:

| `reason` | Почему |
|---|---|
| `requested` | Посетитель попросил человека. |
| `personal_case` | Вопрос о заявке, платеже или аккаунте самого посетителя. Проверить это могут только сотрудники. |
| `topic` | Сообщение на одну из тем, которые проект передаёт человеку. |
| `operators_only` | Проект работает без ИИ: каждое сообщение уходит людям. |
| `cap_reached` | Лимит ИИ исчерпан: месячный лимит ИИ-диалогов компании ([Тариф, оплата и лимит](https://tolkly.io/docs/ru/billing.md#cap)) или дневная защита проекта ([Как отвечает Tolkly](https://tolkly.io/docs/ru/overview.md#daily-cap)). Вместо бота отвечают люди. |
| `attachment` | Посетитель отправил файл, а бот файлы не читает. |
| `scenario` | Система заявок проекта не ответила боту (ошибка, таймаут, неизвестный статус), поэтому вопрос берут люди. |

### `tolkly:resolved`
Посетитель нажал «Помогло» под ответом бота. `detail.answerId` — id ответа или `null`, если чат
его не знает. Событие срабатывает один раз на ответ. На оценку после того, как оператор закрыл
разговор, оно не срабатывает.

### `tolkly:unread`
Изменилось число ответов, которые посетитель ещё не прочитал. `detail.unread` — их число,
`detail.ask` — `true`, когда чат просит контакт, а посетитель этого ещё не видел. Событие
срабатывает только при изменении. С `launcher="none"` так ваша страница показывает отметку, которую
показала бы кнопка:

```js
document.addEventListener('tolkly:unread', (event) => {
  const { unread, ask } = event.detail
  helpButton.classList.toggle('has-news', unread > 0 || ask)
})
```

## Язык
Чат говорит на языке из своего атрибута `lang`. Если атрибута нет — на языке из `<html lang>`.

Чат следит за обоими. Если сайт меняет язык без перезагрузки или задаёт `chat.lang = 'ru'`, чат
перерисовывается на новом языке и заново загружает разговор с сервера.

У чата есть тексты на 15 языках: `en`, `ru`, `hy`, `kk`, `uz`, `az`, `ka`, `ky`, `tg`, `uk`, `tr`,
`de`, `es`, `fr` и `pt`. Для любого другого языка он берёт основной язык проекта
([Как выглядит чат](https://tolkly.io/docs/ru/widget.md#language)), а если он не задан — английский, но имена операторов
всё равно следуют языку страницы.
