Стенд MOEX CRM

диагностика интеграции CraftTalk ↔ CRM · собрано 2026-11-01T10:03:16Z UTC
всё в порядке0 диалогов · 0 запросов в CRM · 0 ошибок · 0 предупреждений
Очистить
0Запросов в журналепоказано последних 0
0Диалоговсгруппировано по dialogId
0Запросов в CRMCreateIncident / Assign / Close / Update
0Вызовов платформыusers / article / channels / mediator
0ОшибокHTTP, порядок событий, ответ CRM
0Предупрежденийподозрительные значения DTO

Замечания 0

Замечаний нет: порядок событий соблюдён, значения DTO выглядят ожидаемо, ответы CRM — 2xx с Ok=true.

Сценарии событие → маршрут

Событие выведено из маршрута CRM, который агент выбрал по слоту domain_event_type: сам слот на стенд не передаётся. Ноль в колонке «зафиксировано» означает, что событие за время работы стенда не приходило — это признак непокрытого сценария, а не ошибки стенда.

СобытиеЧто делает CRMЗапросЗафиксировано
DialogCreatedКарточка созданаCRM создала карточку инцидентаPOST /api/Incident/CreateIncident0
TaskRoutingFoundОператор назначенCRM привязала оператора к карточкеPOST /api/Incident/AssignIncident0
DialogDetachedОператор снятCRM отвязала оператора: агент кодирует снятие пустым логиномPOST /api/Incident/AssignIncident0
DialogFinishedКарточка закрытаCRM закрыла карточку, записала длительность, тематики и причину закрытияPOST /api/Incident/CloseIncident0
UserPhoneChangedКлиент обновлёнCRM обновила карточку клиентаPUT /api/Customer/UpdateCustomer0
UserFilledSlotsChangedКлиент обновлёнтот же маршрут, что и UserPhoneChanged — различить их стенд не можетPUT /api/Customer/UpdateCustomer0

Диалоги 0

Запросов пока нет. Страница начнёт собирать картину, как только агент стукнётся на этот адрес: проверьте адрес настройки Host в блоке «Что указать в настройках агента» ниже.

Таблица соответствий поле CRM ← источник

Стенд не видит исходного события, поэтому происхождение каждого поля описано явно. В колонке «последнее значение» — фактическое значение из последнего запроса по маршруту.

Карточка создана POST /api/Incident/CreateIncident

ПолеИсточник значенияПоследнее значение
dialogIdслот ep_DialogId; запасной — user.session_idзапросов по маршруту ещё не было
projectIdслот ep_CustomerId; запасной — user.customer_id / channel.customer_idзапросов по маршруту ещё не было
customerbuildCustomer(): слоты sys_* плюс каналы из /user-channels/getзапросов по маршруту ещё не было
customer.craftTalkIdслот sys_omniuserid; запасной — user.omni_user_idзапросов по маршруту ещё не было
customer.clientIdслот sys_extuseridзапросов по маршруту ещё не было
customer.firstNameслот sys_firstnameзапросов по маршруту ещё не было
customer.lastNameслот sys_lastnameзапросов по маршруту ещё не было
customer.middleNameслот sys_middlenameзапросов по маршруту ещё не было
customer.phoneNumberслот sys_phoneзапросов по маршруту ещё не было
customer.emailслот sys_emailзапросов по маршруту ещё не было
customer.channelsInfochannel.channel_id текущего канала плюс /user-channels/get по sys_omniuseridзапросов по маршруту ещё не было
customer.channelsInfo[].currentChannelпроставляется агентом по совпадению channel_idзапросов по маршруту ещё не было
createdDatenowFormatted(): UTC + datetime_offset_minutes, формат datetime_formatзапросов по маршруту ещё не было
operatorCraftTalkLoginсырой ep_OperatorId и только если ep_InitByOperator=true, иначе пусто; CRM различает «инициировал» и «работал»запросов по маршруту ещё не было

Оператор назначен POST /api/Incident/AssignIncident

ПолеИсточник значенияПоследнее значение
dialogIdслот ep_DialogId; запасной — user.session_idзапросов по маршруту ещё не было
projectIdслот ep_CustomerId; запасной — user.customer_id / channel.customer_idзапросов по маршруту ещё не было
operatorCraftTalkLoginep_OperatorId → /api/external/users/get → слот operator_login; пустая строка = снятие с операторазапросов по маршруту ещё не было

Карточка закрыта POST /api/Incident/CloseIncident

ПолеИсточник значенияПоследнее значение
dialogIdслот ep_DialogId; запасной — user.session_idзапросов по маршруту ещё не было
projectIdслот ep_CustomerId; запасной — user.customer_id / channel.customer_idзапросов по маршруту ещё не было
customerbuildCustomer(): слоты sys_* плюс каналы из /user-channels/getзапросов по маршруту ещё не было
customer.craftTalkIdслот sys_omniuserid; запасной — user.omni_user_idзапросов по маршруту ещё не было
customer.clientIdслот sys_extuseridзапросов по маршруту ещё не было
customer.firstNameслот sys_firstnameзапросов по маршруту ещё не было
customer.lastNameслот sys_lastnameзапросов по маршруту ещё не было
customer.middleNameслот sys_middlenameзапросов по маршруту ещё не было
customer.phoneNumberслот sys_phoneзапросов по маршруту ещё не было
customer.emailслот sys_emailзапросов по маршруту ещё не было
customer.channelsInfochannel.channel_id текущего канала плюс /user-channels/get по sys_omniuseridзапросов по маршруту ещё не было
customer.channelsInfo[].currentChannelпроставляется агентом по совпадению channel_idзапросов по маршруту ещё не было
closedDatenowFormatted(): UTC + datetime_offset_minutesзапросов по маршруту ещё не было
closedByCodeслот ep_Reason (operator-finished / timeout), запасной DialogFinishReason=timeout, иначе Botзапросов по маршруту ещё не было
operatorCraftTalkLogin/api/external/users/get по ep_OperatorId либо по последнему оператору из истории диалога; null если закрыл ботзапросов по маршруту ещё не было
durationInMinsистория диалога /webhooks/mediator/messages: последняя минус первая запись, округление полу-чётноезапросов по маршруту ещё не было
customerMoodCodeконстанта агента 1 — реальная оценка в CRM не передаётсязапросов по маршруту ещё не было
additionalPhoneNumberконстанта агента "" — не заполняетсязапросов по маршруту ещё не было
additionalEmailконстанта агента "" — не заполняетсязапросов по маршруту ещё не было
classifierLevel1Idслот ep_ClassifierLevel1Id; агент сверяет с кодами статей Базы Знаний по classifier_tagsзапросов по маршруту ещё не было
classifierLevel2Idслот ep_ClassifierLevel2Id, та же сверказапросов по маршруту ещё не было
classifierLevel3Idслот ep_ClassifierLevel3Id, та же сверказапросов по маршруту ещё не было
extensionDataвсегда {} — в этой версии не наполняетсязапросов по маршруту ещё не было

Клиент обновлён PUT /api/Customer/UpdateCustomer

ПолеИсточник значенияПоследнее значение
craftTalkIdслот sys_omniuserid; запасной — user.omni_user_idзапросов по маршруту ещё не было
clientIdслот sys_extuseridзапросов по маршруту ещё не было
firstNameслот sys_firstnameзапросов по маршруту ещё не было
lastNameслот sys_lastnameзапросов по маршруту ещё не было
middleNameслот sys_middlenameзапросов по маршруту ещё не было
phoneNumberслот sys_phoneзапросов по маршруту ещё не было
emailслот sys_emailзапросов по маршруту ещё не было
channelsInfochannel.channel_id текущего канала плюс /user-channels/get по sys_omniuseridзапросов по маршруту ещё не было
channelsInfo[].currentChannelпроставляется агентом по совпадению channel_idзапросов по маршруту ещё не было

Все запросы 0

Свежие сверху. Свои служебные вызовы стенд в журнал не пишет — иначе каждое обновление страницы засоряло бы данные, ради которых она открыта. Журнал без отрисовки: JSON, состояние стенда: health.

ВремяСлойСобытиеМетодПутьТелоОтвет

Чего стенд не видит

Агент отправляет стенду только собранный DTO. Перечисленное ниже в журнале не остаётся и восстанавливается по косвенным признакам — поэтому такие строки в колонке ① подписаны отдельно.

Окружение и настройки

Что указать в настройках агента

Hosthttps://jsairu.ru/api
url_hosthttps://jsairu.ru
channels_urlhttps://jsairu.ru
bm_urlhttps://jsairu.ru
Маршрутизацияmod_rewrite работает — адреса выше верны, все маршруты доступны.

Это шаблон из config.php стенда, а не фактические настройки агента: свои значения агент присылает только собранным DTO, поэтому таймаут, формат даты и теги тематик здесь не видны. Адреса выбраны по состоянию mod_rewrite этого сайта — если агент настроен иначе, оба варианта работают, а в журнале видно, каким он реально пользуется.

Файлы стенда

index.phpна месте
ui.phpна месте
ui.jsна месте
config.phpна месте
logs/на месте
Журнал/var/www/jsairuru/data/www/jsairu.ru/logs/requests.jsonl · 0 Б · записей 0 · подрезка после 2 МБ до 500 записей
СерверPHP 8.2.35 · DOCUMENT_ROOT /var/www/jsairuru/data/www/jsairu.ru · SCRIPT_FILENAME /var/www/jsairuru/data/www/jsairu.ru/index.php · REQUEST_URI /

Что стенд отдаёт агенту

ui{ "page_size": 500, "max_bytes": 2097152, "max_records": 500, "attach_window_ms": 120000, "merge_window_ms": 3600000, "slow_request_ms": 2000, "event_gap_ms": 60000 }
crm{ "incident_id": "INC-000042", "incident_number": "000042" }
operator{ "id": "5a2b", "login": "smirnov" }
classifier_codes[ "auth", "login", "payment", "tariff" ]
user_channels[ { "channel_id": "webchat_konstantin_novikov", "channel_user_id": "00d43e30-9116-46ce-8f71-dd1d3dce5784" }, { "channel_id": "tg_ivan", "channel_user_id": "4411992" } ]
dialog_history_minutes35

Стенд открыт и ничего не маскирует: значения настроек, заголовок Authorization и тела запросов видны в открытом виде. Журнал закрыт правилом RewriteRule ^logs/ - [F,L], но сам стенд доступен из интернета — боевые токены через него передавать не стоит.