# Умный Бот 2.0

В **Webim** начиная с версии [10.1](https://webim.ru/webim-10-1/) подключение "внешних" или "умных" ботов, которые размещаются на внешнем относительно **Webim** сервере, происходит посредством **Умный Бот 2.0**. При этом предыдущая версия Умного Бота сохранена в 10.1 и следующих версиях для поддержки совместимости, то есть поддерживаются обе версии API.

## Описание { #description }

В отличие от предыдущей версии, **Умный Бот 2.0** является асинхронным. Робот принимает от пользователя вопрос и отправляет его на внешний сервер. Сервер генерирует ответ и присылает его обратно в сервис **Webim**, сервис показывает ответ пользователю. При этом сервер Webim не находится в ожидании ответа с сервера бота: тот сам пришлёт ответ, когда сформулирует его. В отличие от предыдущей версии Умного Бота, отвечать на запрос сразу же необязательно, необходимо лишь вернуть код `200` при успешном выполнении запроса, а ответ можно сформулировать потом.

---

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

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

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

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

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

---

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

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

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

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

  1. Перейдите в настройки Вашего аккаунта, выберите раздел [Боты](https://webim.ru/kb/bots/add-new-bot.html).

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

  1. Заполните информацию о вашем боте: привяжите его к новому оператору, выберите тип бота **Умный бот**, в качестве версии — `2`.

  1. В поле **Ссылка на внешний API** впишите URL-адрес внешнего сервера робота.

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

  1. После сохранения у вас автоматически сгенерируется токен авторизации запросов и отобразится в поле токена после сохранения.

---

## Базовый URL

Структура URL со стороны **Webim**:

`https://{hostname}/api/bot/v2/{path}`
Где `{hostname}` — имя хоста, на котором размещается сервер **Webim**, вида `{account}.webim.ru` для облачных клиентов и `chat.mycompany.com` для hosted; `{path}` — команда API.

Перечень эндпоинтов Умный Бот 2.0:

  * [`/api/bot/v2/send_message`](#send-message)

  * [`/api/bot/v2/redirect_chat`](#redirect-chat)

  * [`/api/bot/v2/close_chat`](#close-chat)

  * [`/api/bot/v2/file/{guid}?hash={hash}`](#file)

Пример URL:

`https://mycompany.webim.ru/api/bot/v2/redirect_chat`

Данный запрос переведёт чат на оператора.


!!! Note "N.B."
    URL со стороны бота задаётся в настройках

---

## Запросы к Webim { #incoming-requests }

Ниже изложены примеры и описания запросов к **Webim Server**.
Запросы отправляются на URL, указанный при создании бота.

### Авторизация { #auth }

Авторизация осуществляется через `header` с использованием токена (см. [здесь](#setup)). Для каждого бота генерируется новый токен.

Формат токена авторизации:

```
Authorization: Token {token}
```

Пример токена авторизации:

```
Authorization: Token ac650a3c369a4b9599ad52ab71943712
```

### Обработка ошибок  { #errors-callback }

Ответ **Webim** в случае успеха приходит с HTTP-кодом `200`.

Ошибки возвращаются в формате:

```
{
    "error":"код ошибки"
}
```

Если запрос не проходит валидацию, возвращается HTTP-код `400`.

При ошибке авторизации возвращается HTTP-код `403`.

Если робот с заданным токеном не найден, возвращается HTTP-код `403`.

Если использован метод не из описанных ниже, возвращает ошибку `{'error': 'method-not-found'}` с HTTP-кодом `400` для POST-запросов и `404` для GET-запросов.

При разных внутренних ошибках сервера возвращается ошибка с HTTP-кодом `500`.

Если отсутствует токен, сервер вернёт ошибку:

```
{"error": "unauthorized"}
```

Прочие ошибки приходят с HTTP-кодом `200` в формате:

```
{
    "error": (буквенный код ошибки),
    "desc": (текстовое описание ошибки)
}
```

Описание полей ошибок:

| Поле    | Тип      | Пример                                                                   | Описание                                                       | Обязательный |
| ------- | -------- | ------------------------------------------------------------------------ | -------------------------------------------------------------- | ------------ |
| `error` | `String` | `incorrect-request`                                                      | Код ошибки.                                                    | Да           |
| `desc`  | `String` | Запрос сформирован неверно. Возможно, пропущены необходимые параметры.   | Описание ошибки на английском языке. Не является обязательным. | Нет          |

### Ответ чат-бота на вопрос посетителя { #send-message }

**Path**: `/send_message`  

**Тип запроса**: `POST`  

**Content-type**: `application/json`  

**Query-string параметры**: не нужны

Пример URL при отправке ботом сообщения посетителю:

```
POST https://mycompany.webim.ru/api/bot/v2/send_message
```

Пример тела запроса при отправке ботом сообщения:

```
{
    "message": Message,
    "chat_id":3058
}
```

Описание полей объекта в ответе при отправке ботом сообщения:

| Поле      | Тип       | Описание            | Обязательный |
| --------- | --------- | ------------------- | ------------ |
| `message` | `JSON`    | Объект `Message`    | Да           |
| `chat_id` | `Integer` | Идентификатор чата  | Да           |

Объект `Message` может иметь разный набор полей в зависимости от типа сообщения.

#### Текстовое сообщение { #text-message }

Пример содержимого объекта `Message` в текстовом сообщении:

```
{
    "kind":"operator",
    "text":"Здравствуйте, чем я могу вам помочь?"
}
```
Описание полей объекта `Message` в текстовом сообщении:

| Поле   | Тип      | Пример                                                 | Описание                                                                                                                                                                       | Обязательный |
| ------ | -------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------ |
| `kind` | `String` | `operator`                                             | Тип сообщения. В данном случае это текстовое сообщение, где `kind = "operator"`. Все существующие типы сообщений есть в [данной статье](https://webim.ru/kb/dev/basic-objects/message-types.html). | Да           |
| `text` | `String` | `Здравствуйте. Мне нужна ваша консультация по тарифам` | Содержание текстового сообщения.                                                                                                                                               | Да           |

Описание возможных ошибок в текстовом сообщении:

| Код ошибки            | Описание                                                                                                                                            |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `message-not-created` | Не удалось создать сообщение. Возможно, запрос был сформирован неверно.                                                                             |
| `incorrect-request`   | Запрос сформирован неверно. Возможно, пропущены необходимые параметры.                                                                              |
| `chat-not-found`      | Чат с указанным id либо не был найден, либо не назначен на робота, либо диалог неактивен (потому что был закрыт, переведен в общую очередь и др.)   |

#### Файловое сообщение { #file-message }

!!! Warning "Внимание!"
    **Умный Бот** не предусматривает возможность загрузки файла прямым запросом от бота на чат-сервер. Для отправки файла необходимо в объекте Message указать URL, по которому чат-сервер скачает файл. В случае, если у вас возникли вопросы касательно данного метода или загрузки файлов в чат, обратитесь, пожалуйста, в [техническую поддержку](mailto:support@webim.ru) или к вашему аккаунт-менеджеру.

Пример содержимого объекта `Message` для файлового сообщения:

```
{
    "kind":"file_operator",
    "data":{
        "url":"https://webim.ru/wp-content/uploads/2019/04/diagram.png",
        "name":"diagram.png",
        "media_type":"image/png"
    }
}
```
Описание полей объекта `Message` для файлового сообщения:

| Поле              | Тип      | Пример                                 | Описание                                                                                                                                                                                                                                                                                                                                                                                                                        | Обязательный |
| ----------------- | -------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| `kind`            | `String` | `file_operator`                        | Тип сообщения. В данном случае это сообщения оператора, содержащие отправленные файлы. Все существующие типы сообщений есть в [данной статье](https://webim.ru/kb/dev/basic-objects/message-types.html).                                                                                                                                                                                                                                           | Да           |
| `data.url`        | `String` | `https://somesite.com/img54-65-79.jpg` | URL-адрес файла.                                                                                                                                                                                                                                                                                                                                                                                                                | Да           |
| `data.name`       | `String` | `beautifulpicture.jpg`                 | Имя файла.<br>Имя должно содержать расширение.<br>Бот может отправлять файлы с расширениями, заданными параметром `robot_allowed_upload_file_types` настроек [`account config`](https://webim.ru/kb/getting-started/terms-and-concepts.html#account-config).                                                                                                                                                                                       | Да           |
| `data.media_type` | `String` | `image/jpeg`                           | [Internet Media Type](https://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_MIME-%D1%82%D0%B8%D0%BF%D0%BE%D0%B2).<br>Бот может отправлять файлы с `media type`, заданными параметром `robot_allowed_upload_file_content_types`.<br>Также могут быть наложены ограничения на размер файлов, отправляемых ботом (подробности см. в статье [Обработка файлов, загружаемых в чат](https://webim.ru/kb/devops/download-file-scheme.html)). | Да           |

Описание возможных ошибок в файловом сообщении:

| Код ошибки               | Описание                                                                                                                                             |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `insecure-file-type`     | Файл не прошел проверку безопасности.                                                                                                                |
| `incorrect-image`        | Некорректный файл с изображением.                                                                                                                    |
| `media-type-not-match`   | Несоответствие заявленного Media Type с фактическим.                                                                                                 |
| `max-file-size-exceeded` | Размер файла превышает допустимый.                                                                                                                   |
| `message-not-created`    | Не удалось создать сообщение. Возможно, запрос был сформирован неверно.                                                                              |
| `chat-not-found`         | Чат с указанным id либо не был найден, либо не назначен на робота, либо диалог неактивен (потому что был закрыт, переведен в общую очередь и др.).   |
| `incorrect-request`      | Запрос сформирован неверно. Возможно, пропущены необходимые параметры.                                                                               |

#### Сообщение с кнопками { #button-message }

Пример содержимого объекта `Message` для сообщения с кнопками:

```
{
    "kind":"keyboard",
    "buttons":[
        [
            {
                "text":"Перевести на техподдержку",
                "id":"fedc60c4dc0d4348b48b524d"
            }
        ],
        [
            {
                "text":"Перевести на отдел продаж",
                "id":"574f2caad88a41a7a2d6b667"
            }
        ]
    ]
}
```

Описание полей объекта `Message` для сообщения с кнопками:

| Поле      | Тип      | Описание                                                                                                                                                                               | Обязательный |
| --------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| `kind`    | `String` | Тип сообщения. Сообщения с кнопками являются типами `keyboard` или `keyboard_response`. Все существующие типы сообщений есть в [данной статье](https://webim.ru/kb/dev/basic-objects/message-types.html). | Да           |
| `buttons` | `list`   | Вложенный массив, содержащий данные об отправляемых посетителю кнопках. Позволяет группировать наборы кнопок, предлагаемые посетителю, в строки.                                       | Да           |

В свою очередь `Buttons` состоит из массивов `Button`.

Каждый объект `Button` содержит в массиве следующие параметры:

| Поле   | Тип      | Пример                     | Описание                                                                                                                                                                                                                                                                                                                  | Обязательный |
| ------ | -------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| `id`   | `String` | `937bec4863154a2fb0889ff1` | Идентификатор кнопки. Может содержать только латинские буквы, цифры, символы дефиса и нижнего подчёркивания и должен быть не более 24 символов в длину. ID кнопки, генерируемый сервером **Webim**, имеет формат `UUID4`, а ID, генерируемый сторонними ботами, только проверяется на соответствие данным выше критериям. | Да           |
| `text` | `String` | `Задать вопрос оператору`  | Текст кнопки.                                                                                                                                                                                                                                                                                                             | Да           |

**Особенности отображения клавиатуры в Telegram**

В Telegram существуют два основных типа клавиатур:

  * **Inline-клавиатура (InlineKeyboardMarkup)** — кнопки отображаются прямо под сообщением.
  
  * **Reply-клавиатура (ReplyKeyboardMarkup)** — кнопки отображаются вместо стандартной клавиатуры пользователя.

При отправке сообщения вида `kind: "keyboard"` или `kind: "keyboard_response"` через Webim External Bot API выбор конкретного типа Telegram-клавиатуры явно не настраивается.  
Для Telegram-канала такие сообщения отображаются как обычная reply-клавиатура (ReplyKeyboardMarkup). Inline-клавиатура через External Bot API в данный момент не конфигурируется.

Структура поля `buttons` определяет расположение кнопок на клавиатуре:

  * массив `buttons` — это список строк клавиатуры;
  
  * каждый вложенный массив внутри `buttons` — отдельная строка;
  
  * все объекты `Button`, перечисленные в одном вложенном массиве, будут располагаться **горизонтально** в одной строке;
  
  * если каждую кнопку поместить в отдельный вложенный массив, кнопки будут располагаться **вертикально** друг под другом.

Пример двух строк с горизонтальным расположением:

```json
{
  "kind": "keyboard",
  "buttons": [
    [
      { "text": "Текст1" },
      { "text": "Текст2" }
    ],
    [
      { "text": "Текст3" },
      { "text": "Текст4" }
    ]
  ]
}
```

В Telegram такая клавиатура будет состоять из двух строк, в каждой — по две кнопки.

Пример строго вертикального расположения:

```json
{
  "kind": "keyboard",
  "buttons": [
    [ { "text": "Текст1" } ],
    [ { "text": "Текст2" } ],
    [ { "text": "Текст3" } ],
    [ { "text": "Текст4" } ]
  ]
}
```

В этом случае все кнопки будут располагаться вертикально, по одной кнопке в строке.

Описание возможных ошибок в сообщении с кнопками:

| Код ошибки            | Описание                                                                                                                                             |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `incorrect-buttons`   | Сообщение с кнопками составлено неверно.                                                                                                             |
| `message-not-created` | Не удалось создать сообщение. Возможно, запрос был сформирован неверно.                                                                              |
| `incorrect-request`   | Запрос сформирован неверно. Возможно, пропущены необходимые параметры.                                                                               |
| `chat-not-found`      | Чат с указанным id либо не был найден, либо не назначен на робота, либо диалог неактивен (потому что был закрыт, переведен в общую очередь и др.).   |

### Перевод чата { #redirect-chat }

Чат может переводиться на конкретного оператора, отдел или же в общую очередь. Если при переводе не указан ни оператор, ни отдел для перевода, чат будет перенаправлен в общую очередь. Если при переводе чата указан и оператор, и отдел, то запрос не выполнится корректно и чат не будет перенаправлен (необходимо указывать что-то одно).

**Path**: `/redirect_chat`  

**Тип запроса**: `POST`  

**Content-type**: `application/json`  

**Query-string параметры**: не нужны

Пример URL при переводе чата:

```
POST https://mycompany.webim.ru/api/bot/v2/redirect_chat
```

#### Перевод на оператора { #redirect-to-agent }

Пример тела запроса при переводе чата на оператора:

```
{
    "operator_id":486254,
    "chat_id":195
}
```

Описание полей объекта в ответе на запрос при переводе чата на оператора:

| Поле          | Тип     | Пример   | Описание                 | Обязательный |
| ------------- | ------- | -------- | ------------------------ | ------------ |
| `operator_id` | Integer | `168524` | Идентификатор оператора. | Да           |
| `chat_id`     | Integer | `426`    | Идентификатор чата.      | Да           |

Описание возможных ошибок при переводе чата на оператора:

| Код ошибки           | Описание                                                                                                                                             |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `operator-not-found` | Оператор с указанным id не найден.                                                                                                                   |
| `target-is-offline`  | Оператор в состоянии `offline`.                                                                                                                      |
| `incorrect-request`  | Запрос сформирован неверно. Возможно, пропущены необходимые параметры.                                                                               |
| `chat-not-found`     | Чат с указанным id либо не был найден, либо не назначен на робота, либо диалог неактивен (потому что был закрыт, переведен в общую очередь и др.).   |
| `wrong-operator-id`  | Бот не может перенаправить чат на самого себя.                                                                                                       |

#### Перевод на отдел { #redirect-to-department }

Пример тела запроса при переводе чата на отдел:

```
{
    "dep_key":"sales_department",
    "chat_id":425,
    *"allow_redirect_to_offline_dep":false,
    *"allow_redirect_to_invisible_dep":true
}
```

Описание полей объекта в ответе на запрос при переводе чата на отдел:

| Поле                              | Тип       | Пример               | Описание                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | Обязательный |
| --------------------------------- | --------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| `dep_key`                         | `String`  | `sales_department`   | Идентификатор (текстовый ключ) отдела.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | Да           |
| `chat_id`                         | `Integer` | `168`                | Идентификатор чата.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | Да           |
| `allow_redirect_to_offline_dep`   | `Boolean` | `false`              | Переводить ли чат на отдел, если в нем все операторы офлайн. Соответственно, обращения переводятся и при операторах в остальных статусах — [Невидимке](https://webim.ru/kb/for-agents/agent-gui/select-status.html) и прочих. По умолчанию `false`.                                                                                                                                                                                                                                                                                                      | Нет          |
| `allow_redirect_to_invisible_dep` | `Boolean` | `true`               | Переводить ли чат на отдел, если в нем нет операторов онлайн — достаточно, чтобы оператор был в статусе **Невидимка** или аналогичных ему. Если включён параметр `allow_redirect_to_offline_dep`, тогда функциональность `allow_redirect_to_invisible_dep` включается автоматически, так как это более сильное свойство. Таким образом, от предыдущего параметра данный параметр отличается тем, что при его включении чаты не переводятся только в те отделы, где все операторы находятся в статусе **Офлайн**. По умолчанию `true`. | Нет          |
| `ignore_bots`                     | `Boolean` | `true`               | Игнорировать ли ботов при перенаправлении чата. По умолчанию `true`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | Нет          |

!!! Note "N.B."
    Из двух параметров — `allow_redirect_to_offline_dep` и `allow_redirect_to_invisible_dep` — в теле запроса может присутствовать только один; в противном случае в ответ на запрос сервер вернёт ошибку.

Описание возможных ошибок при переводе чата на отдел:

| Код ошибки             | Описание                                                                                                                                                                                                           |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `department-not-found` | Отдел с указанным id не найден.                                                                                                                                                                                    |
| `target-is-offline`    | Отдел в состоянии `offline`.                                                                                                                                                                                         |
| `incorrect-request`    | <ul><li>Запрос сформирован неверно. Возможно, пропущены необходимые параметры.</li><li>В запросе одновременно присутствуют параметры `allow_redirect_to_offline_dep` и `allow_redirect_to_invisible_dep`</li></ul> |
| `chat-not-found`       | Чат с указанным id либо не был найден, либо не назначен на робота, либо диалог неактивен (потому что был закрыт, переведен в общую очередь и др.).                                                                 |

#### Перевод в общую очередь { #redirect-to-queue }

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

```
{
  "chat_id": 425
}
```

Описание полей объекта в ответе на запрос при переводе чата на оператора:

| Поле          | Тип     | Пример   | Описание            | Обязательный |
| ------------- | ------- | -------- | ------------------- | ------------ |
| `chat_id`     | Integer | `426`    | Идентификатор чата. | Да           |

### Закрытие чата { #close-chat }

**Path**: `/close_chat`  

**Тип запроса**: `POST`  

**Content-type**: `application/json`  

**Query-string параметры**: не нужны

Пример URL при закрытии чата:

```
POST https://mycompany.webim.ru/api/bot/v2/close_chat
```

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

```
{
    "chat_id":462
}
```

Описание полей объекта в ответе на запрос при закрытии чата:

| Поле      | Тип       | Пример | Описание           | Обязательный |
| --------- | --------- | ------ | ------------------ | ------------ |
| `chat_id` | `Integer` | `241`  | Идентификатор чата | Да           |

Описание возможных ошибок при закрытии чата:

| Код ошибки          | Описание                                                                                                                                           |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `incorrect-request` | Запрос сформирован неверно. Возможно, пропущены необходимые параметры.                                                                             |
| `chat-not-found`    | Чат с указанным id либо не был найден, либо не назначен на робота, либо диалог неактивен (потому что был закрыт, переведен в общую очередь и др.). |

### Скачивание файлов { #file }

При помощи данного запроса клиент может скачать файл, присланный посетителем в чате с ботом.

**Path**: `/file/{guid}?hash={hash}`  

**Тип запроса**: `GET`  

**Query-string параметры**: `hash` – посчитанный hash

Пример URL при скачивании файлов:

```
GET https://mycompany.webim.ru/api/bot/v2/file/7d5d197ef3ee4b29be6b1a668977ccdc?hash=e96881ac8db26e8570cd9c032900cd3e0b08128132e61c844102633c64a69b2a
```
где:

  * `7d5d197ef3ee4b29be6b1a668977ccdc` – `guid` (уникальный идентификатор) файла;

  * `e96881ac8db26e8570cd9c032900cd3e0b08128132e61c844102633c64a69b2a` – hash-сумма файла, помогающая обезопасить файл от нежелательного скачивания

Результатом обращения на данный URL будет скачивание клиентом файла, присланного посетителем в чате. Механизм скачивания файлов, присланных посетителем, описан в [этой статье](https://webim.ru/kb/devops/download-file-scheme.html).

Ссылка на скачивание файла приходит внутри сообщения, у которого `kind = file_visitor`.

Если не прошла авторизация с хэшем файла, сервер вернёт ошибку: `403 {'error': 'access-denied'}`

Если файл не найден или использован метод не `file`, сервер вернёт ошибку: `404 {'error': 'file-not-found'}`

---

## Запросы от Webim на бот-сервер { #outcoming-requests }

**Webim** обращается на URL-адрес бота, который задаётся в настройках Панели управления при создании бота (см. [пункт 5](#setup)).

Для этих запросов авторизация не требуется.

Для повышения безопасности в URL бота ([пункт 5](#setup)) можно добавить секретный ключ. Он вставляется в URL следующим образом: вместо `address` указывается `address/secret_key`, где `secret_key` – некоторая последовательность символов.

Если **Webim** не удаётся доставить HTTP-запрос на сервер бота (например, из-за ошибки соединения или таймаута), **Webim** выполнит до 5 попыток отправки: первую — сразу, затем ещё 4 повтора. Пауза между повторами увеличивается в 2 раза и составляет 2, 4, 8 и 16 секунд после каждой неудачной попытки.

Если бот ответил, но вернул не HTTP-код `200` или в теле ответа нет `{"result":"ok"}`, повторные попытки не выполняются.

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

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

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

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

### Обработка ошибок { #bot-errors }

В случае успеха бот должен дать следующий ответ:

`200 OK`

Тело ответа бот-сервера на запрос **Webim** должно содержать:

```
{
   "result":"ok"
}
```

В случае получения другого ответа чат будет переведен в общую очередь.

### Назначение чата на робота { #assigning-to-bot }

**Тип запроса**: `POST`  

**Content-type**: `application/json`  

**Query-string параметры**: не нужны

Вызывается при создании чата либо при переводе чата на робота.

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

```
{
    "event":"new_chat",
    "chat":{
        "id":452
    },
    "visitor":{
        "id":"03e1c040d8214bfa8ccfbb053186a24a",
        "channel":{
            "id":"873afd9cfeec448dba19a5c974940bfc",
            "type":"vk",
            "user_id":"16845896"
        },
        "fields":{
            "email":"support@webim.ru",
            "id":"asdf123",
            "icq":"123123123",
            "login":"somelogin",
            "name":"asdf123",
            "phone":"+7 (812) 385-53-37",
            "profile_url":"https://vk.ru/webimru",
            "site":"https://webim.ru"
        }
    },
    "messages": [
        Message,
        Message,
        ...
    ]
}
```

Описание полей объекта в ответе на запрос:

| Поле              | Тип                       | Пример                                                 | Описание                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | Обязательный |
| ----------------- | ------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| `event`           | `String`                  | `new_chat`                                             | Тип события.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | Да           |
| `chat.id`         | `Integer`                 | `247`                                                  | Идентификатор чата.                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | Да           |
| `visitor.id`      | `String`                  | `03e1c040d8214bfa8ccfbb053186a24a`                     | Псевдоуникальный идентификатор посетителя, который ему всегда назначает **Webim**.                                                                                                                                                                                                                                                                                                                                                                                                                | Да           |
| `visitor.channel` | `Object` / `null`         | `{"id": "...", "type": "vk", "user_id": "..."}`        | Канал, из которого пришёл посетитель. Поле всегда присутствует в событии `new_chat`. Если обращение из канала, объект содержит `id` (идентификатор канала в **Webim**), `type` (тип канала, например `telegram`, `vk`, `max`) и `user_id` (идентификатор посетителя в канале, см. [`channel_user_id`](https://webim.ru/kb/dev/identification/visitor-ids.html#channel_user_id)). Если посетитель пришёл с веб-виджета, значение равно `null`. В событии `new_message` это поле не передаётся.                     | Да           |
| `visitor.fields`  | `JSON`                    | `{"name": "Владислав", "phone": "+79113258746", ...}`  | Известная информация о посетителе в виде пар ключ-значение. Идентификатор посетителя внутри `visitor.fields` передаётся в **Webim** фронтэндом, может быть произвольного вида и не быть уникальным. Если отсутствует `visitor.fields`, то идентификатор, соответственно, отсутствует. В случае наличия **visitor.fields** идентификатор является обязательным полем, все остальные поля — нет. Описание всех полей `visitor.fields` можно посмотреть [здесь](https://webim.ru/kb/dev/identification/id-2-0.html). | Нет          |
| `messages`        | Массив объектов `Message` | Приведены ниже в описании события `new_message`        | Сообщения, которые присылал посетитель и которые накопились к моменту, когда чат был назначен на бот (сообщение из каналов, из виджета, если включён запрос контактных данных перед началом чата).                                                                                                                                                                                                                                                                                                | Нет          |

### Новое сообщение { #new-message }

**Тип запроса**: `POST`  

**Content-type**: `application/json`  

**Query-string параметры**: не нужны

Пример тела запроса при отправке сообщения боту:

```
{
    "event":"new_message",
    "message": Message,
    "chat_id":245
}
```

Описание полей объекта в ответе на запрос:

| Поле      | Тип       | Пример          | Описание            | Обязательный |
| --------- | --------- | --------------- | ------------------- | ------------ |
| `event`   | `String`  | `new_message`   | Тип события.        | Да           |
| `message` | `Message` | Приведены ниже  | Объект Message.     | Да           |
| `chat_id` | `Integer` | `247`           | Идентификатор чата. | Да           |

Объект `Message` может содержать в себе разные виды данных и полей.

#### Текстовое сообщение { #bot-text }

Пример содержимого объекта `Message` в текстовом сообщении:

```
{
    "id":"feb8e0f7fe08486db2494c2d5058fd33",
    "kind":"visitor",
    "text":"Здравствуйте"
}
```

Описание полей объекта `Message`:

| Поле   | Тип      | Пример                               | Описание                                                                                                                                                                                           | Обязательный |
| ------ | -------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| `id`   | `String` | `feb8e0f7fe08486db2494c2d5058fd3"`   | Идентификатор сообщения на стороне **Webim**.                                                                                                                                                      | Да           |
| `kind` | `String` | `operator`                           | Тип сообщения. Все типы поддерживаемых **Webim** сообщений перечислены в этой [статье](https://webim.ru/kb/dev/basic-objects/message-types.html). При использовании **Умный Бот 2.0** применимы не все из них. | Да           |
| `text` | `String` | `Могу ли я вам помочь?`              | Текст.                                                                                                                                                                                             | Да           |

#### Файловое сообщение { #bot-file }

Бот должен вернуть ответ `{"result": "ok"}` для сообщений, где `media_type = json`.

По мере отправки файла будет отправляться не один, а несколько запросов, количество которых зависит от размера файла: чем большего он размера, тем длительнее загрузка. В процессе загрузки файла (при значении `upload` в поле `state`) каждый новый запрос будет содержать обновлённое значение процентов загрузки файла (поле `progress`). Последний запрос при отправке файла будет иметь значение `ready` в поле `state`, что значит, что файл отправлен.

Пример содержимого объекта `Message` в запросах с файловым сообщением:

```
{
    "id":"c3e19d57f64e43c3afabdef2ef4e4054",
    "kind":"file_visitor",
    "data":{
        "id":"81f0488",
        "state":"upload",
        "progress": 50,
        "size":560
        "url":"https://yoursite.com/content/file.txt",
    }
}
{
    "id":"c3e19d57f64e43c3afabdef2ef4e4054",
    "kind":"file_visitor",
    "data":{
        "id":"81f0488",
        "state":"upload",
        "progress": 89,
        "size":560
        "url":"https://yoursite.com/content/file.txt",
    }
}
{
    "id":"c3e19d57f64e43c3afabdef2ef4e4054",
    "kind":"file_visitor",
    "data":{
        "state":"ready",
        "name":"file.txt",
        "media_type":"text",
        "size":560
        "url":"https://yoursite.com/content/file.txt",
    }
}
```

Описание полей объекта `Message`:

| Поле              | Тип       | Пример                                        | Описание                                                                                                                                                                            | Обязательный |
| ----------------- | --------- | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| `id`              | `String`  | `6355ba4163f947b9b77f7e65ce4317a7`            | Идентификатор сообщения на стороне **Webim**.                                                                                                                                       | Да           |
| `kind`            | `String`  | `file_visitor`                                | Тип сообщения, в данном случае файл, отправленный посетителем (`file_visitor`). Все существующие типы сообщений перечислены в этой [статье](https://webim.ru/kb/dev/basic-objects/message-types.html). | Да           |
| `data.state`      | `String`  | `upload`                                      | Состояние, в котором находится отправленный файл (`upload` — если находится в процессе загрузки, `ready` — если загрузка завершена).                                                | Да           |
| `data.name`       | `String`  | `somefile.pdf`                                | Название файла. При `data.state = upload` может отсутствовать.                                                                                                                      | Нет          |
| `data.media_type` | `String`  | `application/pdf`                             | Internet Media Type. При `data.state = upload` может отсутствовать.                                                                                                                 | Нет          |
| `data.size`       | `Integer` | `12350`                                       | Размер файла в байтах.                                                                                                                                                              | Нет          |
| `data.progress`   | `Integer` | `95`                                          | Степень загрузки файла при `data.state = upload`. Указывается в процентах.                                                                                                          | Нет          |
| `data.url`        | `String`  | `https://yoursite.com/content/document.pdf`   | URL-адрес загруженного файла (при `data.state = ready`).                                                                                                                            | Да           |

#### Нажатие на кнопку { #bot-buttons }

Запрос содержит выбранную посетителем кнопку.

Пример содержимого объекта `Message` в сообщении с нажатой кнопкой:

```
{
    "id":"ddaa8401e1ef4910abb3657f3ea09683",
    "kind":"keyboard_response",
    "data":{
        "button":{
            "id":"937bec4863154a2fb0889ff1320d1e2f",
            "text":"Задать вопрос оператору"
        },
        "request":{
            "messageId":"fede9187f3da41c9849976a01a40d899"
        }
    }
}
```

Описание полей объекта `Message`:

| Поле                     | Тип      | Пример                               | Описание                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | Обязательный |
| ------------------------ | -------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| `id`                     | `String` | `ddaa8401e1ef4910abb3657f3ea09683`   | Идентификатор сообщения на стороне **Webim**.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | Да           |
| `kind`                   | `String` | `keyboard_response`                  | Тип сообщения. Все типы сообщений в этой [статье](https://webim.ru/kb/dev/basic-objects/message-types.html)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | Да           |
| `data.button`            | `Button` | Объект `Button`                      | Нажатая посетителем кнопка. В некоторых [каналах общения](https://webim.ru/kb/channels/channels-functions.html) (например, WhatsApp[^whatsapp_footnote], ВКонтакте) кнопки выводятся в виде нумерованного списка (текстом). При таком формате посетитель выбирает кнопку путём отправки сообщения с номером кнопки. Иными словами, кнопка считается выбранной только при условии, что кнопка есть в перечне и что посетитель отправил именно номер кнопки (например, "2"). Если посетитель пришлёт номер несуществующей кнопки (например, при перечне кнопок от 1 до 8 пришлёт цифру 9) или пришлёт кнопку в любом другом виде (текст кнопки, номер вместе с текстом и т. п.), кнопка выбрана не будет и запрос не будет отправлен. | Да           |
| `data.request.messageId` | `String` | `"fede9187f3da41c9849976a01a40d899"` | Идентификатор сообщения, кнопка которого была нажата.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | Да           |

### Обновление сообщения { #message-update }

**Тип запроса**: `POST`  

**Content-type**: `application/json`  

**Query-string параметры**: не нужны

Пример тела запроса при обновлении сообщения:

```
{
    "event": "message_updated",
    "message": Message,
    "chat_id": 8754
}
```

Описание полей объекта в ответе на запрос:

| Поле      | Тип       | Пример                                                                          | Описание                                       | Обязательный |
| --------- | --------- | ------------------------------------------------------------------------------- | ---------------------------------------------- | ------------ |
| `event`   | `String`  | `message_updated`                                                               | Тип события.                                   | Да           |
| `message` | `Message` | Объект `Message`. Его вид аналогичен виду в событии [new_message](#new-message) | Содержание объекта `Message` после обновления. | Да           |
| `chat_id` | `Integer` | `2547`                                                                          | Идентификатор чата.                            | Да           |

[^whatsapp_footnote]: WhatsApp принадлежит корпорации Meta, деятельность которой признана экстремистской и запрещена в РФ.

---

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