Upload item image using Square Connect API and PHP - php

I've reviewed the old questions posted here on Stackoverflow about this issue.
But I didn't find any example for php integration.
Here is a sample of my code to do that but it's failing
$url = 'https://connect.squareup.com/v1/me/items/9999999/image';
$auth_bearer = 'Authorization: Bearer ' . $this->accessToken;
$image_data = base64_encode(file_get_contents('image.jpeg'));
$header = array(
$auth_bearer,
'Accept: application/json',
'Content-Type: multipart/form-data; boundary=BOUNDARY',
);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'files=' . $image_data);
$head = curl_exec($ch);
curl_close($ch);
$response = json_decode($head);
echo "<pre>";
print_r($response);
echo "</pre>";
And nothing happens... any help here?
Thanks

You need to post the raw image data (not base64 encoded) with the proper multipart header for a file object. Here's a working example (replace ACCESS_TOKEN, ITEM_ID, and IMAGE_FILE).
<?php
function uploadItemImage($url, $access_token, $image_file) {
$headers = ["Authorization: Bearer $access_token"];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, ['image_data' => "#$image_file"]);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
$return_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
print "POST to $url with status $return_status\n";
curl_close($ch);
return $data ? json_decode($data) : false;
}
print_r(
uploadItemImage(
'https://connect.squareup.com/v1/me/items/ITEM_ID/image',
'ACCESS_TOKEN',
'IMAGE_FILE.jpg'
)
);
?>

Here is my PHP implementation for uploading a PNG image. Sometimes a different code view helps.
As #Troy stated, the important field to include for images is 'Content-Type: multipart/form-data'. Everything else I upload to Square uses 'Content-Type: application/json'.
$square_url = 'https://connect.squareup.com/v1/me/items/' . $square_item_id . '/image';
$cfile = new CURLFile($image_path_on_server, 'image/png', 'image_data');
$image_data = array('image_data' => $cfile);
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer ' . $access_token,
'Content-Type: multipart/form-data',
'Accept: application/json'
));
curl_setopt($curl, CURLOPT_POSTFIELDS, $image_data);
curl_setopt($curl, CURLOPT_URL, $square_url);
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_SAFE_UPLOAD, TRUE);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($curl, CURLOPT_VERBOSE, TRUE);
$json = curl_exec($curl);
curl_close($curl);

Strictly speaking Square API documentation, their method can be implemented keeping a few things in mind.
-- Your request must be enclosed in a boundary and contain the Content disposition, name, filename, content type like the sample below.
--BOUNDARY
Content-Disposition: form-data; name="image_data"; filename="MyImage.png"
Content-Type: image/png
{BLANK LINE IS REQUIRED}
IMAGE BINARY DATA GOES HERE
--BOUNDARY--
In essence, the format of the request must be exactly as specified in the sample. This includes the 'boundary', the newline characters, the necessary headers, a blank line between the headers (for some reason nothing works if the line isn't present), and the actual image binary data. NOTE: the boundary can be any string that you choose, but it must be used consistently. In code, this would look something like this:
$boundary = "---------------------" . md5(mt_rand() . microtime());
$imageToUpload = "--{$boundary}" . "\r\n" .
"Content-Disposition: form-data; name=\"image_data\"; filename=\"" . $full_path_to_image_file . "\"" . "\r\n" .
"Content-Type: image/jpeg" . "\r\n" .
"\r\n" . // <- empty line is required
(file_get_contents($full_path_to_image_file)) . "\r\n" .
"--{$boundary}--";
The above will produce a request that looks like this:
-----------------------51b62743876b1201aee47ff4b1910e49
Content-Disposition: form-data; name="image_data"; filename="/some/directory/image.jpg"
Content-Type: image/jpeg
����
-----------------------51b62743876b1201aee47ff4b1910e49--
-- Technically speaking, the Content-Type in the request must change with the type of image you're uploading (image/jpeg or image/png). You can set the content type to application/octet-stream to cover all basis.
-----------------------51b62743876b1201aee47ff4b1910e49
Content-Disposition: form-data; name="image_data"; filename="/some/directory/image.jpg"
Content-Type: application/octet-stream
����
-----------------------51b62743876b1201aee47ff4b1910e49--
The two examples above will upload an image.
-- 'Image binary data' can be misleading as my every search showed that an image binary is obtained by using the base64_encode function. In my experiments, the base64_encoding doesn't do anything. You only need to open the file with the file_get_contents.
-- In your cURL request, must have the header's Content-Type set to multipart/form-data and have the same boundary as the request. Example below:
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $personalAccessToken, 'Content-Type: multipart/form-data; boundary=' . $boundary ));
So this adds another solution to the mix.

Troy's solution using # is deprecated and I was unable to get it to work. Byron's solution works with the CURLOPT_POST before the CURLOPT_POSTFIELDS (see Mavooks comment at https://www.php.net/manual/en/function.curl-setopt.php) and removing the Content-Type from the header. That is because it is automatically multipart if CURLOPTS_POSTFIELDS is an array and manually including it seems to override it, but then it is missing the boundary.
$square_url = 'https://connect.squareup.com/v1/me/items/' . $square_item_id . '/image';
$cfile = new CURLFile($image_path_on_server, 'image/png', 'image_data');
$image_data = array('image_data' => $cfile);
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer ' . $access_token,
'Accept: application/json'
));
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $image_data);
curl_setopt($curl, CURLOPT_URL, $square_url);
curl_setopt($curl, CURLOPT_SAFE_UPLOAD, TRUE);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($curl, CURLOPT_VERBOSE, TRUE);
$json = curl_exec($curl);
curl_close($curl);

Related

How to publish media (image) on Mastodon using API?

I'm trying to POST an image on Mastodon (specifically on Humblr) but I cannot get the media_id, the response is null, but I'm not sure where the problem is.
I can publish text, no problem, so the authentication part is fine, I only have the problem with the image, the only difference I can see in the documentation is that "Media file encoded using multipart/form-data".
Here's my code so far...
$headers = ['Authorization: Bearer '.$settings['access_token'] , 'Content-Type: multipart/form-data'];
$mime_type = mime_content_type($urlImage);
$cf = curl_file_create($urlImage,$mime_type,'file');
$media_data = array( "file" => $cf);
$ch_status = curl_init();
curl_setopt($ch_status, CURLOPT_URL, "https://humblr.social/api/v1/media");
curl_setopt($ch_status, CURLOPT_POST, 1);
curl_setopt($ch_status, CURLOPT_POSTFIELDS, $media_data);
curl_setopt($ch_status, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch_status, CURLOPT_HTTPHEADER, $headers);
$media_status = json_decode(curl_exec($ch_status));
echo "Response: ".json_encode($media_status);
From this I want to extract the $media_status-> media_id
I don't really know much about 'multipart/form-data' to be honest.
Am I missing something?
This took some trial and error for me as well. Here's what worked for me (PHP 7.3):
$curl_file = curl_file_create('/path/to/file.jpg','image/jpg','file.jpg');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://instanceurl.com/api/v1/media');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer YOUR_TOKEN_HERE',
'Content-Type: multipart/form-data'
]);
$body = [
'file' => $curl_file
];
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
$response = curl_exec($ch);
if (!$response) {
die('Error: "' . curl_error($ch) . '" - Code: ' . curl_errno($ch));
}
echo 'HTTP Status Code: ' . curl_getinfo($ch, CURLINFO_HTTP_CODE) . PHP_EOL;
echo 'Response Body: ' . $response . PHP_EOL;
curl_close($ch);

Posting to API with curl not working

$headers = array();
$headers[] = 'Authorization: hmac ' .$websiteKey.':'.$hmac .':'.$nonce . ':'.$time;
$curl = curl_init();
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl,CURLOPT_POSTFIELDS, $post);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl);
var_dump($result);
curl_close($curl);
I have the code above, i want to post to an api. Somehow its not working. I tried using a var_dump on the result variable. The result is:
string(117) "{"Message":"The request entity's media type 'application/x-www-form-urlencoded' is not supported for this resource."}"
Any idea why its not posting to the api?
The value of the $post=
{"AmountDebit":10,"Currency":"EUR","Invoice":"testinvoice 123","Services":{"ServiceList":[{"Action":"Pay","Name":"ideal","Parameters":[{"Name":"issuer","Value":"ABNANL2A"}]}]}}
Headers:
$headers[] = 'Authorization: hmac ' .$websiteKey.':'.$hmac .':'.$nonce . ':'.$time;
If you don't specify a Content-Type header when making a POST call with Curl, it will add one in with the value application/x-www-form-urlencoded.
From the Everything Curl book:
POSTing with curl's -d option will make it include a default header that looks like Content-Type: application/x-www-form-urlencoded. That's what your typical browser will use for a plain POST.
Many receivers of POST data don't care about or check the Content-Type header.
If that header is not good enough for you, you should, of course, replace that and instead provide the correct one.
Judging by your request, I imagine you'll need to add the following to the top of your script:
$headers[] = 'Content-Type: application/json';
But depending on the exact API you're posting to, this might need to be different.
Have You installed curl before using it.
If it not install try google for Curl installation
and use my curl function for post request its 100% working-
public function curlPostJson() {
$headers = [];
$headers[] = 'Content-Type: application/json';
$headers[] = 'Content-Length: ' .strlen(json_encode($paramdata));
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($paramdata));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,$headers);
$server_output = curl_exec($ch);
curl_close($ch);
return json_decode($server_output);
}

Is there any PHP.ini setting for curl status code 415?

I have tried to call API for send image file using CURL .But I am getting below error:
"statusCode":415,
"error":"Unsupported Media Type"
Please help me.
I have attached code here:
$filename = "screenshot.jpg";
$handle = fopen($filename, "r");
$xml = fread($handle, filesize($filename));
fclose($handle);
$jwt_token = "xxx";
$authorization = "Authorization:".$jwt_token;
$url = "https://prod0-commerce-api.sprinklr.com/media_upload";
$headers = array(
"Content-Type: image/jpg]",
"Cache-Control: no-cache",
"Pragma: no-cache",
$authorization
);
$postdata = array('fileName' => '#'.$filename,
'type' => 'IMAGE'); //<-------------
$soap_do = curl_init();
curl_setopt($soap_do, CURLOPT_URL, $url);
//curl_setopt($soap_do, CURLOPT_CONNECTTIMEOUT, 60);
//curl_setopt($soap_do, CURLOPT_TIMEOUT, 60);
curl_setopt($soap_do, CURLOPT_RETURNTRANSFER, true );
curl_setopt($soap_do, CURLOPT_SSL_VERIFYPEER, false);
//curl_setopt($soap_do, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($soap_do, CURLOPT_POST, true );
curl_setopt($soap_do, CURLOPT_POSTFIELDS, $postdata); //<-----------
curl_setopt($soap_do, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($soap_do);
// Check for errors and display the error message
curl_close($soap_do);
$httpcode = curl_getinfo($soap_do, CURLINFO_HTTP_CODE);
echo $httpcode;
echo "<pre>";
var_dump($result);
if($errno = curl_errno($soap_do)) {
$error_message = curl_strerror($errno);
echo "cURL error ({$errno}):\n {$error_message}";
}
echo "string";exit();
print_r($result);
The problem is in this block:
$postdata = array('fileName' => '#'.$filename,
'type' => 'IMAGE'); //<-------------
The value of type should be a valid MIME type (aka "media type" or "content type").
A MIME type is an identifier composed of two parts (the type and the subtype) joined by slash (/).
The type identifies the category of content (text, image, audio, video, application etc). The subtype identifies more accurate the content inside the category.
For images, the type is image and there are several subtypes: gif, jpeg, png etc.
A correct MIME type for an image file looks like image/jpeg or image/png and not just IMAGE. This is why the server rejects your query.
The PHP function getimagesize() can be used to find the MIME type of a image stored in a file.
Your code should be like this:
$imgInfo = getimagesize($filename);
$postdata = array('fileName' => '#'.$filename,
'type' => $imgInfo['mime']);
And no, there is no setting in php.ini that writes correct code for you.
I have solved using this solution
<?php
$file = "http://localhost/xxx/screenshot.jpg";
$boundary = md5(time());
$eol = "\r\n";
$params = "----".$boundary.$eol
. "Content-Disposition: form-data;name=\"type\"".$eol
. $eol
. "IMAGE"
. $eol
. "----".$boundary.$eol
. "Content-Disposition: form-data;name=\"file\"; filename=\"screenshot.jpg\"".$eol
. '"Content-Type: image/jpeg\"'.$eol
. $eol
. file_get_contents($file) .$eol
. "----".$boundary."--";
$jwt_token = "xxxx";
$authorization = "Authorization:".$jwt_token;
$first_newline = strpos($params, $eol);
$multipart_boundary = substr($params, 2, $first_newline - 2);
$request_headers = array();
$request_headers[] = $authorization;
$request_headers[] = 'Accept: application/json';
$request_headers[] = 'Content-Length: ' . strlen($params);
$request_headers[] = 'Content-Type: multipart/form-data; boundary='. $multipart_boundary;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'xxx');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_HEADER, 1);
$result = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
echo "<pre>";
print_r($result);
exit();
Most of time a error 415 appears when you don't set properly the Content-Type. Maybe you can put Content-Type:
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: image/jpg"));

DropBox API application/octet-stream header

I'm attempting to make a cUrl request with PHP to the Dropbox API, in order to begin to upload a very large zip file. Here is the documentation I'm trying to implement, found at https://www.dropbox.com/developers/documentation/http/documentation#files-upload -
URL structure: https://content.dropboxapi.com/2/files/upload_session/start
Example cUrl Request:
curl -X POST https://content.dropboxapi.com/2/files/upload_session/start \
--header "Authorization: Bearer <get access token>" \
--header "Dropbox-API-Arg: {\"close\": false}" \
--header "Content-Type: application/octet-stream" \
--data-binary #local_file.txt
And here is my code:
$uploads = wp_upload_dir();
$file = $uploads['basedir']."/maintainme/backups/files/backup_".$filename.'/'.$filename.'.zip';
$ch = curl_init();
$url = 'https://content.dropboxapi.com/2/files/upload_session/start';
$headers = array(
'Authorization: Bearer ' .$dropbox_token,
'Dropbox-API-Arg: {\"close\": false}',
'Content-Type: application/octet-stream',
);
$fields = array('file' => '#' . $file);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields );
curl_setopt($ch, CURLOPT_VERBOSE, 1);
$result = curl_exec($ch);
curl_close($ch);
The error message I get is:
Error in call to API function "files/upload_session/start": Bad HTTP "Content-Type" header: "application/octet-stream; boundary=------------------------1ee7d00b0e9b0c47". Expecting one of "application/octet-stream", "text/plain; charset=dropbox-cors-hack".
It seems that this 'Boundary=------------blahblahblah' gets appended to my content-type header each time I try to make this request. Anyone have any ideas??? Thanks!
Solved it! On a whim, I checked into the 'CURLOPT_POSTFIELDS' option found at http://php.net/manual/en/function.curl-setopt.php, and here's what it said:
The full data to post in a HTTP "POST" operation. To post a file, prepend a filename with # and use the full path. The filetype can be explicitly specified by following the filename with the type in the format ';type=mimetype'. This parameter can either be passed as a urlencoded string like 'para1=val1&para2=val2&...' or as an array with the field name as key and field data as value. If value is an array, the Content-Type header will be set to multipart/form-data. As of PHP 5.2.0, value must be an array if files are passed to this option with the # prefix. As of PHP 5.5.0, the # prefix is deprecated and files can be sent using CURLFile. The # prefix can be disabled for safe passing of values beginning with # by setting the CURLOPT_SAFE_UPLOAD option to TRUE.
The relevant part is bolded in the paragraph above. Apparently passing an array to the CURLOPT_POSTFIELDS option is what was appending that 'Boundary=----blahblahblah' the Content-Type and causing the API call to fail. I changed
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields );
to
curl_setopt($ch, CURLOPT_POSTFIELDS, '#'.$file );
and tried again. The initial issue was fixed, but I then encountered a new issue with the 'Dropbox-API-Arg' line in this section of code:
$headers = array(
'Authorization: Bearer ' .$dropbox_token,
'Dropbox-API-Arg: {\"close\": false}',
'Content-Type: application/octet-stream',
);
Turns out, these arguments need to be properly JSON-Encoded. I did this with the code below:
$args = array('close'=>false);
$args = json_encode($args);
and then changed
'Dropbox-API-Arg: {\"close\": false}'
to:
'Dropbox-API-Arg:'.$args
Here is the complete, final code:
$uploads = wp_upload_dir();
$file = $uploads['basedir']."/maintainme/backups/files/backup_".$filename.'/'.$filename.'.zip';
error_log($file);
$args = array('close'=>false);
$args = json_encode($args);
$ch = curl_init();
$url = 'https://content.dropboxapi.com/2/files/upload_session/start';
$headers = array(
'Authorization: Bearer ' .$dropbox_token,
'Dropbox-API-Arg:'.$args,
'Content-Type: application/octet-stream',
);
$fields = array('file' => '#' . $file);
error_log($fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, '#'.$file );
curl_setopt($ch, CURLOPT_VERBOSE, 1);
$result = curl_exec($ch);
error_log($result);
curl_close($ch);

Using PHP to upload an activity to Strava using API v3

I'm working on an application in which I'd like to be able to upload activities (GPX files) to Strava using it's API v3.
My application successfully handles the OAuth process - I'm able to request activities, etc, successfully.
However, when I try to upload an activity - it fails.
Here's the relevant sample of my code:
// $filename is the name of the GPX file
// $actual_file contains the full path
$actual_file = realpath($filename);
$url="https://www.strava.com/api/v3/uploads";
$postdata = "activity_type=ride&file=". "#" . $actual_file . ";filename=" . $filename . "&data_type=gpx";
$headers = array('Authorization: Bearer ' . $strava_access_token);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_POST, 3);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec ($ch);
Here's what I get in response:
{"message":"Bad Request", "errors":[{"resource":"Upload", "field":"file","code":"not a file"}]}
I then tried this:
// $filename is the name of the GPX file
// $actual_file contains the full path
$actual_file = realpath($filename);
$url="https://www.strava.com/api/v3/uploads";
$postfields = array(
"activity_type" => "ride",
"data_type" => "gpx",
"file" => "#" . $filename
);
$postdata = http_build_query($postfields);
$headers = array('Authorization: Bearer ' . $strava_access_token, "Content-Type: application/octet-stream");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_POST, count($postfields));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$fp = fopen($filename, 'r');
curl_setopt($ch, CURLOPT_INFILE, $fp);
$json = curl_exec ($ch);
$error = curl_error ($ch);
Here's what I get in response:
{"message":"Bad Request", "errors":[{"resource":"Upload", "field":"data","code":"empty"}]}
Clearly, I'm doing something wrong when trying to pass the GPX file.
Is it possible to provide a bit of sample PHP code to show how this should work?
For what it's worth - I'm fairly certain the GPX file is valid (it's actually a file I downloaded using Strava's export feature).
I hope that answering my own question less than one day after posting it isn't bad form. But I've got it working, so I may as well, just in case anyone else finds it useful...
// $filename is the name of the file
// $actual_file includes the filename and the full path to the file
// $strava_access_token contains the access token
$actual_file = realpath($filename);
$url="https://www.strava.com/api/v3/uploads";
$postfields = array(
"activity_type" => "ride",
"data_type" => "gpx",
"file" => '#' . $actual_file . ";type=application/xml"
);
$headers = array('Authorization: Bearer ' . $strava_access_token);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec ($ch);
Apparently, it's important not to include the CURLOPT_POST option.
Here is also a working Python example
import os
import requests
headers = {
'accept': 'application/json',
'authorization': 'Bearer <Token>',
}
dir = os.getcwd() + '/files/'
for filename in os.listdir(dir):
file = open(dir + filename, 'rb')
files = {
"file": (filename, file, 'application/gpx+xml'),
"data_type": (None, 'gpx'),
}
try:
response = requests.post('http://www.strava.com/api/v3/uploads',files=files, headers=headers)
print(filename)
print(response.text)
print(response.headers)
except requests.exceptions.RequestException as e: # This is the correct syntax
print(e)
sys.exit(1)

Categories