2015-07-04 4 views
4

Я пытаюсь загрузить изображения с помощью TelegramBot API, используя следующий кодTelgram Bot Bad Gateway

if(file_exists($_FILES['fileToUpload']['tmp_name'])){ 
     $new = fopen($_FILES['fileToUpload']['tmp_name'], "rb"); 
     $contents = fread($new, $_FILES['fileToUpload']['size']); 
     fclose($new); 
     $client = new Client(); 
     $response = $client->post("https://api.telegram.org/botMyApiKey/sendPhoto", [ 
      'body' => ['chat_id' => '11111111', 'photo' => $contents] 
     ]); 
     var_dump($response); 
}else{ 
     echo("No File"); 
} 

я получаю Nginx 502 Bad Gateway. Использую ли я правильный метод? У меня нет проблем с получением getMe с использованием API.

P.S Я использую Guzzle 5.3.0 для совместимости с php.

ответ

1

Попробуйте сделать это как многостраничный пост.

$client->post(
    'https://api.telegram.org/botMyApiKey/sendPhoto', 
    array(
     'multipart' => array(
      array(
       'name'  => 'chat_id', 
       'contents' => '1111111' 
      ), 
      array(
       'name'  => 'photo', 
       'contents' => $contents 
      ) 
     ) 
    ) 
); 

Guzzle documentation reference

Для жрать 5.3

use GuzzleHttp\Client; 

$client = new Client(['defaults' => [ 
    'verify' => false 
]]); 

$response = $client->post('https://api.telegram.org/bot[token]/sendPhoto', [ 
    'body' => [ 
     'chat_id' => 'xxxxx', 
     'photo' => fopen(__DIR__ . '/test.jpg', 'r') 
    ] 
]); 

var_dump($response); 

Примечание: вы должны передать дескриптор файла на 'фото' атрибут, а не содержимое файла.

+0

Я использую Guzzle 5.3. Опция Multipart доступна только в последней версии. Я использую старую версию для использования php. –

+0

http://guzzle3.readthedocs.org/http-client/request.html См. Раздел «Запросы POST». API Telegram требует, чтобы вы загружали фотографии в multipart/form-data – Pete

+0

Посмотрите, как вы редактируете, вы должны передать дескриптор файла, а не содержимое файла. –

0

От Guzzle 3 documentation:

запросы POST в жрать посылаются с заголовком Content-Type application/x-www-form-urlencoded, если POST поля присутствуют, но файлы не отправляются в POST. Если файлы , указанные в запросе POST, то заголовок Content-Type будет станет multipart/form-data.

Метод post() объекта-клиента принимает четыре аргумента: URL, необязательные заголовки, столбцы и массив параметров запроса. К отправьте файлы в запрос POST, добавьте символ @ в значение массива (так же, как если бы вы использовали функцию curl_setopt PHP ). Пример:

$request = $client->post('http://httpbin.org/post', array(), array(
    'custom_field' => 'my custom value', 
    'file_field' => '@/path/to/file.xml' 
)); 

Так что для API Телеграмма это стало бы:

$request = $client->post('https://api.telegram.org/botMyApiKey/sendPhoto', array(), array(
    'chat_id' => 'xxxx', 
    'photo' => '@/path/to/photo.jpg' 
)); 
+0

Теперь это приводит к *** [код статуса] 400 [причина фразы] Плохой запрос ***. Понятия не имею почему. –

+0

См. Мое решение. –

1

я, наконец, нашел решение. Вставка моего решения для других.

move_uploaded_file($_FILES['photo']['tmp_name'], __DIR__."/temp/".$_FILES['photo']['name']); //Important for Form Upload 
$client = new Client(); 
$request = $client->createRequest('POST', 'https://api.telegram.org/botMyApiKey/sendPhoto'); 
$postBody = $request->getBody(); 
$postBody->setField('chat_id', '11111111'); 
$postBody->addFile(new PostFile('photo', fopen(__DIR__."/temp/".$_FILES['photo']['name'], "r"))); 
try{ 
    $response = $client->send($request); 
    var_dump($response); 
}catch(\Exception $e){ 
    echo('<br><strong>'.$e->getMessage().'</strong>'); 
} 

Я озадачен тем, почему это работает с этим видом подхода Гузл, а не с другим. Я подозреваю, что Guzzle не установил правильный тип заголовка с первым подходом.