Заметки
REST 3.0: JSON правильный, а заголовок cURL не отправился
При разборе InvalidJsonException легко зациклиться на содержимом JSON. Но ошибка бывает раньше: строка подготовлена правильно, а HTTP-запрос собран неверно.
Например, эта запись синтаксически похожа на настройку cURL, но не связывает опцию с её значением:
CURLOPT_HTTPHEADER, ['Content-Type: application/json'], В массиве появляются два элемента с числовыми ключами. Нужна пара CURLOPT_HTTPHEADER => [...]. Некорректный массив опций может быть отклонён самим PHP/cURL ещё до отправки запроса.
Запрос к REST 3.0
Фрагмент для PHP 7.3+ с расширением cURL. Переменная $s_url содержит полный URL вебхука к tasks.task.chat.message.send, а $i_task_id — целочисленный ID задачи. В URL этого метода нужен путь /rest/api/.
$ar_payload = ['fields' => ['taskId' => $i_task_id, 'text' => 'Документ подготовлен']];
$s_json = json_encode($ar_payload, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
$curl_handle = curl_init($s_url);
curl_setopt_array($curl_handle, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Accept: application/json'],
CURLOPT_POSTFIELDS => $s_json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($curl_handle);
if ($response === false) {
$s_error = curl_error($curl_handle);
curl_close($curl_handle);
throw new RuntimeException($s_error);
}
$i_status = (int) curl_getinfo($curl_handle, CURLINFO_HTTP_CODE);
curl_close($curl_handle);
echo 'HTTP: ' . $i_status . PHP_EOL;
echo $response; Здесь отдельно видны ошибка транспорта, HTTP-статус и тело ответа. JSON кодируется один раз, в CURLOPT_POSTFIELDS передаётся строка. Передача PHP-массива включила бы другой формат тела запроса.
REST 3.0 ожидает JSON с Content-Type: application/json. Вызов из адресной строки браузера не воспроизводит такой POST-запрос.
Документация: REST 3.0; curl_setopt_array.