Steve's Ramblings

  • Home
  • About
  • LastFM Widgets
  • Post By Mail
  • Site Search
  • Wordbooker
Witterings from the Site owner

← Hitting a moving Target
So much for Mobile broadband →

Using the new Facebook Graph API off-line

May 5th, 2010 by Steve and tagged facebook, graph API, php


One of the features of the old Facebook API was “off-line” access – basically where you could interact with Facebook in a “non-interactive” way : in other words a program or script could interact with Facebook on your behalf without you having to have a Facebook window open in your browser.

The new API also supports this but the documentation is not really totally clear on the “process” needed to do it.

So I sat down and worked it out. The code you are about to see is not neat, or tidy. It contains no proper error handling or checking apart from the bare minimum needed to make it work.

Pre-requisites

You will need:

  • A Webserver
  • PHP V5.x with CURL enabled
  • A MySQL Database.
  • A Facebook Account (preferably a developer account unless your friends like being spammed)
  • A Facebook Application
  • The Facebook Graph PHP-SDK which is available from the GitHub repository.

First of all we need to make sure that we have a table to store the session data in. We are actually storing all the session data : this might be overkill but as a lot of this is still undocumented I felt it was safer to store everything.

So at the start of our example lets do the dirty work with the database. If you were doing this properly you’d have this in a function which you called once, for example with a WordPress plugin you’d call it on plugin activation. But we’re not doing that here so …. and don’t forget to change those db_  parameters to match your system.

$db_server = "localhost";
$db_username = "dbuser";
$db_password = "dbpassword";
$db_name = "dbname";

# Lets connect to the Database and set up the table
mysql_connect($db_server,$db_username,$db_password);
mysql_select_db($db_name);
$ct_res = mysql_query("CREATE TABLE IF NOT EXISTS `facebook_user` (
   `session_key` VARCHAR( 80 ) NOT NULL ,
   `uid` VARCHAR( 80 ) NOT NULL ,
   `expires` VARCHAR( 80 ) NOT NULL ,
   `secret` VARCHAR( 80 ) NOT NULL ,
   `access_token` VARCHAR( 120 ) NOT NULL ,
   `sig` VARCHAR( 80 ) NOT NULL
   );"
);

OK So that’s the DB work done and each time we run the script it will create the table if its not there. Now we can set up the Facebook side of things. Don’t forget to change the path for the facebook.php file (which you did download  didn’t you?). You’ll also need the information about the Facebook Application you set up because I’m not letting you share mine! You may also want to review the permissions that are being granted – the ones in this code are the ones my Wordbooker application uses

# Now lets load the FB GRAPH API
require '../src/facebook.php';

// Create our Application instance.
global $facebook;
$facebook = new Facebook(array(
 'appId'  => '101001010101010101',
 'secret' => 'faafaffdfasdffsafsfsddfasd',
 'cookie' => false,
));

# Lets set up the permissions we need and set the login url in case we need it.
$par['req_perms'] = "publish_stream,
                    offline_access,
                    user_status,
                    read_stream,
                    email,
                    user_groups";
$loginUrl = $facebook->getLoginUrl($par);

The “heart” of the code is the get_check_session function. This function checks to see if we have a session stored in the database and if we do it returns it. If we don’t have a session but a session is being passed in via the URL it gets it, stores it and then returns it. If neither of these cases are true it returns nothing.

function get_check_session(){
  global $facebook;
  # This function basically checks for a stored session and if we have one returns it,
  #If we have no stored session then it gets one and stores it
  # OK lets go to the database and see if we have a session stored
  $sid=mysql_query("Select access_token from facebook_user");
  $session_id=mysql_fetch_row($sid);
  if (is_array($session_id)) {
    # We have a session ID so lets not get a new one
    # Put some session checking in here to make sure its valid
   try {
     $attachment =  array('access_token' => $session_id[0],);
     $ret_code=$facebook->api('/me', 'GET', $attachment);
    }
     catch (Exception $e) {
       # We don't have a good session so
       echo "woops";
      $res = mysql_query('delete from facebook_user where expires=0');
      return;
    }
  return $session_id[0];
 } 

 {
  # Are we coming back from a login with a session set?
  $session = $facebook->getSession();
  if (is_array($session)) {
   # Yes! so lets store it!
   $sql="insert into facebook_user (
               session_key,
               uid,
               expires,
               secret,
               access_token,
               sig)
             VALUES ('".$session['session_key']."','".
                        $session['uid']."','".
                        $session['expires']."','".
                        $session['secret'] ."','".
                        $session['access_token']."','".
                        $session['sig']."');";
   $res = mysql_query($sql);
   return $session['access_token'];
  }
 }
}

OK, believe it or not we are just about there with only a few more lines of code to go. Are you ready?

$access_token=get_check_session();
# If we've not got an access_token we need to login.
if ( is_null($access_token) ) {
echo '<a href="'. $loginUrl.'"><
img src="http://static.ak.fbcdn.net/rsrc.php/zB6N8/hash/4li2k73z.gif" alt="" /> ';
}
else {

# This is where you put your code.
$target=1010101010100110;
$attachment =  array(
 'access_token' => $access_token,
 'message' => 'Did a Test Post :',
 'name' => "Offline posting using stored tokens",
   'link' => "http://blogs.canalplan.org.uk/steve/2010/05/05/using-the-new-facebook-graph-api-off-line/",
  'description' => "This post was made using a stored access token",
  'picture'=>http://blogs.canalplan.org.uk/steve/files/2010/05/Screenshot-5-300x194.png",
			);

$ret_code=$facebook->api('/'.$target.'/feed', 'POST', $attachment);

echo "Returns : ";
var_dump($ret_code);
echo ""; 

$attachment =  array(
'access_token' => $access_token,
 'message' => "and this is a comment I've just made on the post using that same stored token",);

$ret_code=$facebook->api('/'.$ret_code['id'].'/comments', 'POST', $attachment);

echo "Returns : ";
var_dump($ret_code);
echo ""; 

}

Basically any code in the ELSE {} block is executed if you have a Facebook access_token. In the example what we do is post a message to a “target” which is a FB user ID (you can use names rather than numbers), and then we immediately comment on it. Which produces something like:

image showing FB wall postings

A Wall post and an associated comment made by the php code.

So there you go. Why not download the code and give it a go.

  • Share this:
  • Digg
  • Reddit
  • Print
  • StumbleUpon
  • Press This
  • Email

Category Computing |



77 Responses to “ Using the new Facebook Graph API off-line ”

1 2 Next »
  1.    Bruno Gomes Says:
    May 7th, 2010 at 6:21 pm

    Hello from portugal.
    Thank you Thank you Thank you Thank you Thank you

    Does this work Posting to Page walls as the page
    Once Again.
    Thank you for your post…

  2.    Vijay Says:
    May 10th, 2010 at 12:39 am

    Thanks Steve. This is really the first tutorial I could find on Graph API. Thank you so much for the detailed steps.

    I keep getting the below error though I changed the target_id manually and made the fan to the app.

    Fatal error: Uncaught Exception: (#210) User not visible thrown in facebook.php on line 453

    Really appreciate and thanks for the article again.

  3.    Steve Says:
    May 10th, 2010 at 9:07 am

    I’ve changed some code to make it do a good solid session check (I hope). When I get home I’ll update the post and update the downloadable file.

    Does the user you logged in as have access to the target page and is the target page public?

  4.    Vijay Says:
    May 10th, 2010 at 9:53 am

    Thank you so much, Steve

    I will check back.

  5.    Vijay Says:
    May 10th, 2010 at 10:34 am

    Yes, Steve

    I actually trying to publish to the user’s wall. I have create a temp login wiht facebook and became a fan of the app. Pulled the UID of the temp login and used the same UID in the code.

  6.    Steve Says:
    May 10th, 2010 at 6:29 pm

    I’ve updated the post to include the code that checks that the session is valid. The error you are reporting is very odd

  7.    Vijay Says:
    May 11th, 2010 at 9:56 am

    Wow! It works perfectly now. Thanks Steve.

  8.    Nil Says:
    May 11th, 2010 at 11:02 am

    Hi Steven,

    Thanks for your code it works very well. However, I tried also to add the “to” parameter in the post feeding, and it seems not to use that. Do you happen to know if it is working? (If FB really let the end user select friends before he can send the message – it seems possible not through the api):

    $attachment = array(
    ‘access_token’ => $access_token,
    ‘message’ => ‘Did a Test Post :’,
    ‘name’ => “Offline posting using stored tokens”,
    ‘link’ => “http://blogs.canalplan.org.uk/steve/2010/05/05/using-the-new-facebook-graph-api-off-line/”,
    ‘description’ => “This post was made using a stored access token”,
    ‘picture’=>http://blogs.canalplan.org.uk/steve/files/2010/05/Screenshot-5-300×194.png“,
    ‘to’ => friend_list, // a list of user ids separate by comma
    );

    thanks

  9.    Steve Says:
    May 11th, 2010 at 7:31 pm

    Nil, I’ve no idea – I’ve not looked at the to option. It could well be that its not implemented yet (or buggy)

  10.    marcos cabrera Says:
    May 18th, 2010 at 7:27 pm

    greetings from Mexico.

    Thank you very much steve. this code works very well

  11.    AKBAR ALI BUTT Says:
    May 19th, 2010 at 8:39 am

    Hi

    Thanks for tutorial. I need some help. I want to get access token in cron job to update my DB for displaying insights. How can i achieve this. Thanks

    Regards
    Akbar Ali Butt

  12.    Steve Says:
    May 19th, 2010 at 10:12 am

    Once yiu have the token stored in the database you can use it anywhere. As long as it doesn’t expire. So basically take that code and replace the login bit of the code with some error reporting anf wrap it all up in a file with the rest of your code and then call that php file from your cron

  13.    jesus Says:
    May 20th, 2010 at 12:38 am

    i tried this code with the last version of php sdk but i obtain a error 500 when i execute it.
    Could you upload your facebook.php and a detailed how your aplication is configured.

    Pleaseeeeee, i am going mad

  14.    Steve Says:
    May 20th, 2010 at 5:44 am

    Error 500 is an Apache internal server error. What is showing in your Apache server error logs?

  15.    Hexi Says:
    May 20th, 2010 at 10:38 am

    Great tutorial Steve!!!

    Since I’m a total newbie to FB developing, this question might sound trivial but well….

    After applying your tutorial, I used the following my code:

    $target=me;
    $ret=$facebook->api(‘/’.$target.’/friends?access_token=’.$access_token);
    …

    With this code I get the friends of the first user who approved the application and not the current user friends.

    Whats wrong with it?

  16.    Steve Says:
    May 20th, 2010 at 11:38 am

    Hexi – I’ve no idea, and I’ve no idea you could do that, and it does sound like a bug

  17.    Ivan Says:
    May 26th, 2010 at 9:59 pm

    Steve – thanks for providing this code example. It works great! Can’t tell you how much time this saved, and was superior to Facebook’s own example.php code in the php-sdk.

  18.    Steve Says:
    May 26th, 2010 at 10:36 pm

    Ivan. glad you found it useful.

  19.    Enrique Says:
    May 26th, 2010 at 11:02 pm

    Hi Steve!
    I think I’m not understanding completely.
    Is this for “internal” use only? I mean, we are saving the last valid token in our DB for personal use, it’s not associated with any user right?

  20.    Steve Says:
    May 27th, 2010 at 7:01 am

    Enrique, if you stored the wordpress user_id against the data then it would become WP user specific – which is just what I do with my wordbooker plugin.

  21.    Mile Says:
    June 2nd, 2010 at 5:56 pm

    Thank you very much for this article.

  22.    Thomas W Says:
    June 4th, 2010 at 9:57 pm

    Hi Steve! Thanks for the tutorial. I wasted hours on end, trying to post to the feed, because the attachment was being ignored. Thanks to your tutorial, I saw you added the access_token to the attachment. I don’t see any mention of that in any facebook documentation. Where in the world did you think of adding that element to the attachment object?! Now that I added it, it works. Thanks!

  23.    Steve Says:
    June 4th, 2010 at 11:45 pm

    Thomas, glad you’ve got it working. Not sure why I added it – I suspect I either found something buried somewhere deep in the mess that is the FB documentation or it was inspired guesswork on my part!

  24.    dexdex Says:
    June 7th, 2010 at 7:21 am

    wow MAN thanks for the tutorial! Thank you SO much!

  25.    Thomas W Says:
    June 9th, 2010 at 5:40 am

    Hey Steve, one last question.. Do you have any idea of how to post an action link to the attachment in the context of your tutorial? Again, thanks..

  26.    fred Says:
    June 9th, 2010 at 6:35 am

    thanks so much for your sharing! thanks!

  27.    Steve Says:
    June 9th, 2010 at 5:36 pm

    Thomas : the Graph API is actually pretty crap. Action links don’t seem to be supported. You can’t have more than one image per post. If you provide a link and no image then FB goes and basically does a “Facebook Share” on the page and pulls in an image off the page (even if you dont want one). Posting to Fan Page walls as the Page doesn’t work…. and so on and so on.

    Facebook really screwed up with this. This is why my application only uses Graph for Authentication and uses REST for everything else

    Fred : glad I could help.

  28.    Ian Says:
    June 10th, 2010 at 12:00 am

    Steve,

    So of course I decided to try programming an FB app just as hey changed there API and rendered most tutorials on the way out. Glad I found your page!

    I’m wondering what changes I’d need to make in order to authenticate and get an access token for people who are installing an app? When I tried your code on my test application page it presented me with a “connect with FB” button which I’m assuming is more for people interacting with FB on their own sites.

    Thanks for any pointers. :-)

  29.    mives Says:
    June 13th, 2010 at 8:03 am

    A question on get_check_session() function. Is there supposed to be an “else” on line 28?

  30.    mives Says:
    June 13th, 2010 at 8:03 am

    I meant line 24

  31.    mives Says:
    June 13th, 2010 at 8:25 am

    Also, a question on this part:

    if ( is_null($access_token) ) {
    echo ‘ ‘;
    }

    I’m kind of confused. With this kind of code, then it is presumed that the user(?) must be logged in on facebook to see this link, then click it. After that, what happens? Where is the user redirected? Is a callback script called after logging in that saves the session data after logging in? If I’m running a cron job, this can’t work, so I’m thinking that this would be called through cURL. Is that right?

  32.    Steve Says:
    June 13th, 2010 at 8:41 am

    Mives:

    What do you mean is there supposed to be an “else” on line 24?

    As for the is_null check. No the $loginUrl is basically a link that will log them in and then prompt for the permissions. If you’ve not set up Canvas or Connect URLs in your Facebook application then the Facebook servers do a redirect back to your page.

    If you are running in a cron job then you use this code to obtain the offline session tokens which it stores in the database and you can then use those for your cron job. Your cron job should not run any of this cide.

  33.    mives Says:
    June 13th, 2010 at 9:35 am

    I see. Regarding the access token, the one you obtain is the access token for your app right? Does this mean I don’t have to get the access token per user that authorized my app? BTW here is the code I use to get access token per user (called after user authroizes app).

    $data = array(‘type’ => ‘client_cred’,'code’ => $_GET['code'], ‘client_id’ => APP_ID,’client_secret’=>APP_SECRET,’ redirect_uri’=>’http://apps.facebook.com/myapp’);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_URL, ‘https://graph.facebook.com/oauth/access_token’);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    $rs = curl_exec($ch);
    curl_close($ch);
    $data = explode(“=”,$rs);
    $token = $data[1];

  34.    emin Says:
    June 15th, 2010 at 4:57 am

    my app id:136830172993807

    mycode
    $target=136830172993807;
    $attachment = array(
    ‘access_token’ => $access_token,
    ‘message’ => ‘Did a Test Post :’,
    error message

    atal error: Uncaught Exception: (#210) User not visible thrown in C:\Inetpub\vhosts\domain\httpdocs\vartolu\facebook.php on line 453

  35.    Steve Says:
    June 15th, 2010 at 7:30 am

    Limitation of the Facebook API – you cannot post to application walls from an application.

  36.    emin Says:
    June 15th, 2010 at 1:49 pm

    avaible publis working facebook.php for scripts.

  37.    Dhruv Says:
    June 26th, 2010 at 5:56 pm

    Hello Steve,

    Honestly this is the first tutorial which talks about PHP and Graph. Thanks a lot..

    Unfortunately I am getting Uncaught CurlException: 60: SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed thrown in src\facebook.php on line 511 ..

    Any pointers would be appreciated !

    Dhruv

    •    Steve Says:
      June 26th, 2010 at 6:06 pm

      That would look like its a Facebook SSL certificate issue which isn’t something I can do anything about.

  38.    Dhruv Says:
    June 26th, 2010 at 6:30 pm

    Hello Steve,

    Great ! Thanks for your quick response. I solved this but have this problem now

    Fatal error: Uncaught Exception: (#210) User not visible thrown in src\facebook.php on line 453 …

    and I am using

    $target=585907026; This is the ID which I get when I make https://graph.facebook.com/dhruvboruah

    I thought since i am the developer of the application this app should work !

    Really been struggling with GRAPH and confusions with same name of both the Facebook.php names . Any pointers would be appreciated !

    Thanks again !
    Dhruv

  39.    Steve Says:
    June 26th, 2010 at 6:32 pm

    Is 585907026 the ID of the APP you set up?

    If so then it wont work because FB don’t support applications posting to their own pages. I know its completely contrary but that’s Facebook for you.

  40.    Dhruv Says:
    June 26th, 2010 at 6:38 pm

    Thanks again !!!

    But no no, 585907026 is my user id, which i for making this call https://graph.facebook.com/dhruvboruah

    Kind of stuck now!!!

  41.    Steve Says:
    June 26th, 2010 at 6:41 pm

    Then it would suggest that the permissions didn’t get applied properly.

  42.    Dhruv Says:
    June 26th, 2010 at 6:47 pm

    Lastly a basic question !!! How do I apply permissions ? and where ?

    I apologize but this is crazy !

  43.    Dhruv Says:
    June 26th, 2010 at 6:57 pm

    Go it … Thanks a ton !!!

    Everything is perfect !!! Have a great weekend !!

  44.    Steve Says:
    June 26th, 2010 at 8:11 pm

    So its all working now?

  45.    Dhruv Says:
    June 26th, 2010 at 9:28 pm

    Yes, it is working. Thanks !

    This was the first step.

    I intend to authenticate a user from an iphone app and the do the posting etc on his behalf from the server itself. Now I can store his auth details and hope to play around with the same.

    Cheers,
    Dhruv

  46.    Dell Null Says:
    June 28th, 2010 at 10:03 pm

    Hello Steve,
    It works for me and it saved my many hours ;-) I just have one question. I’m developing an app that will post on the wall, almost exact like your example. The only problem is that I can’t post swedish special chars like å ä ö Å Ä Ö. They just disapears in the post. Maybe some kind of filter on facebook? Do you know how to encode those swedish chars? I’ve search all over the net but I can’t find any solution.

  47.    Steve Says:
    June 28th, 2010 at 10:06 pm

    You might need to look at your DB and PHP encoding.

    Wordbooker (my App) uses the following :

    # Database character_set_client : utf8
    # Database character_set_connection : utf8
    # Database character_set_database : utf8
    # Database character_set_filesystem : binary
    # Database character_set_results : utf8
    # Database character_set_server : utf8
    # Database character_set_system : utf8
    # Database character_sets_dir : /usr/share/mysql/charsets/
    # Database collation_connection : utf8_general_ci
    # Database collation_database : utf8_general_ci
    # Database collation_server : utf8_general_ci

    And I’ve posted Swedish and German and Malaysian test posts with no problems.

  48.    Dell Null Says:
    June 28th, 2010 at 10:35 pm

    I found the solution myself ;-) I had mixed up the to parameter and from ;-)

    This is working for me:
    $MyMessage = mb_convert_encoding($MyMessage,”utf-8″,”iso-8859-1″);

  49.    Steve Says:
    June 29th, 2010 at 7:52 am

    Be warned that some PHP installs don’t have multibyte support.

  50.    Dimitriy Says:
    June 29th, 2010 at 8:18 am

    Thanks for your sharing! Great solution! One question: is it possible to add video as attachment?

    Thanks,
    Dimitriy

1 2 Next »
  • Facebook Status


     FB photo for Stephen Atty


    Stephen Atty : Posted a new post on their blog
    (Sat May 12, 10:09 pm).

  •  

  • The Old Stuff

    • May 2012
    • October 2010
    • July 2010
    • May 2010
    • April 2010
    • February 2010
    • January 2010
    • December 2009
    • November 2009
    • October 2009
    • September 2009
    • August 2009
    • July 2009
    • June 2009
    • May 2009
    • April 2009
    • March 2009
    • February 2009
    • January 2009
    • December 2008
    • November 2008
    • October 2008
    • September 2008
    • August 2008
    • July 2008
    • June 2008
    • May 2008
    • April 2008
    • March 2008
    • February 2008
    • January 2008
    • December 2007
    • November 2007
    • October 2007
    • September 2007
    • August 2007
    • July 2007
    • June 2007
    • May 2007
    • April 2007
    • March 2007
    • February 2007
    • December 2006
    • October 2006
    • September 2006
    • August 2006
    • July 2006
    • December 2005
    • November 2005
    • August 2005
    • February 2005
    • January 2005
    • December 2004
  • Site Wide Tags


    3G 93 95 accident accounts Add new tag alcohol allergy advice alone alternator america android animal anniversary apache augusta autherley bank basketball beer Beeston benefits birmingham birthday blogging blogs boat boating Bob Geldof Boscastle boston brakes Braunston brewood BSS Bude builders C cable calendar camsigh canalplan canalplan AC car crash car park cars Cast List casualty Cats Challenger chavs cheese cheltenham Chester Christmas cinco de mayo clearsilver coast code coding cold Computing cooker CPRS crackers curry customer service dead depression diet diy dns e-commerce easter eli stone elvis email enhancement extension facebook favourites fish floods food forums Fraud fridge funding g1 gailey garage garden gas GCHQ General Options geospatial gloucester gnosall gold cup goldstone Goodies google Googlemaps granny buttons graph API grub street guinness hackers hallowell Heathrow holiday holidays home home mooring hoover hotel Importing integration intercontinental internet Internet Explorer irish Javascript jen jewellery Jill Joke json kathy kennebunk kestrel kitchen korea ladykat Last.FM latitude lawn leeching lighthouses linux ll bean lonely longitude lunch maine malvern manage routes maps market drayton maths mexican microsoft midges mintball mobile mooring mortgage MOT moving mozart MP Music mystery Nantwich national hunt netscape new domain new features new server nhs norbury npower ogunquit painting paprika party penkridge petition photos php phpbb pickle plugin Plugins poke in the eye police portland post by email pringles programming pub night pubnight pubs racing rain real ale renault Rick route importing Routes

    Donate

    If you've found anything useful on here and want to say thanks then please feel free:



    WPMUDEV

    WordPress MU, WPMU and BuddyPress plugins, themes and support at WPMU DEV

    Snapshots

    Enhanced with Snapshots
  •  


© 2012 Steve's Ramblings using Dignity theme by themebox

RSS Entries and RSS Comments.

Provided by WPMU DEV -The WordPress Experts
Hosted by Canalplan Blogs


Server uptime: 12 day(s), 7 hour(s) and 24 minute(s) | Server Load: 0.24, 0.35, 0.34
loading Cancel
Post was not sent - check your email addresses!
Email check failed, please try again
Sorry, your blog cannot share posts by email.