Вебхуки и вызовы REST - настройка, права, разбор ошибок
Настраиваем вебхуки в обе стороны, зовём методы REST из кода и разбираем отказы по правам.
Решение
Зовём метод входящим вебхуком:
use Bitrix\Main\Web\HttpClient;
$http = new HttpClient(['socketTimeout' => 10, 'streamTimeout' => 10]);$body = $http->post('https://portal.example.com/rest/1/КЛЮЧ/crm.lead.add.json', [ 'fields' => ['TITLE' => 'Заявка с сайта', 'NAME' => 'Иван'],]);$answer = json_decode($body, true);Адрес вебхука содержит идентификатор пользователя и ключ. Оба значения секретны: попавший в репозиторий адрес равносилен выданному паролю от учётной записи.
Разбираем ответ, а не только код состояния:
if (isset($answer['error'])) { // текст ошибки приходит в теле ответа, а не в заголовках printf("отказ %s: %s\n", $answer['error'], $answer['error_description']);} else { printf("создано: %s\n", $answer['result']);}Отказ по правам приходит обычным ответом с описанием в теле. Проверка только кода состояния прячет причину: сервер отвечает штатно, а операция не выполнена.
Отправляем событие своим кодом:
$http = new HttpClient();$http->post($receiverUrl, [ 'event' => 'ONCRMDEALUPDATE', 'data' => ['FIELDS' => ['ID' => $dealId]], 'ts' => time(),]);// приёмник обязан ответить быстро: платформа не ждёт долгих обработчиковИсходящий вебхук зовёт чужой адрес при наступлении события. Долгий ответ приёмника платформа считает неудачей, поэтому тяжёлую работу на его стороне уводят в очередь, а вызову отвечают сразу.
Проверяем, что вебхук вообще жив:
# самый безопасный метод для проверки: возвращает данные владельца ключаcurl -s "https://portal.example.com/rest/1/КЛЮЧ/profile.json" | head -20# ключ вебхука равен паролю: в репозиторий его не кладут ни при каких условияхОтвет с данными пользователя подтверждает и адрес, и ключ, и права на минимальную область. Отказ на этом вызове означает, что разбирать конкретный метод рано.
Массовые операции делают пакетным вызовом. Он выполняет до полусотни команд одним обращением, отвечает результатом каждой из них и не упирается в предел частоты обращений. Цикл одиночных вызовов на нескольких тысячах записей упрётся в этот предел и начнёт получать отказы вместо ответов.
Ключ вебхука хранят там же, где пароли от платёжных систем. Попавший в репозиторий адрес открывает доступ ко всем выданным областям, и отозвать его можно только удалением вебхука целиком.
Права вебхука не бывают шире прав его владельца. Ключ, созданный менеджером, не увидит чужие сделки, даже если ему выдана вся область CRM. Поэтому для интеграций заводят отдельную учётную запись с нужными правами, а не пользуются ключом живого сотрудника.
Типичные проблемы
Метод возвращает отказ по правам.
Нужная область не выдана вебхуку либо её нет у пользователя-владельца. Права ключа ограничены правами человека, создавшего его.
Ответ приходит успешным, но ничего не создалось.
Проверяется только код состояния. Текст ошибки лежит в теле ответа, и без его разбора отказ выглядит как успех.
Вебхук перестал работать без изменений в коде.
Учётная запись владельца отключена или у неё изменились права. Ключ живёт ровно столько, сколько его владелец.
Исходящий вебхук доходит не всегда.
Приёмник отвечает дольше отведённого времени. Платформа считает такой вызов неудачным, повторяет ограниченное число раз и прекращает попытки.
Одно событие приходит несколько раз.
Повторы после неудачных попыток - штатное поведение. Приёмник должен распознавать дубли по идентификатору события.
Частые вопросы
Сколько вызовов в секунду выдержит портал?
Есть предел частоты обращений, и при его превышении методы начинают отвечать отказом. Массовые операции делают пакетным методом, а не циклом одиночных вызовов.
Как передать файл через REST?
Содержимым в кодировке base64 в поле метода. Прямой загрузки файла обычной формой у большинства методов нет.
Можно ли ограничить вебхук по адресу источника?
Штатной привязки к адресу нет: ключа достаточно для вызова. Ограничение делают на уровне веб-сервера, закрывая путь REST для чужих адресов.
Чем пакетный метод лучше цикла вызовов?
Он выполняет до полусотни команд одним обращением и не упирается в предел частоты. Результат каждой команды приходит отдельным элементом ответа.
Смежное
- REST и вебхуки - оглавление подтемы
- Приём вебхука от внешнего сервиса: точка входа, подпись, повторы - приём уведомлений от чужого сервиса
- Токен доступа с подписью: выпуск, проверка, срок жизни - токен для своего API
- Обмен с 1С и HTTP - устройство интеграций целиком
- Заказы сайта в Битрикс24: вебхук, сопоставление, дубли - типовая задача на вебхуках портала
- Мгновенные сообщения и push - другой способ доставки событий
- Пользователи, группы и права доступа - чьими правами работает вебхук
- Вызов внешнего сервиса из кода: таймауты, повторы, журнал - исходящие вызовы из кода сайта
- Своё API для приложения: контроллер, токен, версии - когда штатного REST не хватает
- Свои действия по REST: включение, ограничение, контекст - как отдать наружу действия своего модуля