Web Developer / Blog

November
27th, 2008

Using the Facebook API to upload photos

Digg this article · Save to del.icio.us · Stumble it!

Facebook’s photos and albums are no way to truly store or organize your photos.  It is however one of the best ways to share them.  This created quite a conundrum for me as I had no interest in uploading photos to two different websites.  I don’t use Flickr or Smugmug or any other photo sharing service that you’ve heard of.  Since I was a co-founder at Photagious it’s a natural choice as my photo management site.

Defining the goal
I wanted to be able to selectively publish photos from my Photagious account to Facebook.  I didn’t need any of the fancy Facebook application junk…I just wanted to make it easy to post photos from my Photagious account into my Facebook photos.  Turns out that it’s dead simple once you do a little bit of research.

Step number one
First, you need to get an application key and secret.  One way to do this by creating a new application.  Most of the information you’ll be asked for will be unused, so fill them in with whatever you’d like.  Just make sure to enable developers working on the application to install it.

Step number two
Second, you need to install the application.

Step number three (final)
Now, the code.  Basically, you generate the request with the required fields, generate the signature, append the file and send off the request.  For the sake of brevity, I’m pasting in the entire file here.

$key = 'your_key';
$sec = 'your_secret';
$ver = '1.0';
$cid = microtime(true);
$uid = 'BIGINT';
$file= '/path/to/your/file.jpg';

$args = array(
  'method' => 'photos.upload',
  'v' => $ver,
  'api_key' => $key,
  'uid' => $uid,
  'call_id' => $cid,
  'format' => 'XML'
);
signRequest($args, $sec);
$args[basename($file)] = '@' . realpath($file);

$ch = curl_init();
$url = 'http://api.facebook.com/restserver.php?method=photos.upload';
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);

echo $data;

function signRequest(&$args, $secret){
  ksort($args);
  $sig = '';
  foreach($args as $k => $v){
    $sig .= $k . '=' . $v;
  }
  $sig .= $secret;
  $args['sig'] = md5($sig);
}

Seriously, that’s it.  Here’s the output I received from the command line.

jmathai@[~/Y/photos]: php fb.php
<?xml version="1.0" encoding="UTF-8"?>
<photos_upload_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd">
<pid>XXXXXXXXXXXXXXXXXX</pid>
<aid>XXXXXXXXXXXXXXXXXX</aid>
<owner>XXXXXXXXXXX</owner>
<src>http://photos-d.ak.fbcdn.net/photos-ak-sf2p/v645/2/72/500273081/s500273081_1648227_6794.jpg</src>
<src_big>http://photos-d.ak.fbcdn.net/photos-ak-sf2p/v645/2/72/500273081/n500273081_1648227_6794.jpg</src_big>
<src_small>http://photos-d.ak.fbcdn.net/photos-ak-sf2p/v645/2/72/500273081/t500273081_1648227_6794.jpg</src_small>
<link>http://www.facebook.com/photo.php?pid=1648227&amp;id=500273081</link>
<caption/>
<created>1227781696</created>
<story_fbid>0</story_fbid>
</photos_upload_response>

Additional reading
You’ll want to get more familiar with Facebook’s API and some of the nuances when posting photos. Here are some links to help get you on your way.

40 Responses to “Using the Facebook API to upload photos”

  1. herve Says:

    I tried this sample and it just times out, has something changed in the API since you posted the code?

  2. jaisen Says:

    @herve, I just tried it again and it worked. If you want you can email me the script you have and I can have a look at it.

  3. herve Says:

    sorry about that, turns out that the path to the file has to be relative to the script, it can’t be an absolute path. Once I realized that, everything worked fine.

  4. dennis Says:

    Hi, what path should i past?

    1) is it the path of the physical image file?
    e.g. C:\images\myimage.jpg

    –OR–

    2)is it the path of the image is my web server?
    e.g. Site: http://www.example.com
    image is located at http://www.example.com/image/my.jpg
    should i past this one only? “/image/my.jpg”

  5. jaisen Says:

    @dennis, You want the path of the physical image file. You can use the full path (i.e. C:\file.jpg on windows).

  6. dennis Says:

    thanks jaisen! :D

  7. dennis Says:

    hi again,

    i got a little problem again, i converted your codes to a function and change
    echo $data; to return $data;

    how come that the data i get does not come in XML? its just pure ramble data of the image i uploaded (without the tags i mean , etc..)

  8. Brian Says:

    Is it possible to pass the UN PWD of the account you want the photos added to? So you could all multiple users on a single site to copy their photos to facebook. Imagine adding code to myspace to move a picture to facebook.

  9. Muhamad Says:

    When i run the code, i got

    12
    This API version is deprecated

    Anybody can help me with this?
    Thanks

  10. jaisen Says:

    @dennis, Muhamad, Oddly enough I get the same result through a browser but it returns only the xml on the command line. I’ll look into this but I don’t know off the top of my head why it’s doing that.

    I can confirm, however, that the request is successful.

    @Brian, you generally want to avoid passing user credentials over the wire. You can easily get an application key and a user id.

  11. vantien Says:

    I make the same this example, but file xml return error ”
    100
    user id parameter or session key required
    - ”
    can you help me this error?

  12. jaisen Says:

    @vantien, are you using the correct user id, key and secret?

  13. Alicia Says:

    I am new to FB development, and I am looking to do something similar (I think). Forgive my ignorance, but I’m missing how this is used in the context of Photagious. Do end users of this app have to install it on their FB account? i.e. Is there a way to upload photos to a FB account through a 3rd-party program without the user installing a FB app? Not sure if I’m asking the right questions. Any advice is appreciated.

  14. jaisen Says:

    @Alicia - Yes, if you want to post photos directly to someone facebook album, they’ll need to install the app. You only need them to grant special permissions if you want to bypass the default “pending” status. If they allow photo upload permissions to your app, then the photos will be active immediately.

  15. pulkit Says:

    please help me to do this .
    I have the same requirement.
    I need detailed steps to follow.(java API)

  16. jaisen Says:

    @pulkit - I don’t know Java but you would do it the same way. I am sure there are several HTTP libraries for Java and they should have similar methods for you to use.

    The main point is to make a POST to the correct endpoint passing along the proper arguments. Passing the image data will be the trickiest piece, but should be trivial with a decent library.

  17. jim Says:

    jaisen, i’m new to facebook application. i already setup a facebook application for testing purposes. so, i’ve decided to give your code a try but i don’t know where to paste your coding. btw, i’m using joyent accelerator to save all my images. can you help me explaining how to do it in simple step by step. thanks…

  18. alfredo Says:

    This works when trying to upload an image from a webserver (http://myserver/image.jpg) to facebook?

  19. jaisen Says:

    @Jim, I used a php script from both the command line or through apache. Which of the steps tripped you up?

    @alfredo, should work from any computer with internet connectivity and the necessary libraries. In this case it’s php and curl.

  20. Frank Says:

    I tried your code and hosted it online, it works, but one problem is can’t upload photo from pc such as c:\helloworld.jpg. How do i do?

  21. jaisen Says:

    @frank, I don’t really have a pc to test with. What’s the exact error you receive? Might it have to do with escaping the \?

  22. Frank Says:

    Here is what i get error:

    Error while loading page from myapp
    The URL http://www.domaincom/facebook/myapp returned HTTP code 200 and no data.
    There are still a few kinks Facebook and the makers of AfinosImageUploader are trying to iron out. We appreciate your patience as we try to fix these issues. Your problem has been logged - if it persists, please come back in a few days. Thanks!

    I sent you my code and my app web address. Hope you can have a look on it. Thank lot!

  23. Frank Says:

    Jaisen:

    are you busy? I have been waiting for your response so long. =(

    Frank

  24. jaisen Says:

    @Frank, I am actually. I probably won’t be able to take a look at it for a while. Plus, Facebook’s APIs are such a pain to work with :).

    Sorry about that though.

  25. DrBigFresh Says:

    Anyone know of a way to fake this out to let it post images on a different server
    i.e. http://www.somewhere.com/this.jpg
    ?

  26. jaisen Says:

    @DrBigFresh, you could download the image using curl and then upload it from the file system.

  27. Jeaffrey Gilbert Says:

    I’m getting error:
    “Grant permission for status updates 200 Permissions error”

    What should I do..? Thx Jaisen.

  28. Adam Says:

    U r an absolute legend!! Started learning MIME types and all sorts and then found this golden code.

    One question.. could I upload several images at once or do we do this for each image?

    thanks

  29. jaisen Says:

    @Adam, I don’t believe they support multiple photos per request so you’ll have to do this for each image. I haven’t used this api in ages so I maybe out dated with that information.

  30. adam Says:

    @jaisen, I’ve decided to use a loop and call this function for each photo.

    Thanks again for this bit of work. Really helped me.

  31. Yoyobee Says:

    Hey guys ? I tried to push image from URL like this : http://example.com/img/test.jpg but not work.
    Then I used : ./img/test.jpg it work well .
    So my question : could we using full urls like : http://somewhere.com/someimage.jpg ?
    Would you like to help me about this issue ? Thanks a lot. If can, please mail for me. Thanks again.

  32. jaisen Says:

    In order to upload a file hosted on the you’ll first have to download it using curl or some other tool.

  33. Yoyobee Says:

    Well, I think this could be done with run_multipart_http_transaction in Facebook library. If you don’t want to using curl you could use multipart http and this method work with any http url.
    This tips help anyone want upload image from any url within http :
    in file :facebookapi_php5_restlib.php
    Function : call_upload_method()
    Disable check file exist or handle with your own.
    Function : post_upload_request()
    Using run_multipart_http_transaction() as default upload instead of curl upload.
    I think it can help someone !

  34. Miro Says:

    Hello,

    I’ve put this to work, but when I what to set caption with a new line or a link it displays the html code in the caption, but no link.

    Is it possible to put some HTML in the photo caption?

    Thanks in advance,
    Miro

  35. Yoyobee Says:

    @Miro : I don’t think we could put HTML in photo caption. In Facebook API sheet docs caption must be string value.

  36. pranko Says:

    hello,

    i love this description of how to use the restapi with curl!

    but …

    i always get an 104 error with this example!

    [CODE]
    $key = APP_KEY_DATA;
    $secApp = APP_SECRET_DATA;

    $ver = ‘1.0′;
    $cid = microtime(true);
    $uid = $_GET['uid'];
    $file= ‘picture.jpg’;

    $args = array(
    ‘method’ => ‘facebook.photos.upload’,
    ‘v’ => $ver,
    ‘api_key’ => $key,
    ‘uid’ => $uid,
    ‘call_id’ => $cid,
    ’session_key’ => $_GET['key'],
    ‘format’ => ‘XML’
    );

    signRequest($args, $secApp);

    $args[basename($file)] = ‘@’.realpath($file);

    $ch = curl_init();
    $url = ‘http://api.facebook.com/restserver.php’;
    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);
    print_r(curl_getinfo($ch));

    echo $data;

    function signRequest(&$args, $secret)
    {
    echo “app secret:”.$secret.”";
    ksort($args);
    $sig = ”;
    foreach($args as $k => $v)
    {
    $sig .= $k . ‘=’ . $v;
    }

    $sig .= $secret;
    echo “signatureRAW:”.$sig.”—”;
    $args['sig'] = md5($sig);
    echo “signature:”.md5($sig).”—”;
    }
    [/CODE]

    i am honestly desperate because i can’t see anything wrong in there!

    even the output
    signatureRAW:api_key=APP_KEYcall_id=PHP_MICROTIMEformat=XMLmethod=facebook.photos.uploadsession_key=SESSION_IDuid=UIDv=1.0APP_SECRET

    look right to me!

    any suggesstions?

  37. pranko Says:

    sorry …

    stupid me!

    on :http://wiki.developers.facebook.com/index.php/How_Facebook_Authenticates_Your_Application

    it says: $secret = ‘Secret Key’; // where ‘Secret Key’ is your application secret key

    but i found out that it is session_secret!

    works now!

    very nice tutorial, THX again

  38. pranko Says:

    once again me …

    facebook says it needs the raw file data!
    but the args just put …
    $args[basename($file)] = ‘@’.realpath($file);
    is this CRUL specific?
    never seen this construction in php before!

  39. jaisen Says:

    It is PHP specific.

  40. pranko Says:

    i am honestly sorry to ask a question and then correct you but …

    i found out yesterday that @file … is curl specific from the curllib.c

    the method is called: curl_formparse(”userfile=@/tmp/karte.jpg”,&ppost,&plast);

    but anyway … more than a nice example and still works with new facebook policy!

    THX a lot …

Leave a Reply


About this site:
This is my (Jaisen Mathai) personal site for potential employers who want to see my resume or portfolio. My ideal job would be to work as a Web developer on a large scale consumer website. My experience is in using PHP, MySQL, Ajax and JSON. I really enjoy creative brainstorming...taking a problem apart and narrowing 100 solutions down to the best one.

Thanks for stopping by. Be sure to drop me a line.