Перейти к основному содержимому

Событие веб-хука по своей сущности

[OnWebhookUnknownEntity] Веб-хук по сущности, которую модуль не обслуживает

Доступно с версии 3.9.0

На более ранних версиях событие не вызывается вовсе. Подписка на него безвредна: обработчик просто никогда не будет позван.

Модуль сам умеет раскладывать по каталогу Битрикс шесть типов сущностей МойСклад: product, variant, bundle, service, productfolder и specialpricediscount. Веб-хук по любому другому типу — например по партии (consignment), контрагенту (counterparty) или заказу покупателя (customerorder) — модуль обработать не может и не пытается.

Раньше такой веб-хук отбрасывался молча: модуль отвечал МойСклад 200 OK, и событие пропадало. При этом подписку на такую сущность вполне можно было зарегистрировать своим кодом через OnBeforeWebHookOptionsBuild — веб-хуки создавались, приходили и терялись.

Теперь модуль отдаёт такой веб-хук вашему коду событием OnWebhookUnknownEntity и на этом свою часть работы заканчивает.

За объектом в МойСклад ходите сами

У события нет параметра ms_element — в отличие от OnWebhookUpdate и OnWebhookSkipped. Модуль не знает, как устроена ваша сущность, и в API за ней не обращается. Вам приходит href; запрос по нему — на вашей стороне.

Что модуль гарантирует к моменту вызова

Событие бросается не на сыром теле запроса. К этой точке модуль уже:

  • проверил соль в адресе веб-хука (webhook_url_salt) сравнением за постоянное время;
  • убедился, что обмен включён, и выбрал профиль обмена по profile_id;
  • нормализовал домен в meta->href;
  • проверил href на принадлежность эндпоинту МойСклад — чужой адрес в теле веб-хука до обработчика не доходит;
  • убедился, что действие входит в CREATE, UPDATE, DELETE;
  • отсёк повтор того же события в пределах времени дедупликации (cache_webhook_time, по умолчанию 5 секунд).
Отсекайте свою сущность первой строкой

Событие приходит по любому типу вне шести штатных, а не только по вашему. Сюда же попадает всё, что не совпало со списком обслуживаемых типов посимвольно: сравнение строгое, поэтому PRODUCT в другом регистре или product с лишним пробелом — для модуля тоже «чужая сущность». Поломки в этом нет, раньше такие веб-хуки точно так же молча отбрасывались, но обработчик, который не проверил entity строгим сравнением, может принять их за свои.

if ($eventParams['entity'] !== 'consignment') {
return;
}

Когда событие не вызывается

СлучайПочему
Сущность из шести штатныхОна идёт своим маршрутом, событиями OnWebhookUpdate, OnWebhookSkipped и OnBeforeDeleteItem
Действие вне CREATE / UPDATE / DELETEМодуль отбрасывает такой веб-хук раньше развилки по типу
href не принадлежит API МойСкладОтсекается защитой от подстановки чужого адреса
Повтор того же события в пределах cache_webhook_timeДедупликация: второй раз событие не бросается
Событие не попало в первые webhook_limit_count событий запросаМодуль обрабатывает только начало пачки. Настройка «Количество событий за раз» на вкладке «Веб-хуки»
Обмен выключен или соль не совпалаПриём обрывается до разбора тела
Свой try/catch обязателен

Исключение из вашего обработчика модуль глушит молча — чтобы одна упавшая сущность не оборвала остальные события пачки. Ни в лог модуля, ни в ответ оно не попадёт. Если вам нужно знать о своих ошибках, ловите их сами и пишите в свой лог.

Результат обработчика не читается

Отменять модулю на чужой сущности нечего: он с ней и так ничего не делает. EventResult возвращать бессмысленно.

Параметры события

ПараметрТипОписание
hookobjectОбъект веб-хука от МойСклад целиком, с уже нормализованным meta->href
entitystringТип сущности МойСклад, например consignment, counterparty, customerorder
actionstringДействие веб-хука: CREATE, UPDATE или DELETE
hrefstringСсылка на сущность в API МойСклад — то же, что hook->meta->href, строкой

Возвращаемое значение

Ничего возвращать не нужно — результат не читается.

Обновление на 3.9.0: что делать владельцу существующей доработки

Короткий ответ — ничего. Событие только добавляет то, чего раньше не было; ни одно существующее событие модуля не изменило ни состава параметров, ни момента срабатывания.

Как устроена ваша доработкаЧто делать при обновлении
Обработчики OnWebhookUpdate, OnWebhookSkipped, OnBeforeDeleteItem, OnBeforeWebHookOptionsBuild и события импортаНичего. Они работают по шести штатным сущностям, и их маршрут не изменился
Собственный приёмник веб-хуков на своём адресе, мимо модуляНичего. Модуль в этой цепочке не участвует
Свои сущности ловились «как-нибудь ещё» и не ловилисьПоявилась штатная дверь — OnWebhookUnknownEntity. Переходить не обязательно, но теперь это единственный поддерживаемый путь
В коде модуля правился список обслуживаемых типовПравка будет затёрта обновлением. Перенесите логику на OnWebhookUnknownEntity: она переживёт все следующие обновления
Отдельно — обновление с версий ниже 3.8.0

В версиях до 3.8.0 веб-хук с действием DELETE по любому типу сущности шёл в штатное удаление: модуль искал в каталоге элемент, у которого XML_ID совпадает с идентификатором из href, и удалял или деактивировал его. Это работало и для сущностей, которые модуль не обслуживает, — и было закрыто в 3.8.0 как уязвимость: тело веб-хука недоверенное, а совпадение идентификатора ничего не подтверждает.

Если ваша доработка опиралась на этот побочный эффект, после обновления он не вернётся — ни в 3.8.0, ни в 3.9.0. Снимать элементы каталога по своей сущности теперь нужно самостоятельно, из обработчика OnWebhookUnknownEntity с действием DELETE.