How to properly configure Guzzle to download zip files from other servers - php

This function is meant to download .zip files
function download($url, $debug = false)
{
$client = new Client([
'connect_timeout' => 10,
'timeout' => 60.0,
'debug' => $debug
]);
$response = $client->request('GET', $url);
try {
if ($response->getStatusCode() == 200) {
return $response->getBody()->getContents();
}
} catch (RequestException $e) {
//var_dump($response->getBody()->getContents());
$txt = json_encode(['log_error' => $e->getResponse(), 'response' => $response->getBody()->getContents(), 'url' => $url]);
file_put_contents(storage_path() . '/logs-etiquetas/log-' . microtime(true) . '-' . auth()->user()->company_id . '.txt', $txt);
}
return false;
}
I'm getting error below
production_ERROR: Client error: GET https: //api.mercadolibre.com/shipment_labels? shipment_ids = 27868452659,27864682043,27168438675,27868264704,27868866716,27868738288,27867965828 & response_type = zpl2 & caller.id = 23264143 & access_token = 400 Bad Request response:
bad_request

Related

missing_charset for slack-api

I use Guzzle to send messages to the Slack API. It's all working fine except for the warning missing-charset. Here is my Guzzle function:
private function guzzleClient(string $method, string $url, array $parameters = [])
{
$client = new Client(['headers' => [
'Authorization' => "Bearer " . $this->slackOauthToken,
'Content-Type' => 'application/json; charset=utf-8',
]]);
switch (strtoupper($method)) {
case "POST":
$response = $client->post($url, [RequestOptions::JSON => $parameters]);
break;
case "GET":
$response = $client->get($url, ["query" => $parameters]);
break;
}
$json = json_decode($response->getBody()->getContents());
if((is_object($json)) && ($json->ok == false)) {
return "Error: " . $json->error . "\n";
} else {
return $json;
}
}
As far as I can determine, the charset is there and in the headers. But I keep still getting the missing-chaset error - where am I going wrong?

Trying to download mp3 file via API GET response using guzzle client in laravel

I've tried several methods to download an mp3 file via API get request. I feel like as if I'm close but just can't seem to get the download.
My URL returns a binary mp3 file.
This is a portion of what I'm getting in my response header array returning with the get request. Hope this is helpful.
"Content-Disposition" => array:1 [
0 => "attachment; filename=RE3e327a2615b93f528fee111da9b60e17.mp3; filename*=UTF-8''sample.mp3"
]
Here is a sample of my code using the Guzzle client in Laravel. Trying Laravel's download method but I believe I need to get the actual file from the Content-Disposition. Much appreciated for any help. Thanks.
$client = new Client();
try {
$url = 'http://getmp3website.net/recording/sample.mp3';
$response = $client->request('GET', $url,
[
'headers' => [
'Authorization' => 'bearer ' . env("AUTH_TOKEN"),
'Content-Type' => 'audio/mp3',
],
]);
return response()->download($response);
} catch (Exception $ex) {
return $ex;
}
#Note: this is not a tested answer, I have just provided an example to follow the comments above
<?php
$client = new Client();
try {
$url = 'http://getmp3website.net/recording/sample.mp3';
$resource = \GuzzleHttp\Psr7\Utils::tryFopen('/path/to/file', 'w');
//or you can use $myFile = fopen('/path/to/file', 'w') or die('not working');
$stream = \GuzzleHttp\Psr7\Utils::streamFor($resource);
$client->request('GET', $url , [
'save_to' => $stream,
'headers' => [
'Authorization' => 'bearer ' . env("AUTH_TOKEN"),
'Content-Type' => 'audio/mp3',
],
]
);
/**
* // As `save_to` is deprecated(guzzle wants us to download files as stream I guess), you can use sink as well, sink will automatically stream files for you
$resource = \GuzzleHttp\Psr7\Utils::tryFopen('/path/to/file', 'w');
$client->request('GET', $url, ['sink' => $resource]);
*/
return response()->download($pathsavedfile);
} catch(\GuzzleHttp\Exception\RequestException $e){
// you can catch here 400 response errors and 500 response errors
// You can either use logs here
$error['error'] = $e->getMessage();
$error['request'] = $e->getRequest();
if($e->hasResponse()){
if ($e->getResponse()->getStatusCode() == '400'){
$error['response'] = $e->getResponse();
}
}
Log::info('Error occurred in request.', ['error' => $error]);
}catch (Exception $ex) {
return $ex;
}

Video uploaded through YouTube Data API is becoming private

I have tried uploading a video to YouTube channels using by the YouTube Data API, by composer:
"require": {
"google/apiclient": "^2.7",
"hybridauth/hybridauth": "~3.4.0",
"guzzlehttp/guzzle": "^7.0"
}
The video is uploaded successfully, but YouTube marks every video uploaded into it as private. Does anybody know how to fix this scenario?
public function upload_video_on_youtube($id, $arr_data)
{
$result_data = array();
$channel_id = $id;
$uploaded = false;
$stopper = 0;
while ($uploaded == false && $stopper == 0) {
$arr_data['summary'] = $this->getrandomstring(10);
$arr_data['title'] = $this->getrandomstring(10);
$client = new Google_Client();
$arr_token = $this->getAccessToken($channel_id);
if ($arr_token['error'] == false) {
$res = array();
$accessToken = array(
'access_token' => $arr_token['access_token']
);
$client->setAccessToken($accessToken);
$service = new Google_Service_YouTube($client);
$video = new Google_Service_YouTube_Video();
$videoSnippet = new Google_Service_YouTube_VideoSnippet();
$videoSnippet->setDescription($arr_data['summary']);
$videoSnippet->setTitle($arr_data['title']);
$video->setSnippet($videoSnippet);
$videoStatus = new Google_Service_YouTube_VideoStatus();
$videoStatus->setPrivacyStatus('unlisted');
$video->setStatus($videoStatus);
try {
$response = $service->videos->insert(
'snippet,status',
$video,
array(
'data' => file_get_contents($arr_data['video_path']),
'mimeType' => 'video/*',
'uploadType' => 'multipart'
)
);
if (isset($response->id)) {
$video_id = $response->id;
$res['error'] = false;
$res['response'] = $video_id;
array_push($result_data, $res);
$uploaded = true;
return $result_data;
}
} catch (Exception $e) {
if (401 == $e->getCode()) {
// echo ($arr_token['email'] . " Youtube Access token expired");
$refresh_token = $this->get_refersh_token($channel_id);
$client = new GuzzleHttp\Client(['base_uri' => 'https://accounts.google.com']);
$response = $client->request('POST', '/o/oauth2/token', [
'form_params' => [
"grant_type" => "refresh_token",
"refresh_token" => $refresh_token,
"client_id" => $arr_token['client_id'],
"client_secret" => $arr_token['client_secret'],
],
]);
$data = json_decode($response->getBody());
$data->refresh_token = $refresh_token;
$this->update_access_token($channel_id, json_encode($data));
$uploaded = false;
} elseif (403 == $e->getCode()) {
// echo ($arr_token['email'] . ' Youtube channel quota exceeded');
$channel_id = $channel_id + 1;
$uploaded = false;
}
}
} else if ($arr_token['error'] == true) {
$res['error'] = true;
$res['response'] = "Your Daily Upload Quota is Exceeded";
array_push($result_data, $res);
$stopper = 1;
return $result_data;
}
}
}
If you check the documentation for videos.insert you will see that all videos that are uploaded by apps that have not gone through the verification process will be set to private.
Once you go through the verification process you will be able to set your videos to public
This is an update after some clarity from Google.
At the top of the Video.insert page you will see it states.
Apps that dont need to be verified can just go though an audit is not verification, these are two different things. You need to apply for an audit. YouTube API Services - Audit and Quota Extension Form

PHP Uploading Zero Bytes To S3

I am trying to upload mp3 files to Amazon S3 but for some reason anything I upload is uploaded with a byte length of zero. I cannot seem to figure out why this is happening. I've tried following a tutorial and adjusting the code myself. Any help is appreciated.
<?php
error_reporting(0);
require '../../../../includes/aws-sdk-php/vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
if (isset($_GET['test'])){
if($_GET['test'] == "true"){
include("../../depend.php");
include("../../../../includes/okta-jwt/okta-jwt-functions.php");
include("../../../../includes/aws-s3/functions.php");
$jwtToken = $_GET['token'];
$validateJWT = validateJWT($jwtToken);
echo "$validateJWT";
die();
}
}
include("../../depend.php");
include("../../../../includes/okta-jwt/okta-jwt-functions.php");
if(isset($_POST['episodeTitle'])){
$episodeTitle = $_POST['episodeTitle'];
}
if(isset($_POST['episodeDescription'])){
$episodeDescription = $_POST['episodeDescription'];
}
if(isset($_POST['explicitContent'])){
$explicitContent = $_POST['explicitContent'];
}
if(isset($_POST['episodeShowID'])){
$episodeShowID = $_POST['episodeShowID'];
}
if(isset($_POST['jwtToken'])){
$jwtToken = $_POST['jwtToken'];
}
if(isset($_POST['audioFile'])){
$episodeAudio = $_POST['audioFile'];
}
$validateJWT = validateJWT($jwtToken);
$payloadJSON = json_decode($validateJWT);
$payloadDecoded = $payloadJSON;
$payloadUserID = $payloadDecoded->userID;
//Check if JWT Token Is Valid
if($payloadUserID != 0){
$payloadUserOrgID = $payloadDecoded->userOrgID;
$payloadRole = $payloadDecoded->role;
$payloadExp = $payloadDecoded->exp;
$payloadState = $payloadDecoded->state;
$payloadFirstName = $payloadDecoded->firstName;
$payloadLastName = $payloadDecoded->lastName;
$payloadFullName = $payloadDecoded->fullName;
$episodeStateCode = bin2hex(random_bytes(25));
date_default_timezone_set('UTC');
$showUtcTimestamp = date("Y-m-d H:i:s");
// AWS Info
$bucketName = 'XXX';
$IAM_KEY = 'XXX';
$IAM_SECRET = 'XXX';
// Connect to AWS
try {
// You may need to change the region. It will say in the URL when the bucket is open
// and on creation.
$s3 = S3Client::factory(
array(
'credentials' => array(
'key' => $IAM_KEY,
'secret' => $IAM_SECRET
),
'version' => 'latest',
'region' => 'us-east-2'
)
);
} catch (Exception $e) {
// We use a die, so if this fails. It stops here. Typically this is a REST call so this would
// return a json object.
die("Error: " . $e->getMessage());
}
// $keyName = "test_example/" . basename($_FILES["audioFile"]['name']);
// $keyName = "org-$payloadUserOrgID/$episodeStateCode-" . basename($_FILES["audioFile"]['name']);
$keyName = "org-$payloadUserOrgID/$episodeStateCode.mp3";
$pathInS3 = 'https://s3.us-east-2.amazonaws.com/' . $bucketName . '/' . $keyName;
// Add it to S3
try {
// Uploaded:
$file = $_FILES["audioFile"]['tmp_file'];
$s3->putObject(
array(
'Bucket'=>$bucketName,
'Key' => $keyName,
'SourceFile' => $file,
'StorageClass' => 'STANDARD'
)
);
} catch (S3Exception $e) {
die('Error:' . $e->getMessage());
} catch (Exception $e) {
die('Error:' . $e->getMessage());
}
echo 'Done';
}
?>
I can confirm that the file is being uploaded to S3 but the data in the file is not there. Any help in this would be very much appreciated.

GuzzleHttp\Client 400 bad request on Laravel 5.5

I am sending a POST request to an API, Curl returns 200 and the correct response.
When Implementing with GuzzleHttp\Client, I get a 400 Bad request, what is wrong with my formatting.
here is my code using Laravel Returns 400 Bad Request:
$client = new Client();
$URI = 'http://api.example.com';
$params['headers'] = ['Content-Type' => 'application/json',
'apikey' => config('app._api_key'),
'debug' => true
];
$params['form_params'] = [
'sender' => 'Test_sender',
'recipient' => config('app.test_recipient'),
'message_body' => 'Test body'
];
return $response = $client->post($URI, $params);
Curl (Returns 200):
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'apikey: 212121212’ -d '{ "message_body": "test","sender": "2018","recipient": “4453424141” }' 'http://api.example.com'
Try the below code:
$client = new \GuzzleHttp\Client(['headers' => ['Content-Type' => 'application/json',
'apikey'=> config('app._api_key'),
'debug' => true
]
]);
$URI = 'http://api.example.com';
$body['sender']='Test_sender';
$body['recipient']=config('app.test_recipient');
$body['message_body']='Test body';
$body=json_encode($body);
$URI_Response = $client->request('POST',$URI,['body'=>$body]);
$URI_Response =json_decode($URI_Response->getBody(), true);
return $URI_Response;
Note: I would suggest you to handle error please refer GuzzleDocumentation
That is proper error handling:
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
try {
$response = $client->get(YOUR_URL, [
'connect_timeout' => 10
]);
// Here the code for successful request
} catch (RequestException $e) {
// Catch all 4XX errors
// To catch exactly error 400 use
if ($e->getResponse()->getStatusCode() == '400') {
echo "Got response 400";
}
// You can check for whatever error status code you need
} catch (\Exception $e) {
// There was another exception.
}
Implementation: http://guzzle.readthedocs.org/en/latest/quickstart.html
You can handle errors like this
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\RequestException;
use Exception;
try{
$client = new Client();
$response = $client->request('POST', $url,[
'headers' => $header,
'form_params' => $form-params
]);
$body = $response->getBody();
$status = 'true';
$message = 'Data found!';
$data = json_decode($body);
}catch(ClientException $ce){
$status = 'false';
$message = $ce->getMessage();
$data = [];
}catch(RequestException $re){
$status = 'false';
$message = $re->getMessage();
$data = [];
}catch(Exception $e){
$this->status = 'false';
$this->message = $e->getMessage();
$data = [];
}
return ['status'=>$status,'message'=>$message,'data'=>$data];

Categories