Using the new Facebook Graph API off-line
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:
So there you go. Why not download the code and give it a go.

June 29th, 2010 at 8:19 am
You need to ask over in the FB Developers forums about that.
July 6th, 2010 at 9:05 am
Great piece of code, I have been searching for something like this since the REST API seems to be on its way out.
Thanks for the share,
July 6th, 2010 at 8:19 pm
Seb – the old REST API will be around for a while I suspect but I think that any new features will only be available through the GRAPH API.
I’m going to do a major upgrade on my plugin using REST and once its stable I’ll start moving functions over to the GRAPH API which by then might be feature rich, mature, well documented and not the bug ridden mess it is at the moment.
July 11th, 2010 at 8:03 pm
Thanks Steve,
You saved me who knows how long trying to figure out how to use an existing access_token (received via a mobile app) to make calls on the server……
Dominic
iPhone, Facebook, oAuth 2.0 and the Graph API. A Tutorial, Part 2.
July 18th, 2010 at 8:54 am
Great Stuff!
Thanks for the post.
Baja
July 18th, 2010 at 11:13 pm
Great post, really helpful with everything in one place.
Thanks!!!
July 20th, 2010 at 8:29 am
It is a great post. All things are tied up together. Thank you very much. Carry on !!
July 30th, 2010 at 8:27 am
Steve,
I want to use Oauth to get the facebook user name and email address for my website registration.
I did a test on myself and submitted the authorize url. Clicked allow. Got the url code…requested the oauth token and then got the json with the info.
My question is this. Is there any server side script you know of that can parse the info and add it to mysql database.
I know just enough php to get me in trouble and haven’t learned any javascript.
I love the idea of a single click registration and hope to get this figured out.
Can you point me in the right direction?
Thank you in advance for any help you can provide.
Phil
July 30th, 2010 at 2:37 pm
I think you’d have to write your own – just like I did to handle all the data that I pull back for my Status Cache code. Also you might need to check that FB dont mind you basically using them as a Authentication service.
August 5th, 2010 at 8:18 pm
Hello Steve,
I want to issue extended permission in order to publish data on particular facebook profile. To do so I use following code snip for that.
Code:
$par= “publish_stream, offline_access, user_status, read_stream, email”;
$loginUrl = $facebook->getLoginUrl(array(‘req_perms’ => $par));
Everytime I request I got following error.
API Error Code: 100
API Error Description: Invalid parameter
Error Message: Invalid permission: email>
Can you please suggest?
Thanks,
Mitz P
August 5th, 2010 at 9:22 pm
All I can suggest is taking it up in the Facebook developer forums.
August 6th, 2010 at 9:03 am
Hello Steve,
Thanks for your reply.
I have posted on http://forum.developers.facebook.com/viewtopic.php?pid=255013 before posting to you!
Let me know if you can help me out in this.
Thanks for sharing your code with us .. Its really helpful to understand.
Thanks,
Mitul P.
August 6th, 2010 at 4:16 pm
I’ve replied on there – your code has a => where it shouldn’t have!
August 9th, 2010 at 12:32 pm
Thanks
August 10th, 2010 at 3:57 pm
Hello Steve,
I am facing an issue with Event ID. Can you help/suggest me in that matter if possible please.
You can see post at http://forum.developers.facebook.com/viewtopic.php?id=69537.
Hope to get support from you!
Thanks,
Mitul P.
August 10th, 2010 at 4:07 pm
I’ve never used event_IDs because its not really something related to my plugin. But looking at your problem it looks like it might be a FB bug – but I’d suggest posting your code over on that thread so people can see exactly what you are doing
August 10th, 2010 at 6:10 pm
Hello Steve,
Thank you for your prompt response. I have posted and reported bug on facebook as well.
Thanks,
Mitul P.
August 11th, 2010 at 10:30 pm
Got the code up but I keep getting this error.
Parse error: syntax error, unexpected T_VARIABLE, expecting ‘,’ or ‘;’ in /home/chatdivi/public_html/domain/index.php on line 86
August 12th, 2010 at 6:45 am
Have you forgotten to fill in the target id:
# Dont forget to populate the target ID
$target=;
August 20th, 2010 at 11:12 am
Steve, you’re nothing less than a blessing in disguise. I just can’t thank you enough!! This saved me SO much time!! I’ll get you a beer someday,definitely
August 20th, 2010 at 2:17 pm
1)Now, who ever (even if they haven’t authorized) visits my application’s page, the post is published only on the first registered user’s wall ?
2)How do I automate this entire process of offline publishing? Using Cron?
Thank you
August 20th, 2010 at 3:26 pm
1)This code posts to the target wall using a stored session. That is all it is supposed to do. It exists purely as a proof of concept for other users to take and modify to their own ends. So if anyone visits it and there is a stored session then it will post to the wall belonging to that stored session
2) How you do it is up to do. As I stated – this is purely proof of concept code, it is not a complete solution. There are lots of different ways you can automate it – you need to find the method that is best for you.
August 20th, 2010 at 8:24 pm
this is exactly what i have been looking for. thank you so much
August 20th, 2010 at 8:27 pm
Ok, Thank You Steve..I’m still grateful to you for having provided us with working Facebook code. Have a gr8 day.
September 1st, 2010 at 6:42 am
Well, I just wanted to thank you for posting a working example. For some strange reason, when I tried to submit my comment, I got the following warning. I am not cheating! No..
Cheating huh
Protected by: AVH First Defense Against Spam
http://blogs.canalplan.org.uk/quizzical.php
September 1st, 2010 at 9:19 pm
For some reason the nonce check was failing – so it thought you were trying to bypass the anti-spam system.