Решение ошибки "Bad Request: there is no document in the request" при отправке файла в Telegram API
При отправке документа через Telegram Bot API возникает следующая ситуация: код корректно работает на хостинге, но при запуске через OpenServer возвращается ошибка:
Array(
[ok] =>
[error_code] => 400
[description] => Bad Request: there is no document in the request
)Используется следующий PHP-код:
$FILE = $_SERVER['DOCUMENT_ROOT'].'/img.jpg';
$ch = curl_init();
curl_setopt_array($ch,array(
CURLOPT_URL =>'https://api.telegram.org/bot'.$TOKEN.'/sendDocument',
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_TIMEOUT => 10,
CURLOPT_POSTFIELDS => json_encode(array(
'chat_id' => $CHAT_ID,
'document' => new \CURLFile($FILE)
)),
));
echo curl_exec($ch);
curl_close($ch);Причина ошибки
Проблема заключается в некорректной передаче данных в параметре CURLOPT_POSTFIELDS. При использовании json_encode() для массива, содержащего объект CURLFile, сериализация происходит неправильно, особенно в среде OpenServer.
Решение
Для корректной отправки файла через cURL необходимо передавать данные в формате массива без преобразования в JSON. Telegram API ожидает данные в формате multipart/form-data, который cURL формирует автоматически при передаче массива или строки с постфиксом @.
Замените строку с CURLOPT_POSTFIELDS на следующую:
CURLOPT_POSTFIELDS => array(
'chat_id' => $CHAT_ID,
'document' => new \CURLFile($FILE)
),Уберите вызов json_encode(). cURL самостоятельно установит правильный заголовок Content-Type: multipart/form-data и корректно обработает файл.
Исправленный код
$FILE = $_SERVER['DOCUMENT_ROOT'].'/img.jpg';
$ch = curl_init();
curl_setopt_array($ch,array(
CURLOPT_URL =>'https://api.telegram.org/bot'.$TOKEN.'/sendDocument',
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_TIMEOUT => 10,
CURLOPT_POSTFIELDS => array(
'chat_id' => $CHAT_ID,
'document' => new \CURLFile($FILE)
),
));
echo curl_exec($ch);
curl_close($ch);После этого изменения код будет стабильно работать как на хостинге, так и в локальном окружении OpenServer.