# Детальные статусы звонка

Начиная с версий Itgrix bx [3.5.1](https://docs.itgrix.ru/changelog-bx#3.5.1) и Itgrix amo [2.8.0](https://docs.itgrix.ru/changelog-amo#2.8.0), мы расширили список распознаваемых статусов звонков от всего двух (Успешный и Пропущенный) до почти всех, какие поддерживаются в CRM.

## Теперь нам нужно Extra

Одновременно с этим возросли наши требования к настройке Asterisk: для выяснения результата звонка нам необходимо наличие поля "extra" в таблице CEL. Если вдруг у вас его нет, то статусы звонка будут работать по-старому с только двумя базовыми значениями.

Несмотря на временную поддержку CEL без extra, оставлять настройки в несоответствующем системным требованиям виде не стоит, потому что мы уже опираемся на содержание extra для обработки перехвата звонков и будем рассчитывать на наличие extra при разработке новых функций.

{% hint style="info" %}
Если новые статусы звонка пока не соответствуют вашим ожиданиям, можно временно их отключить, сделав поле extra недоступным.

Для этого нужно в конфиге в поле database.column\_name\_aliases.cel\_extra прописать значение "id" вместо "extra" - тогда модуль вместо extra будет смотреть в поле id, не увидит ожидаемых данных и будет работать без них по-старому.

Не забудьте перезапустить службу чтобы изменения вступили в силу и сообщить нам что нужно изменить в статусах звонков чтобы они работали более правильно.
{% endhint %}

## Статусы в Asterisk

В основе статусов звонков лежит новое для нас свойство звонка - **результат**. Это итог попытки абонента А позвонить абоненту Б, выражаемый [кодом из протокола SIP](https://en.wikipedia.org/wiki/List_of_SIP_response_codes). Коды по виду и смыслу похожи на статус-коды протокола HTTP, например 404 означает "не найдено", но в приложении к телефонии.\
Результат звонка не является в прямом смысле статус-кодом SIP, но набор ситуаций, описываемых этими кодами, очень подходит по смыслу.

Чтобы определить результат звонка, мы опираемся на содержимое поля extra, где есть задаваемые Asterisk'ом значения `hangup_cause` и `dial_status`.\
`hangup_cause` принимает значения от 0 до 127, и некоторые из них [соответствуют](https://wiki.asterisk.org/wiki/display/AST/Hangup+Cause+Mappings) одному или нескольким статус-кодам SIP.\
`dial_status` может быть пустым или принимать [одно из 9 значений](https://www.voip-info.org/asterisk-variable-dialstatus/), таких как "ANSWERED" или "CANCEL".\
Оба этих поля вместе позволяют нам определить результат звонка:

| hangup cause                                             | dial status                         | Результат звонка                              |
| -------------------------------------------------------- | ----------------------------------- | --------------------------------------------- |
| 0 Не определено                                          |                                     | 0 Неизвестно - обрабатываем звонок по-старому |
| любой                                                    | CANCEL                              | 480 Временно недоступен                       |
| любой                                                    | <p>CHANUNAVAIL</p><p>CONGESTION</p> | 500 Ошибка сервера                            |
| <p>1 Unallocated</p><p>20 SubscriberAbsent</p>           | ANSWER                              | 200 Успех                                     |
| <p>1 Unallocated</p><p>20 SubscriberAbsent</p>           |                                     | 404 Не найдено                                |
| 16 NormalClearing                                        | <p>пусто</p><p>ANSWER</p>           | 200 Успех                                     |
| 16 NormalClearing                                        | NOANSWER                            | 408 Таймаут запроса                           |
| 16 NormalClearing                                        | BUSY                                | 486 Абонент занят                             |
| 17 UserBusy                                              |                                     | 486 Абонент занят                             |
| 18 NoUserResponse                                        |                                     | 408 Таймаут запроса                           |
| 19 NoAnswer                                              |                                     | 480 Временно недоступен                       |
| 21 CallRejected                                          |                                     | 603 Вызов отклонён                            |
| 26 AnsweredElsewhere                                     |                                     | 200 Успех                                     |
| 28 InvalidNumberFormat                                   |                                     | 484 Не полный адрес                           |
| <p>34 NormalCircuitCongestion</p><p>127 Interworking</p> |                                     | 500 Ошибка сервера                            |
| 38 NetworkOutOfOrder                                     |                                     | 500 Ошибка сервера                            |
| 44 RequestedChanUnavail                                  | ANSWER                              | 200 Успех                                     |
| 44 RequestedChanUnavail                                  |                                     | 500 Ошибка сервера                            |
| 58 BearercapabilityNotavail                              |                                     | 488 Невозможно принять                        |
| 66 ChanNotImplemented                                    | ANSWER                              | 200 Успех                                     |
| 66 ChanNotImplemented                                    |                                     | 405 Метод не поддерживается                   |

Очевидно, что здесь учтены не все 1280 возможных комбинаций. Некоторые значения `hangup_cause` не используются Asterisk, некоторые комбинации не имеют смысла и невозможны, но самое главное - наше предварительное исследование показало, что этот набор вариантов покрывает все распространённые случаи.\
По мере обнаружения, новые случаи будут добавляться в список, а пока они будут обрабатываться по-старому, с двумя вариантами.

## Статусы в CRM

Каждая CRM конечно же имеет своё представление о том, какие у звонка могут быть статусы.\
Они зависят от точки зрения конкретной CRM на роль звонков в бизнес-процессе и модель взаимодействия сотрудника со звонком.\
Важно, что в CRM как задавать, так и читать статус звонка могут пользователи, а не только автоматика, и поэтому список вариантов должен быть интуитивно понятным и не слишком большим.\
На этот уменьшенный набор статусов мы транслируем наш набор результатов звонка.

### Bitrix24

[Статусы звонков в Битрикс24](https://helpdesk.bitrix24.ru/open/6017375/?sphrase_id=69423046) основаны на статус-кодах SIP, так же как и наш результат звонка, с небольшими особенностями:

| Статус                             | Описание от Битрикс24                                                                                     | Пример отображаемого текста                                              |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| 200 Успешный звонок                | запрос был успешно принят, распознан и подтвержден                                                        | Входящий звонок от <номер> завершен. Успешный звонок                     |
| 304 Пропущенный звонок             | для этого статуса мы взяли нестандартный код                                                              | Пропущен входящий звонок от <номер>. Пропущенный звонок                  |
| 402 Недостаточно средств на счету  | требуется оплата                                                                                          | Вы не можете совершить звонок, на вашем счету недостаточно средств.      |
| 403 Запрещено                      | абонент не зарегистрирован                                                                                | Звонок на номер <номер> завершен. Запрещено                              |
| 404 Неверный номер                 | вызываемый абонент не найден, нет такого SIP-номера                                                       | Звонок на номер <номер> невозможен. Данное направление не обслуживается. |
| 423 Заблокировано                  | сервер отклоняет запрос, так как слишком короткий интервал (или номер в черном списке Битрикс24)          | нет                                                                      |
| 480 Временно не доступен           | временно недоступное направление, попробуйте позвонить позже                                              | Абонент <номер> временно недоступен.                                     |
| 484 Данное направление не доступно | принят запрос с неполным адресом                                                                          | Звонок на номер <номер> невозможен. Данное направление не обслуживается. |
| 486 Занято                         | абонент занят                                                                                             | Абонент <номер> занят другим звонком.                                    |
| 500 Внутренняя ошибка сервера      | звонок на абонента, который не зарегистрирован в сети, либо выключил телефон                              | нет                                                                      |
| 503 Данное направление не доступно | сервер не может в данный момент обслужить вызов из-за перегрузки или проведения технического обслуживания | Звонок на номер <номер> завершен. Данное направление не доступно         |
| 603 Отклонено                      | вызов отменен из-за "падения" сети                                                                        | Абонент <номер> отменил вызов.                                           |
| 603-S Вызов отменен                | вызываемый пользователь не желает принимать входящие вызовы, не указывая причину отказа                   | Звонок на номер <номер> отменен.                                         |

Итоговый статус определяется по результату звонка:

| Результат звонка            | Доп условия                  | Статус BX24                        |
| --------------------------- | ---------------------------- | ---------------------------------- |
| 200 Успех                   | Звонок входящий неотвеченный | 304 Пропущенный звонок             |
| 200 Успех                   |                              | 200 Успешный звонок                |
| 404 Не найдено              |                              | 404 Неверный номер                 |
| 405 Метод не поддерживается |                              | 405                                |
| 408 Таймаут запроса         |                              | 304 Пропущенный звонок             |
| 480 Временно недоступен     |                              | 304 Пропущенный звонок             |
| 484 Не полный адрес         |                              | 484 Данное направление не доступно |
| 486 Абонент занят           | Звонок входящий неотвеченный | 304 Пропущенный звонок             |
| 486 Абонент занят           |                              | 486 Занято                         |
| 488 Невозможно принять      |                              | 484 Данное направление не доступно |
| 500 Ошибка сервера          |                              | 500 Внутренняя ошибка сервера      |
| 603 Вызов отклонён          |                              | 603 Отклонено                      |
| 0 Неизвестно                | Отвеченный звонок            | 200 Успешный звонок                |
| 0 Неизвестно                | Неотвеченный звонок          | 304 Пропущенный звонок             |

### amoCRM

[Статусы звонка в Amo](https://www.amocrm.ru/developers/content/telephony/calls_add) не основаны на статус-кодах SIP, а нацелены по смыслу на заполнение пользователем:

1. Оставил голосовое сообщение
2. Перезвонить позже
3. Нет на месте
4. Разговор состоялся
5. Неверный номер
6. Не дозвонился
7. Номер занят

Кроме статуса, в Амо также есть поле "Результат звонка", которое содержит произвольный **текст**. Мы постарались использовать этот текст чтобы сделать статус интуитивно понятным.

Данные звонка Amo по результату звонка определяются так:

| Результат звонка                                         | Доп условия                  | Статус amoCRM        | Текст                  |
| -------------------------------------------------------- | ---------------------------- | -------------------- | ---------------------- |
| 200 Успех                                                | Звонок входящий неотвеченный | 6 Не дозвонился      | Пропущенный звонок     |
| 200 Успех                                                |                              | 4 Разговор состоялся | Успешный звонок        |
| 404 Не найдено                                           |                              | 5 Неверный номер     | Номер не обслуживается |
| <p>408 Таймаут запроса</p><p>480 Временно недоступен</p> |                              | 3 Нет на месте       | Абонент не ответил     |
| 488 Невозможно принять                                   |                              | 5 Неверный номер     | Ошибка оператора связи |
| 484 Не полный адрес                                      |                              | 5 Неверный номер     | Некорректный номер     |
| 486 Абонент занят                                        | Звонок входящий неотвеченный | 6 Не дозвонился      | Номер занят            |
| 486 Абонент занят                                        |                              | 7 Номер занят        | Номер занят            |
| 603 Вызов отклонён                                       |                              | 2 Перезвонить позже  | Вызов отклонён         |
| 0 Неизвестно                                             | Отвеченный звонок            | 4 Разговор состоялся |                        |
| 0 Неизвестно                                             | Неотвеченный звонок          | 6 Не дозвонился      |                        |

## Настройка статуса звонка в кастомизации

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

Кастомизация делается в коде скрипта, файл [/opt/itgrix\_{crm}/customizer/actions/process\_final\_params.php](https://docs.itgrix.ru/custom_bx#id-5-process_final_params)\
\
Пример:

```php
$this->logDebug('params: '.json_encode($params));

if ($params['call_full']['channel']['was_answered'] == true)  {
   $params['STATUS_CODE'] = 200;
}

return array(
   'state' => 'success',
   'data'  => $params,
);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.itgrix.ru/faq/detalnye-statusy-zvonka.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
