Событие пропущенного веб-хука
[OnWebhookSkipped] Веб-хук по сущности, которую модуль обрабатывать не стал
Событие OnWebhookSkipped — пара к OnWebhookUpdate. Если OnWebhookUpdate срабатывает, когда элемент найден или создан, то OnWebhookSkipped срабатывает в противоположном случае: веб-хук пришёл, модуль его разобрал, но ничего делать не стал.
Так бывает, когда:
- элемента нет в каталоге Битрикс, а создавать его по веб-хуку настройки не разрешают;
- сущность архивная;
- сущность не проходит фильтр по доп. полю;
- сущность лежит вне групп товаров, выбранных в настройках импорта;
- объект сущности не удалось загрузить из МойСклад (сетевая ошибка, сущность уже удалена).
До появления этого события такой веб-хук не оставлял кастомному коду ни одного сигнала.
Событие информационное, возвращать ничего не нужно. Отменить или изменить поведение модуля через него нельзя — модуль и так ничего не делает.
Когда событие не вызывается
| Случай | Почему |
|---|---|
Действие DELETE | Удаление обрабатывается раньше, своим событием — OnBeforeDeleteItem |
Сущность specialpricediscount (скидки) | У скидок другой путь обработки, объект сущности там не создаётся |
Сущность productfolder | Группы товаров обрабатываются отдельной веткой |
| Веб-хук отсечён дедупликацией кеша или настройками до разбора | Модуль до этой точки не доходит |
| Модификации при включённой опции загрузки модификаций агентом | Веб-хук по variant пропускается раньше |
На магазине, где веб-хуки настроены на весь каталог МойСклад, а импортируется только одна группа товаров, событие будет приходить на каждый веб-хук вне этой группы. Держите обработчик лёгким — тяжёлая логика здесь заметно замедлит приём веб-хуков.
- Описание события
- Пример вызова события
- Примеры использования
Параметры события
| Параметр | Тип | Описание |
|---|---|---|
hook | object | Объект веб-хука от МойСклад целиком |
entity | string | Сущность: product, variant, bundle, service |
action | string | Действие веб-хука: CREATE или UPDATE |
ms_element | object | null | Сущность из МойСклад. null, если объект не удалось загрузить из API |
ms_element может быть null — именно в этом случае модуль и не смог ничего сделать. Проверяйте значение перед обращением к свойствам.
Возвращаемое значение
Ничего возвращать не нужно.
//Пример кода нужно вставить в файл init.php
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'rbs.moyskladstocks',
'OnWebhookSkipped',
'OnWebhookSkippedHandler'
);
function OnWebhookSkippedHandler(\Bitrix\Main\Event $event)
{
$eventParams = $event->getParameters();
// $hook — объект веб-хука МойСклад:
// $hook->action // 'CREATE' | 'UPDATE'
// $hook->meta->type // 'product' | 'variant' | 'bundle' | 'service'
// $hook->meta->href // 'https://api.moysklad.ru/api/remap/1.2/entity/product/...'
$hook = $eventParams['hook'];
$entity = $eventParams['entity']; // тип сущности МойСклад
$action = $eventParams['action']; // CREATE или UPDATE
// $msElement — сущность из МойСклад либо null, если объект не загрузился
// $msElement->name // 'Название товара'
// $msElement->externalCode // 'abc123externalcode'
// $msElement->archived // true
// $msElement->pathName // 'Каталог/Обувь'
$msElement = $eventParams['ms_element'];
if ($msElement === null) {
// объект из МойСклад загрузить не удалось
return;
}
#WORK_AREA#
}
Создание элемента своими силами
Модуль создавать элемент не стал, а кастомной логике он нужен.
function OnWebhookSkippedHandler(\Bitrix\Main\Event $event)
{
$eventParams = $event->getParameters();
$msElement = $eventParams['ms_element'];
if ($msElement === null || $eventParams['entity'] !== 'product') {
return;
}
// Архивные всё равно пропускаем
if (!empty($msElement->archived)) {
return;
}
// Создание элемента — на стороне разработчика
YourProductCreator::createFromMs($msElement);
}
Мониторинг: сколько веб-хуков уходит в никуда
function OnWebhookSkippedHandler(\Bitrix\Main\Event $event)
{
$eventParams = $event->getParameters();
$msElement = $eventParams['ms_element'];
YourAuditLogger::log([
'event' => 'webhook_skipped',
'entity' => $eventParams['entity'],
'action' => $eventParams['action'],
'href' => $eventParams['hook']->meta->href,
'reason' => $msElement === null ? 'ms_load_failed' : 'not_in_catalog',
'path_name' => $msElement->pathName ?? '',
'timestamp' => date('Y-m-d H:i:s'),
]);
}