PHP Upload Image from URL to Facebook [duplicate] - php

I'm trying to upload www hosted (e.g. http://www.google.se/intl/en_com/images/srpr/logo1w.png) files to a facebook album.
Creating an album works just fine, but I don't seem to uploading any photos. I'm using the facebook php-sdk ( http://github.com/facebook/php-sdk/ ) and the examples I already tried are:
Upload Photo To Album with Facebook's Graph API
How can I upload photos to album using Facebook Graph API
I'm guessing CURL uploads perhaps only can manage locally stored files and not web hosted ones.
Here's my code:
/*
Try 1:
$data = array();
$data['message'] = $attachment->post_title;
$data['file'] = $attachment->guid;
try {
$photo = $facebook->api('/' . $album['id'] . '/photos?access_token=' . $session['access_token'], 'post', $data);
} catch (FacebookApiException $e) {
error_log($e);
}
*/
// Try 2:
//upload photo
$file = $attachment->guid;
$args = array(
'message' => 'Photo from application',
);
$args[basename($file)] = '#' . realpath(file_get_contents($file));
$ch = curl_init();
$url = 'https://graph.facebook.com/' . $album['id'] . '/photos?access_token=' . $session['access_token'];
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $args);
$data = curl_exec($ch);
//returns the photo id
print_r(json_decode($data,true));
...where attachment->guid contains the photo url.
I'm pretty much stuck right now...

i think the problem is here:
$args[basename($file)] = '#' . realpath(file_get_contents($file));
since you want to post a picture from another source (right?), you should save it temporarily on your own host.
i also needed to do something like this, and since i had to process the image, i used the following way:
$im = #imagecreatefrompng('http://www.google.se/intl/en_com/images/srpr/logo1w.png');
imagejpeg($im, 'imgs/temp/temp.jpg', 85);
$args['image'] = '#' . realpath('imgs/temp/temp.jpg');
the rest looks fine though

I'll suggest to use the Facebook php SDK, it will be easier and the code will work with future updates of the APIs:
Using the Graph API php sdk:
$fbk = new Facebook(/* conf */);
$fbk->setFileUploadSupport(true);
//If you are executing this in a script, and not in a web page with the user logged in:
$fbk->setAccessToken(/* access token from other sources */);
//To add to an album:
$fbk->api("/$albumId/photos", "POST",
array('source' => '#'. realpath($myPhoto), 'message' => "Nice photo"));
//To upload a photo directly (the album will be created automatically):
$fbk->api("/me/photos", "POST",
array('source' => '#'. realpath($myPhoto), 'message' => "Nice photo"));
Using cURL directly:
If your really want to use cURL, your code is almost correct, but the error is in the $args array:
$args = array(
'message' => 'Photo from application',
'source' => file_get_contents($file)
);
Since the key for the photo data is source, see the Facebook Doc
Note on the # in cURL:
Also notice that the # in cUrl means that the parameter will be replaced with the actual bytes of the file that follows the #, so it isn't required if you already put in the source parameter the actual bytes.

I'm guessing CURL uploads perhaps only can manage locally stored files and not web hosted ones.
No, that’s not the case.
But you need to give the full, publicly reachable HTTP URL to the image, without an # in front – and you have to use the parameter name url for this value.
https://developers.facebook.com/docs/reference/api/photo/:
You can also publish a photo by providing a url param with the photo's URL.

Related

php telegram sendPhoto not working (url & file location)

I need some help if possible with php sendPhoto api, I've been using the sendPhoto method in php on my apache server to auto send images into telegram, I've been using this same method for almost 6-7 months and from few days ago suddenly the api method stopped working. I tried passing photo= using the absolute path of file in url and in php using the files directory+filename but sends me an error msg from the api as shown below, first part is my php method which doesnt return any errors, just shows blank
# my php telegram code
$dir = "Attachments/2022/04/09/imagename.jpeg";
$chat_id = '(groupchatid)';
$bot_url = "https://api.telegram.org/bot(mybotapi)/";
$url = $bot_url . "sendPhoto?chat_id=" . $chat_id ;
$post_fields = array('chat_id' => $chat_id,
'photo' => new CURLFile(realpath($dir)),
'caption' =>'Test Image', );
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array( "Content-Type:multipart/form-data" ));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
$output = curl_exec($ch);
When i execute this script as it used to work before recently this is the response i get from the API
{
"ok": false,
"error_code": 400,
"description": "Bad Request: invalid file HTTP URL specified: Unsupported URL protocol"
}
If I replace the image URL to another server it send the image successfully, but im unable to send anything only from my server, If I try access the file directly using the URL of my servers image file I can access it from any pc no issue, only problem is telegram fetching the image, please help, appreciate it
Excuse, I don't usually use curl, so I can give you another option:
function sendPhoto($id, $photo, $text = null){
GLOBAL $token;
$url = 'https://api.telegram.org/bot'.$token."/sendPhoto?
chat_id=$id&photo=$photo&parse_mode=HTML&caption=".urlencode($text);
file_get_contents($url);
}
Just declare the sendPhoto function in this way, put the variabile in which you stored the token instead of "$token" and use the parameters in this way:
$id = the id of the user (the one you declared like this: $id = $update['message']['from']['id'];)
$photo = absolute path of the image you want to send
$text = OPTIONAL caption for the image

Facebook PHP upload file from memory

I'm reading an image from my S3 bucket in AWS and want to upload it to Facebook.
This is the reading function:
/**
* Get a file from the s3 storage
*/
private function uploadPicture() {
$picture = new FacebookPicture();
$file = $this->s3Manager->getFile($this->subEndPoint,$this->verb);
$picture->pictureContent = $file["Body"];
$facebookAlbum = new FacebookAlbum();
$facebookAlbum->album = new Album();
$facebookAlbum->album->facebookAccessToken = "myAccessToken";
$facebookAlbum->id = "myAlbumId";
$facebookManager = new FacebookManager();
$facebookManager->uploadPicture($facebookAlbum,$picture);
}
This is the uploading to Facebook function
/**
* #param $facebookAlbum FacebookAlbum the album to upload the picture to
* #param $picture FacebookPicture the picture to upload
*/
public function uploadPicture($facebookAlbum,$picture)
{
$this->facebook->setAccessToken($facebookAlbum->album->facebookAccessToken);
$this->facebook->setFileUploadSupport(true);
$args = array();
$args["message"] = $picture->description;
$args["source"] = "#" . $picture->pictureContent;
$data = $this->facebook->api('/'. $facebookAlbum->id . '/photos', 'post', $args);
var_dump($data);
}
I keep getting :
curl_setopt_array(): The usage of the #filename API for file uploading is deprecated. Please use the CURLFile class instead in <b>acebook-php-sdk-master/src/base_facebook.php</b> on line <b>1005</b><br />
I think that the problem is that the image content is saved in the memory.
How can I use the variable in my memory in order to post it to Facebook ?
#filename has been deprecated in PHP >= 5.5.0 as stated here under the CURLOPT_POSTFIELDS description , So thats the reason why you got the error .
you have your answer here at this stack overflow thread, where different solutions are discussed . Also here is a snippet from RFC for the code.
Currently, cURL file uploading is done as:
curl_setopt($curl_handle, CURLOPT_POST, 1);
$args['file'] = '#/path/to/file';
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $args);
This API is both invonvenient and insecure, it is impossible to send
data starting with '#' to the POST, and any user data that is being
re-sent via cURL need to be sanitized so that the data value does not
start with #. In general, in-bound signalling usually vulnerable to
all sorts of injections and better not done in this way.
Instead of using the above method, the following should be used to
upload files with CURLOPT_POSTFIELDS:
curl_setopt($curl_handle, CURLOPT_POST, 1);
$args['file'] = new
CurlFile('filename.png', 'image/png'); curl_setopt($curl_handle,
CURLOPT_POSTFIELDS, $args);

How to Upload Inline-Images using Graph API Batch Request?

I'm trying to upload images using Graph API Batch Request, but i'm unable to upload using inline image, can anyone help me please?
Batch Request Docs: https://developers.facebook.com/docs/reference/api/batch/
Photo batch uploads: http://developers.facebook.com/blog/post/493/
Photo batch uploads blog post code works fine, but i want to upload images from my server and not from my pc, Ex: /public_html/image/pic.jpg and i'm not sure how i can do it.
EDIT: I'm using PHP SDK 3.0.1
Here's my code:
<?php
CODE WAS CHANGED AND THE PROBLEM IS FIXED ALREADY, SEE THE ANSWER BELOW
?>
This is from their docs:
Uploading binary data
Binary data can be specified as part of the multipart/mime portion of
the batch API request. The batch Graph API allows uploading multiple
binary items as part of a batch call. In order to do this, you need to
add all the binary items as multipart/mime attachments to your
request, and need each operation to reference its binary items using
the "attached_files" property in the operation. The "attached_files"
property can take a comma separated list of attachment names in its
value.
The following example shows how to upload 2 photos in a single batch
call:
curl
–F ‘access_token=…’ \
-F ‘batch=[{“method”:”POST”, \
“relative_url”:”me/photos”, \
“body”:”message=My cat photo” \
"attached_files":"file1" \
},
{“method”:”POST”, \
“relative_url”:”me/photos”, \
“body”:”message=My dog photo” \
"attached_files":"file2" \
},
]’
-F ‘file1=#cat.gif’ \
-F 'file2=#dog.jpg' \
https://graph.facebook.com
EDIT 2:
The first issue I see is that the Batch should not be part of the URL, but rather part of the params ...
See the crude batch example below:
$batch = array();
$req = array(
'method' => 'GET',
'relative_url' => '/me'
);
$batch[] = json_encode($req);
$req = array(
'method' => 'GET',
'relative_url' => '/me/albums'
);
$batch[] = json_encode($req);
$params = array(
'batch' => '[' . implode(',',$batch) . ']'
);
try {
$info = $facebook->api('/','POST',$params);
} catch(FacebookApiException $e) {
error_log($e);
$info = null;
}
if(!empty($info)){
if($info[0]['code'] == '200'){
$user_profile = json_decode($info[0]['body']);
}
if($info[1]['code'] == '200'){
$user_albums = json_decode($info[1]['body']);
}
echo "<pre>User Profile:\n";
print_r($user_profile);
echo "\nAlbums\n";
print_r($user_albums);
echo "<pre>";
}
Notice specifically how the $facebook->api call is formatted ...
EDIT:
Here is a working batch picture upload:
$files = array(
'/data/Pictures/pic1.jpg',
'/data/Pictures/pic2.jpg',
'/data/Pictures/pic3.jpg'
);
//Must set upload support to true
$facebook->setFileUploadSupport(true);
$batch = array();
$params = array();
$count = 1;
foreach($files as $file){
$req = array(
'method' => 'POST',
'relative_url' => '/me/photos',
'attached_files' => 'file' . $count
);
//add this request to the batch ...
$batch[] = json_encode($req);
//set the filepath for the file to be uploaded
$params['file'.$count] = '#' . realpath($file);
$count++;
}
$params['batch'] = '[' . implode(',',$batch) . ']';
try{
$upload = $facebook->api('/','post',$params);
} catch(FacebookApiException $e) {
error_log($e);
$upload = null;
}
//View the results ...
if(!is_null($upload)){
echo "<pre>" . print_r($upload,1) . "<pre>";
echo "<hr />";
}
Just tested and it works like a charm ...
Well, I'm not too sure and I cannot check at the moment, but
http://au.php.net/manual/en/function.curl-setopt.php
Look it up at CURLOPT_POSTFIELDS, it says:
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, files thats passed to this option with the # prefix must be in array form to work.
Here is another CURL example:
CURL PHP send image
So what you need to do is
$queries = array(
array("method" => "POST", "relative_url" => "me/photos","body" => "message=cool","attached_files" => 'file1')
);
and
$batch = $facebook->api("/?batch=".json_encode($queries)."&file1=#pic.jpg", 'POST');
// // File you want to upload/post
$post_data['file1'] = "#D:/home/2.jpg";
$post_data['file2'] = "#D:/home/1.jpg";
// Initialize cURL
$ch = curl_init();
// Set URL on which you want to post the Form and/or data
curl_setopt($ch, CURLOPT_URL, $post_url);
// Data+Files to be posted
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
// Pass TRUE or 1 if you want to wait for and catch the response against the request made
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
// For Debug mode; shows up any error encountered during the operation
curl_setopt($ch, CURLOPT_VERBOSE, 1);
// Execute the request
$response = curl_exec($ch);
// echo curl_errno($ch);
// echo curl_error($ch);
// Just for debug: to see response
echo $response;
This will work for sure its working for me

Offline upload photo to Facebook with photo from web server

I've searched around everywhere without luck and found lots of examples to upload a photo to facebook when the user is in a session (i.e. the user is physically sitting at the computer and accessing the web page). I've tried the samples, and they work.
I noticed this unanswered question from last year on the same issue
Stackoverflow Question
My current app lets the user authorise off-line updates and I store the access_token, user_id, etc. and I can succesfully post to a users wall when they are offline.
I'm really struggling getting something to work with posting a photo to the users wall. Reading the Facebook documentation, I'm thinking you can only upload photos using multipart/form-data!?!?
That wouldn't work if the user isn't at their computer. Can you upload photos that are stored on a directory on my server?
Here's my code so far. Remember, this doesn't use a facebook session as the access_code has already been granted and stored beforehand. As I mentioned, posting to a users wall already works with this approach.
$filename= "#/myphotodir/filename.jpg");
$url = "https://graph.facebook.com/".$uid."/photos"; //$uid is fb user id
$ch = curl_init($url);
$attachment = array('access_token' => $access_token,
'app_id' => $app_id,
'name' => "A photo from me...",
'fileUpload' => true,
'message' => "my message",
'image' => $filename,
);
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $attachment);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result= curl_exec($ch);
curl_close ($ch);
Edit: $result comes back false... forgot to add that.
Any help would be appreciated.
Many thanks,
Dean
You should use the Facebook SDK. With the Facebook SDK, you can use:
$facebook->setFileUploadSupport( true );
$parameters = array(
'access_token' => 'ACCESS_TOKEN_HERE',
'message' => 'PHOTO_CAPTION',
'image' => '#' . realpath( '/path_to_file.jpg' ) // Notice the # sign
);
$facebook->api( '/user_id/photos', 'post', $parameters );
This will post the photo to their default album. If you replace user_id with an album_id you can post to a specific album.

PHP - Upload a web hosted photo to facebook album via Graph API

I'm trying to upload www hosted (e.g. http://www.google.se/intl/en_com/images/srpr/logo1w.png) files to a facebook album.
Creating an album works just fine, but I don't seem to uploading any photos. I'm using the facebook php-sdk ( http://github.com/facebook/php-sdk/ ) and the examples I already tried are:
Upload Photo To Album with Facebook's Graph API
How can I upload photos to album using Facebook Graph API
I'm guessing CURL uploads perhaps only can manage locally stored files and not web hosted ones.
Here's my code:
/*
Try 1:
$data = array();
$data['message'] = $attachment->post_title;
$data['file'] = $attachment->guid;
try {
$photo = $facebook->api('/' . $album['id'] . '/photos?access_token=' . $session['access_token'], 'post', $data);
} catch (FacebookApiException $e) {
error_log($e);
}
*/
// Try 2:
//upload photo
$file = $attachment->guid;
$args = array(
'message' => 'Photo from application',
);
$args[basename($file)] = '#' . realpath(file_get_contents($file));
$ch = curl_init();
$url = 'https://graph.facebook.com/' . $album['id'] . '/photos?access_token=' . $session['access_token'];
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $args);
$data = curl_exec($ch);
//returns the photo id
print_r(json_decode($data,true));
...where attachment->guid contains the photo url.
I'm pretty much stuck right now...
i think the problem is here:
$args[basename($file)] = '#' . realpath(file_get_contents($file));
since you want to post a picture from another source (right?), you should save it temporarily on your own host.
i also needed to do something like this, and since i had to process the image, i used the following way:
$im = #imagecreatefrompng('http://www.google.se/intl/en_com/images/srpr/logo1w.png');
imagejpeg($im, 'imgs/temp/temp.jpg', 85);
$args['image'] = '#' . realpath('imgs/temp/temp.jpg');
the rest looks fine though
I'll suggest to use the Facebook php SDK, it will be easier and the code will work with future updates of the APIs:
Using the Graph API php sdk:
$fbk = new Facebook(/* conf */);
$fbk->setFileUploadSupport(true);
//If you are executing this in a script, and not in a web page with the user logged in:
$fbk->setAccessToken(/* access token from other sources */);
//To add to an album:
$fbk->api("/$albumId/photos", "POST",
array('source' => '#'. realpath($myPhoto), 'message' => "Nice photo"));
//To upload a photo directly (the album will be created automatically):
$fbk->api("/me/photos", "POST",
array('source' => '#'. realpath($myPhoto), 'message' => "Nice photo"));
Using cURL directly:
If your really want to use cURL, your code is almost correct, but the error is in the $args array:
$args = array(
'message' => 'Photo from application',
'source' => file_get_contents($file)
);
Since the key for the photo data is source, see the Facebook Doc
Note on the # in cURL:
Also notice that the # in cUrl means that the parameter will be replaced with the actual bytes of the file that follows the #, so it isn't required if you already put in the source parameter the actual bytes.
I'm guessing CURL uploads perhaps only can manage locally stored files and not web hosted ones.
No, that’s not the case.
But you need to give the full, publicly reachable HTTP URL to the image, without an # in front – and you have to use the parameter name url for this value.
https://developers.facebook.com/docs/reference/api/photo/:
You can also publish a photo by providing a url param with the photo's URL.

Categories