# Умный Бот 1.0

**Умный Бот 1.0** — это механизм подключения роботов к сервису **Webim**. Программно-аппаратная часть (бэкенд) таких роботов находится на внешнем относительно сервиса **Webim** сервере. Общение между сервисом и аппаратно-вычислительной частью происходит через HTTP-запросы из сервиса **Webim** на этот сервер. Робот **Умный Бот** принимает от пользователя вопрос и отправляет его на внешний сервер. Сервер генерирует ответ и присылает его обратно в сервис **Webim**, сервис показывает ответ пользователю. После этого робот снова ожидает вопрос от пользователя.
Если программно-аппаратная часть (бэкенд) робота перестала отвечать, не знает ответа или возникли другие проблемы, то чат переходит в общую очередь.

**Умный Бот 1.0** является синхронным. Сервис ожидает ответ от робота в теле `response`.

В версии [Webim 10.0](https://webim.ru/blog/11888-webim-10-0/) робот получил название **Умный бот**. Теперь для создания робота существует [специальный интерфейс](https://webim.ru/kb/bots/add-new-bot.html).

## Общая логика { #common-logic }

На робота **Умный Бот** автоматически назначаются все онлайн-чаты, которые поступают в отдел, в который этот робот добавлен. Онлайн-статус робота влияет на общий онлайн-статус системы:

  * если робот - *Онлайн*, то он будет принимать все чаты от пользователей, и кнопка на сайте будет *Онлайн*;

  * если робот - *Невидимка* и нет операторов онлайн, то он будет принимать все чаты от пользователей, но кнопка на сайте будет показываться *Офлайн*;

  * если робот — *Офлайн*, то он не будет принимать никакие чаты (и не будет влиять на онлайн-статус кнопки).

---

## Настройка { #setup }

Инструкция по настройке и подключению умного бота актуальна для сервиса **Webim** версии 10.0.

Для подключения внешнего робота к сервису **Webim**:

  1. Создайте оператора в системе через интерфейс. Инструкцию по созданию оператора см. [здесь](https://webim.ru/kb/getting-started/registration-agent.html).

  1. Перейдите в настройки Вашего аккаунта, выберите раздел **Боты**.

  1. В открывшемся окне нажмите на кнопку **Создать новый бот**.

  1. Заполните информацию о вашем боте, в поле **Ссылка на внешний API** впишите URL-адрес внешнего сервера робота.

  1. Сохраните изменения.

## Логика работы бота { #logic-of-work }

Когда в системе происходят различные события, то логика робота-оператора в **Webim** делает POST-запрос в предоставленный сторонний API-endpoint разработчиков робота. Данные передаются в формате `JSON`. При возникновении какой-либо ошибки запроса к API (ответ отличается от ожидаемого или запрос закрылся по таймауту (5 сек)) чат автоматически переводится в общую очередь операторов. Робот имеет два события: `new_chat`, `new_message`.

В версии API 1.0 HTTP-запросы к серверу робота не поддерживают авторизацию. Вам следует самостоятельно позаботиться о его защите на сетевом уровне.

HTTP-запросы от сервиса **webim** к серверу в заголовке содержат следующие параметры:

  * `X-Bot-API-Dialect` — "диалект" API (в данном случае `Webim Standard`);

  * `X-Bot-API-Version` — версия API (в данном случае `1.0`);

  * `X-Webim-Version` — полная версия **Webim** (например: `10.3.11`)

Заголовок `content-type` имеет значение `application/json`. Ответы от сервера робота ожидаются в одинаковом формате независимо от событий.

### Начало нового чата (`new_chat`) { #new-chat }

Событие `new_chat` срабатывает в момент назначения нового чата на робота.

URL-адрес сервера, куда передаются данные, берется из [настроек бота](#setup).

Формат передаваемых данных: POST-запрос на сервер робота, данные в формате JSON.

Структура передаваемых данных:

```
{
    "event": "new_chat",
    "chat": {
        "id": (string)
    },
    "visitor": {
        "id": (string),
        "channel": (object or null)
    },
    "messages": [(message), (message)...]
}
```

Пример тела запроса:

```
{
    "event": "new_chat",
    "chat": {
        "id": "23f56796-4db8-4284-a6e4-4c6865918bb6"
    },
    "visitor": {
        "id": "51b6d2d74ac24af38cbfbb7cf5529845",
        "channel": {
            "id": "873afd9cfeec448dba19a5c974940bfc",
            "type": "telegram",
            "user_id": "67854257"
        }
    },
    "messages": [
            {
                "kind":"visitor",
                "text":"Мне нужна ваша помощь"
            }
    ]
}
```

Описание параметров:

| Название параметра        | Тип               | Описание                                                                                                                                                                                                                                                 |
| ------------------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `event`                   | `String`          | Описывает, какое событие произошло.                                                                                                                                                                                                                      |
| `chat.id`                 | `String`          | Уникальный идентификатор чата. Представлен в формате UUID4. Данный идентификатор назначается чату на фронтэнде и не совпадает с другим идентификатором чата, который отображается в истории диалога.<br>Пример: `7388e3b3-4065-4953-8638-2d41d6e6c730`   |
| `visitor.id`              | `String`          | Уникальный идентификатор пользователя.                                                                                                                                                                                                                   |
| `visitor.channel`         | `Object` / `null` | Канал, из которого пришёл посетитель. Объект с `id`, `type`, `user_id` либо `null` для веб-виджета. В `new_message` не передаётся.                                                                                                                       |
| `visitor.channel.id`      | `String`          | Идентификатор канала в **Webim**. Совпадает с полем **Идентификатор канала** в настройках канала.                                                                                                                                                        |
| `visitor.channel.type`    | `String`          | Тип канала, например `telegram`, `vk`, `max`, `whatsapp_360dialog`.                                                                                                                                                                                      |
| `visitor.channel.user_id` | `String`          | Идентификатор посетителя в канале. Формат зависит от канала, см. [`channel_user_id`](https://webim.ru/kb/dev/identification/visitor-ids.html#channel_user_id).                                                                                                           |
| `messages`                | `String`          | Массив из сообщений пользователя, которые были отправлены в чат до его появления в РМО (например, во время выбора отдела в каналах).                                                                                                                     |

Сообщение (`message`) имеет вид:

```
{
    "kind": (string),
    "text*": (string),
    "response*": {
        "button": (button)
    }
}
```

Пример тела запроса:

```
{
    "kind": "keyboard_response",
    "response": {
        "button":{
            "id":"2",
            "text":"Обратиться в техническую поддержку"
        }
    }
}
```

Описание параметров:

| Название параметра | Тип      | Описание                                                                                                    |
| ------------------ | -------- | ----------------------------------------------------------------------------------------------------------- |
| `kind`             | `String` | `visitor` или `keyboard_response`.                                                                          |
| `text`             | `String` | Текст сообщения пользователя.<br>**Присутствует**, если `kind = visitor`.                                   |
| `response`         | `Object` | Описывает ответ пользователя на `keyboard` сообщение.<br>**Присутствует**, если `kind = keyboard_response`. |
| `response.button`  | `Button` | Описывает нажатую кнопку.                                                                                   |

Тип `Button` имеет вид:

```
{
    "id": (string),
    "text": (string)
}
```

Пример тела запроса:

```
{
    "id": "4",
    "text": "Перевести чат на оператора"
}
```

Описание параметров:

| Название параметра | Тип      | Описание                                                                      |
| ------------------ | -------- | ----------------------------------------------------------------------------- |
| `id`               | `String` | Уникальный идентификатор кнопки (не более 24 символов, не может быть пустым). |
| `text`             | `String` | Текст на кнопке.                                                              |

### Новое сообщение от клиента, нажатие кнопки (`new_message`)

Событие `new_message` инициируется в момент прихода нового сообщения от пользователя в чат (после нажатия пользователем кнопки), назначенный на робота.

URL-адрес сервера, куда передаются данные, берется из настроек бота (см. [выше](#setup)). Формат передаваемых данных: POST-запрос на сервер робота, данные в формате `JSON`.

Структура передаваемых данных зависит от типа сообщения пользования (значения параметра `kind`): оно может принимать значение `visitor` (если пользователь отправил текстовое сообщение) и `keyboard_response` (если пользователь выбрал ответ из предложенных ему через кнопочное меню).

Структура передаваемых данных (тип сообщения `visitor`):

```
{
    "event": "new_message",
    "chat": {
        "id": (string)
    },
    "kind": (string),
    "text": (string)
}
```

Пример тела запроса:

```
{
    "event": "new_message",
    "chat": {
        "id": "9401b039-ace3-4619-b884-a24e0aaf7adb"
    },
    "kind": "visitor",
    "text": "Здравствуйте, не могли бы вы мне помочь?"
}
```

Структура передаваемых данных (тип сообщения `keyboard_response`):

```
{
    "event": "new_message",
    "chat": {
        "id": (string)
    },
    "kind": (string),
    "response": {
        "button": (button)
    }
}
```

Пример тела запроса:

```
{
    "event": "new_message",
    "chat": {
        "id": "9401b039-ace3-4619-b884-a24e0aaf7adb"
    },
    "kind": "keyboard_response",
    "response": {
        "button": {
            "id": "937bec4863154a2fb0889ff1320d1e2f",
            "text": "Перевести диалог на Отдел продаж"
        }
    }
}
```

Описание параметров:

| Название параметра | Тип      | Описание                                                                                                                                                                                                                                                                       |
| ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `event`            | `String` | Описывает, какое событие произошло.<br>**Не может быть** `NULL`.                                                                                                                                                                                                               |
| `chat.id`          | `String` | Уникальный идентификатор чата. Представлен в формате UUID4. Данный идентификатор назначается чату на фронтэнде и не совпадает с другим идентификатором чата, который отображается в истории диалога. Не может быть `NULL`.<br>Пример: `7388e3b3-4065-4953-8638-2d41d6e6c730`   |
| `kind`             | `String` | **Обязательно принимает** одно из значений: `visitor` или `keyboard_response`.                                                                                                                                                                                                 |
| `text`             | `String` | Текст сообщения пользователя. **Не может быть** `NULL`, если `kind = visitor`.                                                                                                                                                                                                 |
| `response.button`  | `Button` | Описывает нажатую кнопку - ответ пользователя на `keyboard`-сообщение.<br>**Не может быть** `NULL`, если `kind = keyboard_response`.                                                                                                                                           |
| `button.id`        | `String` | Идентификатор нажатой кнопки.<br>**Не может быть** `NULL, если kind = keyboard_response`.                                                                                                                                                                                      |
| `button.text`      | `String` | Текст, содержащийся в нажатой посетителем кнопке.<br>**Не может быть NULL**, если `kind = keyboard_response`.                                                                                                                                                                  |

### Ожидаемые ответы на вопросы { #awaited-answers }

`200` (успешно)  

При любом другом ответе на запрос чат будет переведён в общую очередь.

На запрос со стороны **Webim** сервер робота должен ответить объектом JSON с параметрами:

| Название параметра | Тип       | Описание                                                                                                                                                                                                                            |
| ------------------ | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `has_answer`       | `Boolean` | <ul><li>`true` — робот может ответить на сообщение клиента;</li><li>`false` — робот не знает ответ: чат будет переведен в общую очередь, бот не отправит никаких сообщений или кнопок, даже если они содержатся в ответе.</li></ul> |
| `messages`         | `Array`   | Массив из сообщений.                                                                                                                                                                                                                |

!!! Note "N.B."
    Начиная с версии **10.8**, при обработке ответа внешнего бота действует следующая логика:

    * Если в ответе присутствует параметр `has_answer` (в любом значении), **все элементы из массива `messages` публикуются в чате** и отображаются в РМО.

    * Если `has_answer: true` — сообщения публикуются, и диалог **остаётся на боте**.

    * Если `has_answer: false` — сообщения публикуются, после чего диалог **снимается с бота** и **передаётся оператору** (в общую очередь).

    * Если параметр `has_answer` **отсутствует**, сообщения из ответа **игнорируются**, диалог **передаётся оператору**.

    Пример (`has_answer: false` c сообщениями):

    ```
    {
    "has_answer": false,
    "messages": [
            { 
                "kind": "operator", 
                "text": "Передаю вас специалисту" 
            }
        ] 
    }
    ```

Запрос с событием `new_chat` допускает пустое тело ответа. При пустом теле ответа на `new_message` либо при коде ответа от `400` до `599` на любой тип события чат переводится в общую очередь.

**Webim** ждёт ответа от сервера робота в течение 5 секунд по умолчанию. Таймаут можно изменить с помощью параметра `timeout_for_request_to_external_bot`. После истечения таймаута чат переводится в общую очередь.

Текстовое сообщение (`message`) имеет вид:

```
{
    "kind": (string),
    "text": (string)
}
```

Пример содержимого:

```
{
    "kind": "operator",
    "text": "Здравствуйте, отвечу на все ваши вопросы."
}
```

Описание параметров:

| Название параметра | Тип      | Описание                                           |
| ------------------ | -------- | -------------------------------------------------- |
| `kind`             | `String` | Значение `kind` **должно быть только** `operator`. |
| `text`             | `String` | Сообщение от оператора.                            |

Кнопочное сообщение (`message`) имеет вид:

```
{
    "kind": (string),
    "buttons": [
        [
            {
                "id": (string),
                "text": (string)
            }
        ]
    ]
}
```

Пример содержимого:

```
{
    "kind": "keyboard",
    "buttons": [
        [
            {
                "id": "ask_agent",
                "text": "Спросить у оператора"
            }
        ],
        [
            {
                "id": "ask_department",
                "text": "Обратиться в отдел"
            }
        ]
    ]
}
```

Описание параметров:

| Название параметра | Тип               | Описание                                                                                                               |
| ------------------ | ----------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `kind`             | `String`          | Значение `kind` **должно быть только** `keyboard`.                                                                     |
| `buttons`          | `Array of Arrays` | Массив массивов кнопок вида `[[b1, b2], [b3]]`.<br>Запись означает, что кнопки `b1`, `b2` расположены на одной строке. |

Объект `button` имеет вид:

```
{
    "id": (string),
    "text": (string)
}
```


Пример содержимого объекта `button`:

```
{
    "id": "4",
    "text": "Перевести чат на оператора"
}
```

Описание параметров:

| Название параметра | Тип      | Описание                                                 |
| ------------------ | -------- | -------------------------------------------------------- |
| `id`               | `String` | Идентификатор кнопки. Может быть не длиннее 24 символов. |
| `text`             | `String` | Текст кнопки                                             |

### Примеры отчётов { #report-examples }

Робот знает ответ:

```
{
    "has_answer": true,
    "messages": [
        {
            "kind": "operator",
            "text": "Мы работаем над вашей проблемой"
        },
        {
            "kind": "keyboard",
            "buttons": [
                [
                    {
                        "id": "call_agents",
                        "text": "Обратиться к операторам"
                    }
                ],
                [
                    {
                        "id": "call_agent",
                        "text": "Обратиться к оператору"
                    }
                ]
            ]
        }
    ]
}
```

Выглядит это так:

![Пример отчёта умного бота](https://webim.ru/kb/img/bots/smart-bot/v-1-0/report-example.webp){ style="width: 511px; max-width: 100%" }

Робот не знает ответа:

```
{
    "has_answer": false
}
```

---

Источник: https://webim.ru/kb/bots/smart-bot/v-1-0.html
