I am using the Slack Web API Wrapper (https://github.com/palanik/slack-php) trying to upload files to the slack api with the files->upload function with multipart/form-data . However, I only get a error message: "no_file_data".
Here is my code:
include 'vendor/autoload.php';
$slack = new wrapi\slack\slack('api-key');
$file = new CurlFile(realpath(dirname(__FILE__) . '/dir/dir/test.jpg'), 'image/png');
$id = 'XXXX';
$reply = $slack->files->upload
(
[
[
'name' => 'file.jpg',
'channel' => $id,
'file' => $file,
'filetype' => 'jpg',
'filename' => 'test.jpg'
]
]
);
Any ideas of what I am doing wrong? I have tried review the other threads here... The test.jpg-file is not the error source.
Related
I am trying to create Video ad Campaigns using LinkedIn API. I am using Laravel, Guzzle and I have followed steps given in documentation to upload video
Initialize Upload for Video
Upload the Video
Finalize Video Upload
On Initialization I receive success response with multiple upload Urls depending on the file size. Using these uploadUrl I am making request to upload the file chunk using Guzzle but in response it is throwing INternal server error 500. I understand it can be server error but not sure if that raised to any header, param or token.
Please help If anyone has faced similar issue and got resolved. I am sharing the response of the initialize upload and request being made using Guzzle.
Doc Link
Response of Initialize APi
{#1344 // app/Services/LinkedIn/LinkedInCampaignService.php:328
+"value": {#1324
+"uploadUrlsExpireAt": 1669664693370
+"video": "urn:li:video:C4D10AQGwksU16dn3Zw"
+"uploadInstructions": array:2 [
0 => {#1325
+"uploadUrl": "https://www.linkedin.com/dms-uploads/C4D10AQGwksU16dn3Zw/uploadedVideo?sau=aHR0cHM6Ly93d3cubGlua2VkaW4uY29tL2FtYnJ5L2FtYnJ5LXZpZGVvLz94LWxpLWFtYnJ5LWVwPUFRTE9OS2RwQmlCOS1BQUFBWVM2bndCNTd1MTR1Yjh5bVVKQ1BERDhFcVhIN1hxcXl1OHBiM3BuUVVCLV82dng2cjZscGVkWmNJajZFZXR2c2trZ1pKM1Z2MVJwWDRxQnQ4T1Z1SWxHNGlUbk85eF9tX082dE11MHhySnhod0RmbFNzUlBvWV90b1Fjdmd0TlZUTlNOQ2RlQkZKR2Zodk8tSktkcWlGMUFpa3pDZjVveDFMcnBQbkY3TXBaYkVkdlpKQXJnMGQ4R3gxQmFZWGR2SFA4aXdtRWRGdGlrSGNLRXVTa283eDhvWnNOZXRVX3I2WVlQa2dXaC1rZlVGbkh0MnNqVW03akItLVFtaGpzX3lwYTdiaEtMd0oxRFZyaEhvUE9KeGl2eFZKSEFELWVFM2txd2tHOWlvblByVm9IMU9tM2N4NXdTMU9TLUgtbjZyMmo4aHZIMFg5ckdlNWNSQkNjdUt0RmVCRkpGMzVoYnN1ZXdCZ3k1UkdxMjdpT1ZFVWRVVUdOelpxRWRKQXlGQXlFTTgteUtwbmVQalpORnFQcFVnVHl6cG80c3hqMGo2VDl6Nlp2cWNlcE1SaDBoZDRhY2Vhc1luUHNfUTc1cWNjbFBXQ2hKclpWU2NhaktRWk9WNlAyc3ZUU190cWFNQkZ1VGtWQ2Q3a0RIY2o5VmVaam1YY3hFREdpWVQzVmM4Vy1ieDdqZFRXMHBpRk9ZcURPTndTcjJZajNBZU4tcXVmRThtQy1qMzA4eEdic3NVQ0wxTTVSZTJjVmVxOS1pbDVQWmQ2MDRXU2lBSXhhejNDM09aenZmaXYtRkRwWlBIaEdscGVCYTdadFAycGRJMXR4eUpUdzVtcFFMTExiN1o2WGNscWoybWFlWkJwUkxZU0VIZXZ0Q29qMXNSUDRrcHQ0ZFluTUw1U0J6RV9qU2ZacW1pS21SS29RcnNrYWZrcUtUY0tMV1o5ZmZKTWZvaGNHTVE2ZTlRdlBJaGJHZ3ZSSFlWdFBjd1BOOG5uSG5rXzFIcE1SWWtWeGdoTVlhQm5KVGJrWDIxaExzYVBNVHlyM2FTQnlTME54c0c2UENMX202eDN2NlBmUC1nQXo1UDZOUGkxUHRubDE2Nm92Tm5ZNHNTdWxrNDdlaGVfZ1FZcnJDalZIbGVYZW4wU0g4TGUwaDNLczFLckdsekpyY0pqMjhQa29NQUdXN1ZCdktZN0ctdFZ0T0Q1cEswTTNsMUthUUQteGxsWnpVV3JLN2V2ZmtfZnEtZWNENTR5aHpKb1FVTzVmbWhDeDVIWERjT1ZYckhlWXlqVFlpbVQ5R1ZmdU9fbkdSZWtTczZENHZ6eVljejN1S0QxVmEzY3dnTU9heWQ4S3RBaVRjMGU3ZFVPdmJaMklNUnhnUlNKQnBaTmtDaHRybGRKQlJJUjRlakdMUkxJS2FpRElRUDlzMGkwUHZhNHVPOG8%253D&pn=1&m=91877349&app=4647153&sync=0&v=beta&ut=1cmOzfpLG0Caw1"
+"lastByte": 4194303
+"firstByte": 0
}
1 => {#1345
+"uploadUrl": "https://www.linkedin.com/dms-uploads/C4D10AQGwksU16dn3Zw/uploadedVideo?sau=aHR0cHM6Ly93d3cubGlua2VkaW4uY29tL2FtYnJ5L2FtYnJ5LXZpZGVvLz94LWxpLWFtYnJ5LWVwPUFRTE9OS2RwQmlCOS1BQUFBWVM2bndCNTd1MTR1Yjh5bVVKQ1BERDhFcVhIN1hxcXl1OHBiM3BuUVVCLV82dng2cjZscGVkWmNJajZFZXR2c2trZ1pKM1Z2MVJwWDRxQnQ4T1Z1SWxHNGlUbk85eF9tX082dE11MHhySnhod0RmbFNzUlBvWV90b1Fjdmd0TlZUTlNOQ2RlQkZKR2Zodk8tSktkcWlGMUFpa3pDZjVveDFMcnBQbkY3TXBaYkVkdlpKQXJnMGQ4R3gxQmFZWGR2SFA4aXdtRWRGdGlrSGNLRXVTa283eDhvWnNOZXRVX3I2WVlQa2dXaC1rZlVGbkh0MnNqVW03akItLVFtaGpzX3lwYTdiaEtMd0oxRFZyaEhvUE9KeGl2eFZKSEFELWVFM2txd2tHOWlvblByVm9IMU9tM2N4NXdTMU9TLUgtbjZyMmo4aHZIMFg5ckdlNWNSQkNjdUt0RmVCRkpGMzVoYnN1ZXdCZ3k1UkdxMjdpT1ZFVWRVVUdOelpxRWRKQXlGQXlFTTgteUtwbmVQalpORnFQcFVnVHl6cG80c3hqMGo2VDl6Nlp2cWNlcE1SaDBoZDRhY2Vhc1luUHNfUTc1cWNjbFBXQ2hKclpWU2NhaktRWk9WNlAyc3ZUU190cWFNQkZ1VGtWQ2Q3a0RIY2o5VmVaam1YY3hFREdpWVQzVmM4Vy1ieDdqZFRXMHBpRk9ZcURPTndTcjJZajNBZU4tcXVmRThtQy1qMzA4eEdic3NVQ0wxTTVSZTJjVmVxOS1pbDVQWmQ2MDRXU2lBSXhhejNDM09aenZmaXYtRkRwWlBIaEdscGVCYTdadFAycGRJMXR4eUpUdzVtcFFMTExiN1o2WGNscWoybWFlWkJwUkxZU0VIZXZ0Q29qMXNSUDRrcHQ0ZFluTUw1U0J6RV9qU2ZacW1pS21SS29RcnNrYWZrcUtUY0tMV1o5ZmZKTWZvaGNHTVE2ZTlRdlBJaGJHZ3ZSSFlWdFBjd1BOOG5uSG5rXzFIcE1SWWtWeGdoTVlhQm5KVGJrWDIxaExzYVBNVHlyM2FTQnlTME54c0c2UENMX202eDN2NlBmUC1nQXo1UDZOUGkxUHRubDE2Nm92Tm5ZNHNTdWxrNDdlaGVfZ1FZcnJDalZIbGVYZW4wU0g4TGUwaDNLczFLckdsekpyY0pqMjhQa29NQUdXN1ZCdktZN0ctdFZ0T0Q1cEswTTNsMUthUUQteGxsWnpVV3JLN2V2ZmtfZnEtZWNENTR5aHpKb1FVTzVmbWhDeDVIWERjT1ZYckhlWXlqVFlpbVQ5R1ZmdU9fbkdSZWtTczZENHZ6eVljejN1S0QxVmEzY3dnTU9heWQ4S3RBaVRjMGU3ZFVPdmJaMklNUnhnUlNKQnBaTmtDaHRybGRKQlJJUjRlakdMUkxJS2FpRElRUDlzMGkwUHZhNHVPOG8%253D&pn=2&m=91877349&app=4647153&sync=0&v=beta&ut=3GSFILXAS0Caw1"
+"lastByte": 5253879
+"firstByte": 4194304
}
]
+"uploadToken": ""
}
}
Calling Upload Urls
public function uploadChunkedVideo($fileName, $uploadInstructions)
{
try {
$fileHandler = fopen(storage_path('app') . '/' . $fileName, 'r');
$client = new Client();
$uploadPartIds = [];
foreach ($uploadInstructions as $instruction) {
$chunkedUpload = $client->put($instruction->uploadUrl, [
'headers' => [
'Content-Type' => 'application/octet-stream',
'Authorization' => 'Bearer ' . $this->accessToken,
'LinkedIn-Version' => config('services.linkedIn.version'),
],
'multipart' => [
[
'name' => $fileName,
'contents' => fread($fileHandler, $instruction->lastByte - $instruction->firstByte),
]
],
]);
//Push etag
$uploadPartIds[] = $chunkedUpload->getHeader('ETag')[0];
}
} catch (\GuzzleHttp\Exception\ServerException $e) {
dd($e->getResponse()->getBody()->getContents());
}
}
This worked for me.
$fileHandler = fopen(storage_path('app') . '/' . $fileName, 'r');
$client = new Client();
$uploadPartIds = [];
foreach ($uploadInstructions as $instruction) {
$chunkedUpload = $client->put($instruction->uploadUrl, [
'headers' => [
'Content-Type' => 'application/octet-stream',
'Authorization' => 'Bearer ' . $this->accessToken,
'LinkedIn-Version' => config('services.linkedIn.version'),
],
'body' => fread($fileHandler, $instruction->lastByte - $instruction->firstByte),
]);
//Push etag
$uploadPartIds[] = $chunkedUpload->getHeader('ETag')[0];
info($uploadPartIds);
}
return $uploadPartIds;
Hi I am trying to send an image. The documentation states that I can send a file using multipart/form-data.
Here is my code:
// I checked it, there really is a file.
$file = File::get(Storage::disk('local')->path('test.jpeg')) // it's the same as file_get_contents();
// Here I use the longman/telegram-bot library.
$serverResponse = Request::sendPhoto([
'chat_id' => $this->tg_user_chat_id,
'photo' => $file
]);
// Here I use Guzzle because I thought that there might be an
// error due to the longman/telegram-bot library.
$client = new Client();
$response = $client->post("https://api.telegram.org/$telegram->botToken/sendPhoto", [
'multipart' => [
[
'name' => 'photo',
'contents' => $file
],
[
'name' => 'chat_id',
'contents' => $this->tg_user_chat_id
]
]
]);
Log::info('_response', ['_' => $response->getBody()]);
Log::info(env('APP_URL') . "/storage/$url");
Log::info('response:', ['_' => $serverResponse->getResult()]);
Log::info('ok:', ['_' => $serverResponse->getOk()]);
Log::info('error_code:', ['_' => $serverResponse->getErrorCode()]);
Log::info('raw_data:', ['_' => $serverResponse->getRawData()]);
In both cases, I get this response:
{\"ok\":false,\"error_code\":400,\"description\":\"Bad Request: invalid file HTTP URL specified: Wrong URL host\"}
Other download methods (by ID and by link) work. Can anyone please point me in the right direction?
Using the php-telegram-bot
library, sendPhoto can be used like so:
<?php
require __DIR__ . '/vendor/autoload.php';
use Longman\TelegramBot\Telegram;
use Longman\TelegramBot\Request;
// File
$file = Request::encodeFile('/tmp/image.jpeg');
// Bot
$key = '859163076:something';
$telegram = new Telegram($key);
// sendPhoto
$chatId = 000001;
$serverResponse = Request::sendPhoto([
'chat_id' => $chatId,
'photo' => $file
]);
The trick is to use Request::encodeFile to read the local image.
I am uploading a file to my API built on laravel. In my code below, the data is sent to the API. But how can i get the file that was uploaded to the API ?
Controller
$file = $request->file('imported-file');
$name = $file->getClientOriginalName();
$path ='/Users/desktop/Folder/laravelapp/public/Voice/';
$client = new \GuzzleHttp\Client();
$fileinfo = array(
'message' => 'Testing content',
'recipient' => "102425",
);
$res = $client->request('POST', $url, [
'multipart' => [
[
'name' => 'FileContents',
'contents' => file_get_contents($path . $name),
'filename' => $name
],
[
'name' => 'FileInfo',
'contents' => json_encode($fileinfo)
]
],
]);
API Controller
if (!empty('FileInfo')) {
return response()->json([
'status' => 'error',
'file_content' => $request->file('FileContents'),
'media'=>$request->hasFile('FileContents'),
]);
}
This is the response, i get "file":null,"file_content":{},"media":true
Why is the file content empty when media is showing true meaning there is a file ?
There can be multiple reasons :
Check your content type. Sometimes we forget to specify multipart/form-data and the request is sent with generic application/x-form-urlencoded etc.
Secondly if you are using jQuery, then set :
contentType: false,
processData: false,
cache: false
This will help your form request no getting converted to string payload and not forcing ajax to set content type. try using FormData.
Update : Found similar answer in this post has detailed answer for this.
I am able to upload a file to an API endpoint using Postman.
I am trying to translate that into uploading a file from a form, uploading it using Laravel and posting to the endpoint using Guzzle 6.
Screenshot of how it looks in Postman (I purposely left out the POST URL)
Below is the text it generates when you click the "Generate Code" link in POSTMAN:
POST /api/file-submissions HTTP/1.1
Host: strippedhostname.com
Authorization: Basic 340r9iu34ontoeioir
Cache-Control: no-cache
Postman-Token: 6e0c3123-c07c-ce54-8ba1-0a1a402b53f1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="FileContents"; filename=""
Content-Type:
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="FileInfo"
{ "name": "_aaaa.txt", "clientNumber": "102425", "type": "Writeoff" }
----WebKitFormBoundary7MA4YWxkTrZu0gW
Below is controller function for saving the file and other info. The file uploads correctly, I am able to get the file info.
I think the problem I am having is setting the multipart and headers array with the correct data.
public function fileUploadPost(Request $request)
{
$data_posted = $request->input();
$endpoint = "/file-submissions";
$response = array();
$file = $request->file('filename');
$name = time() . '_' . $file->getClientOriginalName();
$path = base_path() .'/public_html/documents/';
$resource = fopen($file,"r") or die("File upload Problems");
$file->move($path, $name);
// { "name": "test_upload.txt", "clientNumber": "102425", "type": "Writeoff" }
$fileinfo = array(
'name' => $name,
'clientNumber' => "102425",
'type' => 'Writeoff',
);
$client = new \GuzzleHttp\Client();
$res = $client->request('POST', $this->base_api . $endpoint, [
'auth' => [env('API_USERNAME'), env('API_PASSWORD')],
'multipart' => [
[
'name' => $name,
'FileContents' => fopen($path . $name, 'r'),
'contents' => fopen($path . $name, 'r'),
'FileInfo' => json_encode($fileinfo),
'headers' => [
'Content-Type' => 'text/plain',
'Content-Disposition' => 'form-data; name="FileContents"; filename="'. $name .'"',
],
// 'contents' => $resource,
]
],
]);
if($res->getStatusCode() != 200) exit("Something happened, could not retrieve data");
$response = json_decode($res->getBody());
var_dump($response);
exit();
}
The error I am receiving, screenshot of how it displays using Laravel's debugging view:
The way you are POSTing data is wrong, hence received data is malformed.
Guzzle docs:
The value of multipart is an array of associative arrays, each
containing the following key value pairs:
name: (string, required) the form field name
contents:(StreamInterface/resource/string, required) The data to use in the
form element.
headers: (array) Optional associative array of custom headers to use with the form element.
filename: (string) Optional
string to send as the filename in the part.
Using keys out of above list and setting unnecessary headers without separating each field into one array will result in making a bad request.
$res = $client->request('POST', $this->base_api . $endpoint, [
'auth' => [ env('API_USERNAME'), env('API_PASSWORD') ],
'multipart' => [
[
'name' => 'FileContents',
'contents' => file_get_contents($path . $name),
'filename' => $name
],
[
'name' => 'FileInfo',
'contents' => json_encode($fileinfo)
]
],
]);
$body = fopen('/path/to/file', 'r');
$r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);
http://docs.guzzlephp.org/en/latest/quickstart.html?highlight=file
In Laravel 8 with guzzle I am using this:
The idea is that you are reading the file with fread or file_get_content, then you can use the Laravel getPathname() which points to the file in /tmp
$response = $this
->apiClient
->setUserKey($userToken)
->post(
'/some/url/to/api',
[
'multipart' => [
'name' => 'avatar',
'contents' => file_get_contents($request->file('avatar')->getPathname()),
'filename' => 'avata.' . $request->file('avatar')->getClientOriginalExtension()
]
]
);
Here is the parameter, under labels.restricted :
https://developers.google.com/drive/v2/reference/files/insert
But cannot code it in PHP tried almost everything but still getting error from the google drive API.
$file = new Google_Service_Drive_DriveFile();
$file->setTitle(TESTFILE);
$file->setRestricted();
$result = $service->files->insert(
$file,
array(
'data' => file_get_contents(TESTFILE),
'mimeType' => 'application/octet-stream',
'uploadType' => 'multipart'
//
// HERE SHOULD BE THE CODE FOR THE labels.restricted
//
)
);
You have to setRestricted on a Label:
$label = new Google_Service_Drive_DriveFileLabels();
$label->setRestricted(true);
$file->setLabels($label);