Since the offline_access Permission is deprecated in Facebook's Authentication flow, we have problem getting the so called long lived access tokens without that permission.
In Facebook's document about the deprecation it says, that server side OAuth generated access tokens will be long lived, but they are not.
Am I missing something? Some setting in app settings? Some special code I need to use to extend expiration time of access tokens? As I understand the documentation, for server side authentication, the access token which can be accessed by getAccessToken() method of PHP SDK when the user is logged in is long lived.
Edit (August 14th 2012):
A week ago the official Facebook PHP SDK was updated. The function name was changed to setExtendedAccessToken, and it was decided we actually needed to destroy the session afterwards, to remove the risk of having two active sessions.
Also, the function no longer actually returns the token, but instead stores it within the persistant data. You can therefore get the new access token with the public function getAccessToken afterwards. Grab the new SDK from official Facebook PHP SDK github page to make sure you're up to date.
Original Answer:
I have added a new public function to the base_facebook.php file, which returns an new access token which expires in 60 days. You can make a request to this function after you've received the normal access token. I've not tested, but I assume you also need to enable 'deprecate offline_access" in your Advanced settings of the Developer App.
Just add this to your base_facebook.php inside the facebook class and make a call to it. It works for me.
public function getExtendedAccessToken(){
try {
// need to circumvent json_decode by calling _oauthRequest
// directly, since response isn't JSON format.
$access_token_response =
$this->_oauthRequest(
$this->getUrl('graph', '/oauth/access_token'), array(
'client_id' => $this->getAppId(),
'client_secret' => $this->getAppSecret(),
'grant_type'=>'fb_exchange_token',
'fb_exchange_token'=>$this->getAccessToken()
)
);
} catch (FacebookApiException $e) {
// most likely that user very recently revoked authorization.
// In any event, we don't have an access token, so say so.
return false;
}
if (empty($access_token_response)) {
return false;
}
$response_params = array();
parse_str($access_token_response, $response_params);
if (!isset($response_params['access_token'])) {
return false;
}
return $response_params['access_token'];
}
Actually what was said:
If the access_token is generated from a server-side OAuth call, the resulting access_token will have the longer expiration time. If the call is made while there is still a valid access_token for that user, the returned access_token from this second call will remain the same and only the expiration time will be extended. Again, calling this multiple times during the same day will result only in the first call extending the expiration time.
Which means that it will be just longer than client-side generated token, and to receive extended token (60 days) you need do it manually by issuing request to:
https://graph.facebook.com/oauth/access_token?
client_id=APP_ID&
client_secret=APP_SECRET&
grant_type=fb_exchange_token&
fb_exchange_token=EXISTING_ACCESS_TOKEN
This token can still became invalid for several reasons, and how to handle this described in How-To: Handle expired access tokens blog post.
Update:
As of Aug 07, 2012 you can use setExtendedAccessToken method to extend access_token instead of manually constructing URL and retrieving details.
//using a javascript for popup for facebook login
FB.login(function(response) {
if (response.authResponse) {
var accessToken = response.authResponse.accessToken;
//got the accesstoken with 1-2 hours expire time
//got the accesstoken into a controller called facebook controller
$request = $this->getRequest();
$params = $request->getParams();
$token=$params['accessToken'];
//taking the access token to extend to 60days
$conf = $this->getConfigs();
$appid = $conf['fbdetails']['appid'];
$secret = $conf['fbdetails']['secret'];
$baseurl = $conf['app']['baseurl'];
//After the execution of below code , we will have a response with acess token expire time to 60days.
$token_url = "https://graph.facebook.com/oauth/access_token?client_id=".$appid."&client_secret=".$secret."&grant_type=fb_exchange_token&fb_exchange_token=".$token;
// Above response is given for parsing.
$c = curl_init();
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($c, CURLOPT_URL, $token_url);
$contents = curl_exec($c);
$err = curl_getinfo($c,CURLINFO_HTTP_CODE);
curl_close($c);
$paramsfb = null;
parse_str($contents, $paramsfb);
//after the parsing the contents in the above execution code the new extended accesstoken is stored.
$user_session = new Zend_Session_Namespace('fbuser');
$user_session->access_token = $paramsfb['access_token'];
//stored to session.
$this->_redirect('/home');
//Have a nice coding
An access token generated through a server-side OAuth call will be of the extended (longer) kind and you don't need to exchange it. It is already an extended token.
The only thing you must do is enable "Deprecate offline access" in your app settings. This is of course only necessary if "Deprecate offline access" was previously disabled.
Then, when you authenticate users through Facebook you will receive an access token that lives for 60 days. Authenticating multiple times during the same day will result only in the first authentication extending the expiration time.
Should you need an access token that NEVER expires for a PAGE, see my answer to a similar question here
From the developers page:
By using a long-lived user access token, querying the [User
ID]/accounts endpoint will now provide page access tokens that do not
expire for pages that a user manages.
this is for extending pages access token to expiring never, and extending the life of user access tokens expiring after 2 months(the 'new access token').
Ok so it took about a week of research but here is my solution.
in the https://developers.facebook.com/tools/explorer/ make sure that you have manage_page as part of your access_token. after that use this code with your app id, secret, and redirect:
<?php
app_id = "APP_ID";
$app_secret = "APP_SECERET";
$post_login_url = "REDIRECT_URL";
$code = $_REQUEST['code'];
//Obtain the access_token with publish_stream permission
if(empty($code)){
$dialog_url= "http://www.facebook.com/dialog/oauth?"
. "client_id=" . $app_id
. "&redirect_uri=" . urlencode( $post_login_url)
. "&COMMA_SEPARATED_LIST_OF_PERMISSION_NAMES";
echo("<script>top.location.href='" . $dialog_url
. "'</script>");
}
else {
$token_url="https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id
. "&redirect_uri=". urlencode($post_login_url)
. "&client_secret=" . $app_secret
. "&code=" . $code;
$response = file_get_contents($token_url);
$params = null;
parse_str($response, $params);
$access_token = $params['access_token'];
echo 'access token: ' . $access_token.'<br>';
if($access_token){
$token_url="https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id
. "&redirect_uri=". urlencode($post_login_url)
. "&client_secret=" . $app_secret
.'&grant_type=fb_exchange_token'
. "&fb_exchange_token=" . $access_token;
$response = file_get_contents($token_url);
$access_token = $params['access_token'];
echo 'new access token: '.$access_token;
}
}*/
?>
After that copy the 'new access token' and go back to https://developers.facebook.com/tools/explorer/ When you get there past in your new access token into the the access token field.
Then click submit. After that in the node you will see a +____ click on this and scroll down to the accounts and click that. find the page that you need the access token for and copy and paste it into the access key field. click debug and you will see that it will never expire. save that token it will stay valid as long as you do not reset your apps secret.
Inspired by previous answers, I wrote a simple token self-renewal program. First, just put your current token in the 'token.sec' file.
This program will read a token from the file, and update with a new token if everything is OK. In other programs, you just need to use the token:
$access_token = file_get_contents("token.sec");
Here we are:
<?php
$app_id = "<your app id>";
$app_secret = "<your app secret>";
$access_token = file_get_contents("token.sec");
$token_url="https://graph.facebook.com/oauth/access_token?"
. "grant_type=fb_exchange_token"
. "&client_id=" . $app_id
. "&client_secret=" . $app_secret
. "&fb_exchange_token=" . $access_token;
$ch = curl_init($token_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if($response === false) {
die ('Curl error: ' . curl_error($ch));
}
// Close handle
curl_close($ch);
// parse the output
parse_str($response, $params);
if(!isset($params['access_token'])) {
die("No access token");
}
echo ("New token: $access_token\n");
// eveything looks OK
rename("token.sec", "token.sec.back"); // just in case
$myfile = fopen("token.sec", "w") or die("Unable to open file!");
fwrite($myfile, $access_token);
fclose($myfile);
?>
Finally, we can add this in our crontab to renew the token once per momth:
0 0 1 * * cd /home/<path>; php exchangeToken.php
Related
I would like to post to my own Facebook page's wall from my website using PHP.
I have the following:
Facebook Application with AppID, AppSecret, ApiKey
Facebook Page with PageID
my own Facebook account - I'm the admin and the creator of the application and page mentioned above.
E.g. I write a blog post, and I'd like to get the name, the short description and a picture on my Facebook page's wall. Or I would like to publish some articles on the Facebook page every day automatically as a cron job.
Could you provide a step-by-step tutorial how to accomplish this?
I've read this article about Facebook Login:
https://developers.facebook.com/docs/facebook-login/
but I still don't know what to write in my code.
UPDATE 1
This is how I send a request for an App Access Token:
$url = 'https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_id='
.Yii::app()->params['FacebookAppID']
.'&client_secret='
.Yii::app()->params['FacebookSecret'];
The response is similar to this (fake symbols):
access_token=326584076429|ax3-D39YbpDcR9rMRQn_fMvNu_s
What access_token is it? Application Access Token? How to get a User Access Token?
I tried to use the access token from here:
https://developers.facebook.com/tools/explorer?method=GET&path=me%2Faccounts
but I got the following error message:
An active access token must be used to query information about the current user
So how should I obtain the right access token?
UPDATE 2:
How can I get the right Facebook tokens in my application without any client interaction?
I'm the admin and the creator of the Facebook Application and the Facebook Page.
Step by step
Authenticate a user that is a page admin (yourself)
Request an extended access token (to get a 60 day variety as offline_access is gone). See https://developers.facebook.com/docs/offline-access-deprecation/
Call Graph API me/accounts and search thru the resulting list to find the page you're interested in
Take the page access token from the page and start using that for the calls to post
It might be possible to get an extended access token for a page access token like described in step 2, please try and let us know if that can be done for page access token too.
You can experiment with the above at https://developers.facebook.com/tools/explorer
Happy Coding!
EDIT
For getting an access token without dialogs for any user, you can use https://developers.facebook.com/tools/access_token/ to get an access token.
Steps:
Request For manage_pages permission ( Allow this process ) :
https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&scope=manage_pages&response_type=token
Get Access token from URL :
If the administrator allows this permission. You should be redirected to URL below:
http://YOUR_URL/#access_token=AAABY5jBXQz0BAEzNKkb6FZC22D7aOoKIfFuozIjoOpkGHRJ6SyzBvqx24JGooMc31374EdRFNXkOyLZCBzETRD9vhZAZC8MZD&expires_in=0
Use Access token in the URL and you should get this:
AAABY5jBXQz0BAEzNKkb6FZC22D7aOoKIfFuozIjoOpkGHRJ6SyzBvqx24JGooMc31374EdRFNXkOyLZCBzETRD9vhZAZC8MZD
Check Access token using Graph API:
https://graph.facebook.com/me/accounts?access_token=TOKEN_FROM_ABOVE
Connection will return information and access token for each page.
Implement it in your code:
You can use App access token while call a Facebook Graph API method.
Update:
If you want use API method in Facebook SDK, DEPRECATED REST API or FQL Query...
You have to use users_accesstoken this way:
Method 1:
Use your account or users to login to your Facebook page with offline_access permissions and grab access_token while login success using $facebook->getAccessToken(), and save it in database so you can use it anytime.
You can check the expiration time of the token here, token with offline_access permissions never expire except when the user changes his password or maybe anything else.
Method 2:
You can update your access_token dynamically using the code below (say goodbye to expire token). Facebook shows this solution here, it's a sample code for executing an FQL Query:
Code:
<?php
$app_id = 'YOUR_APP_ID';
$app_secret = 'YOUR_APP_SECRET';
$my_url = 'POST_AUTH_URL';
$code = $_REQUEST["code"];
//auth user
if(empty($code)) {
$dialog_url = 'https://www.facebook.com/dialog/oauth?client_id='
. $app_id . '&redirect_uri=' . urlencode($my_url) ;
echo("<script>top.location.href='" . $dialog_url . "'</script>");
}
//get user access_token
$token_url = 'https://graph.facebook.com/oauth/access_token?client_id='
. $app_id . '&redirect_uri=' . urlencode($my_url)
. '&client_secret=' . $app_secret
. '&code=' . $code;
$access_token = file_get_contents($token_url);
Try this simple function to post onto a wall:
function doWallPost($postName = '', $postMessage = '', $postLink = '', $postCaption = '', $postDescription = '') {
$FB_APP_ID = 'xxxxxxxxxxxxxxxxxxxxxxxx';
$FB_APP_SECRET = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx';
$APP_RETURN_URL = ((substr($_SERVER['SERVER_PROTOCOL'], 0, 4) == "HTTP") ? "http://" : "https://") . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'];
$code = $_REQUEST["code"];
if (empty($code)) {
$dialog_url = "http://www.facebook.com/dialog/oauth?client_id=" . $FB_APP_ID . "&redirect_uri=" . $APP_RETURN_URL . "&scope=publish_stream";
header("Location:$dialog_url");
}
$token_url = "https://graph.facebook.com/oauth/access_token?client_id=" . $FB_APP_ID . "&redirect_uri=" . urlencode($APP_RETURN_URL) . "&client_secret=" . $FB_APP_SECRET . "&code=" . $code;
$access_token = file_get_contents($token_url);
$param1 = explode("&", $access_token);
$param2 = explode("=", $param1[0]);
$FB_ACCESS_TOKEN = $param2[1];
$url = "https://graph.facebook.com/me/feed";
$attachment = array(
'access_token' => $FB_ACCESS_TOKEN,
'name' => $postName,
'link' => $postLink,
'description' => $postDescription,
'message' => $postMessage,
'caption' => $postCaption
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $attachment);
$result = curl_exec($ch);
header('Content-type:text/html');
curl_close($ch);
return $result;
}
I'm using the Facebook PHP SDK to call relevant APIs to post and get data. At present I'm saving a user access token in the database but it expires after 60 days. How can I refresh a user access token?
1 . When do I need to refresh the access tokens? After it expires, or before?
2 . What is the best way to refresh access tokens?
3 . Should my users need to login again to refresh access token?
This is the function that I'm using to extend the access token. but expire time remain same.
public function getExtendedAccessToken($access_token)
{
$token_url="https://graph.facebook.com/oauth/access_token";
$params=array('client_id'=>self :: appId,'client_secret'=>self :: appSecretId,'grant_type'=>'fb_exchange_token','fb_exchange_token'=>$access_token);
$response = $this->curl($token_url,$params);
$response = explode ('=',$response);
$response = explode ('&',$response[1]);
$response = $response[0];
return $response;
}
The access token can't be refreshed just like that, the user should access the app again to get the new token.
You can refresh the token at anytime you wish. In fact, the best way is to refresh the token each time the user visits your app. In this way, the token will never be expired if the user keep visiting the app once in 60 days.
Try this:
$app_id = FB_APP_ID;
$app_secret = FB_SECRET_ID;
$canvas_URL = FB_PAGE_URL;
$code = $_REQUEST["code"];
if(empty($code)) {
$_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection
$dialog_url = "https://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . $canvas_URL . "&state="
. $_SESSION['state'];
echo("<script> top.location.href='" . $dialog_url . "'</script>");
}
if($_REQUEST['state'] == $_SESSION['state']) {
$facebook->api('oauth/access_token', array(
'client_id' => FB_APP_ID,
'client_secret' => FB_SECRET_ID,
'type' => 'client_cred',
'code' => $code,
));
$token = $facebook->getAccessToken();
echo$token;
}
public function getExtendedAccessToken($access_token)
{
$token_url="https://graph.facebook.com/oauth/access_token";
$params=array('client_id'=>self :: appId,'client_secret'=>self :: appSecretId,'grant_type'=>'fb_exchange_token','fb_exchange_token'=>$access_token);
$response = $this->curl($token_url,$params);
$response = explode ('=',$response);
$response = explode ('&',$response[1]);
$response = $response[0];
return $response;
}
I am using the following code to post to my facebook fan page and it is working fine. Now I want to use cronjob in order to post to Facebook. I know I have to use as access token but I am not sure how to set it up. I tried to use echo my own access token and the page's access token and use it in the post api but that did not work I got this error:
Uncaught OAuthException: An active access token must be used to query information about the current user.
Here is my code that I tried:
require_once('scripts/facebook.php');
$config = array('appId' => 'xxx','secret' => 'xxx');
$params = array('scope'=>'user_likes,publish_actions,email,offline_access,publish_stream,manage_pages');
$facebook = new Facebook($config);
$user = $facebook->getUser();
if($facebook->getUser()) {
try {
$user_profile = $facebook->api('/me');
$access_token = $facebook->getAccessToken();
//echo "1. ".$access_token;
} catch(FacebookApiException $e) {
$login_url = $facebook->getLoginUrl($params);
error_log($e->getType());
error_log($e->getMessage());
}
} else {
$login_url = $facebook->getLoginUrl($params);
}
$page_id = "xxxxxxxxxxxxx";
$page_access_token = "";
$result = $facebook->api("/me/accounts");
foreach($result["data"] as $page) {
if($page["id"] == $page_id) {
$page_access_token = $page["access_token"];
//echo '<br>';
//echo "2. ".$page_access_token;
break;
}
}
$args = array(
'access_token' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'message' => stripslashes($image_caption).$animaged_gif,
'name' => stripslashes($image_caption).$animaged_gif,
'link' => "http://www.example.com/images.php?i=".$image_name,
'picture' => "http://www.example.com/thumbnails/".$image_name.".png",
'actions' => array(
'name' => 'See Pic',
'link' => "http://www.example.com/images.php?i=".$image_name
)
);
$post = $facebook->api("/$page_id/feed","post",$args);
As you can see that I tried to use the actual access token that I got when I echo out my own access token. But that did not work. I also used the page's access token, but that also did not work. Can you please tell what I am missing here or what is the proper way to do this ?
After some further search I did, I came across setAccessToken and $page_info = $fb->api("/".$sInfo['pageId']."?fields=access_token"); but there is very limited resources on how to use them. I am not even sure if those will be appropriate to this problem. All I need to know is which access token I need to use and what is the appropriate code to set it up ?
This is how you can do it :
Get a short lived accesstoken.
Extend it.
Get a long lived page accesstoken. (Doesn't matter, here we are going to fetch new accesstoken every time. Less complicated, and reliable.)
Thought I would go with an algo, instead I am adding all the possible codes and documentations since this may help someone else too.
Getting short lived access token and extending it:
fetchtoken.php
<?php
//read more : https://developers.facebook.com/docs/howtos/login/server-side-login/
session_start();
$app_id = "xxxxxxxxxxxxxx";
$app_secret = "xxxxxxxxxxxxxxxx";
$my_url = "www.stackoverflow.com/"; // redirect url
$code = $_REQUEST["code"];
if(empty($code)) {
// Redirect to Login Dialog
$_SESSION['state'] = md5(uniqid(rand(), TRUE)); // CSRF protection
$dialog_url = "https://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($my_url) . "&state="
. $_SESSION['state'] . "&scope=publish_stream,read_friendlists,email";
echo("<script> top.location.href='" . $dialog_url . "'</script>");
}
if($_SESSION['state'] && ($_SESSION['state'] === $_REQUEST['state'])) {
$token_url = "https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url)
. "&client_secret=" . $app_secret . "&code=" . $code;
$response = file_get_contents($token_url);
$params = null;
parse_str($response, $params);
$longtoken=$params['access_token'];
//save it to database
}
?>
So you now have a long lived accesstoken ready in your database, a text file or whatever.
cronjob.php
<?
require_once('scripts/facebook.php');
// Pull access token from the file/db
$access_token = "access token from file or db";
$facebook->setAccessToken($access_token); // sets our access token as the access token when we call something using the SDK, which we are going to do now.
$config = array('appId' => 'xxx','secret' => 'xxx');
$params = array('scope'=>'user_likes,publish_actions,email,publish_stream,manage_pages');
$facebook = new Facebook($config);
$user = $facebook->getUser();
if($facebook->getUser()) {
try {
$user_profile = $facebook->api('/me');
} catch(FacebookApiException $e) {
$login_url = $facebook->getLoginUrl($params);
error_log($e->getType());
error_log($e->getMessage());
}
}
else {
$login_url = $facebook->getLoginUrl($params);
}
$page_id = "xxxxxxxxxxxxx";
$page_access_token = "";
$result = $facebook->api("/me/accounts");
foreach($result["data"] as $page) {
if($page["id"] == $page_id) {
$page_access_token = $page["access_token"];
//echo '<br>';
//echo "2. ".$page_access_token;
break;
}
}
$args = array(
'access_token' => $page_access_token,
'message' => stripslashes($image_caption).$animaged_gif,
'name' => stripslashes($image_caption).$animaged_gif,
'link' => "http://www.example.com/images.php?i=".$image_name,
'picture' => "http://www.example.com/thumbnails/".$image_name.".png",
'actions' => array(
'name' => 'See Pic',
'link' => "http://www.example.com/images.php?i=".$image_name
)
);
$post = $facebook->api("/$page_id/feed","post",$args);
?>
Make sure you don't grab access_token(user access token / $access_token) again in the script.
Also, the access_token in $args which is the page access token should be inserted by the $page_access_token variable, and not manually.
Having offline_access in the scope does nothing than showing them on the permission dialogue box that their data can be accessed any time which can be done without that notification anyway.
This should work as long as you visit the fetch.php once at the start, and once every 60 days manually.
Let me know.
This should probably fix it.
offline_access is deprecated. It is now being replaced by a system where you get an extended expiry access_token.
When you run it manually, You generate a live access token, which is invalid after 1-2 hours after you acutally run it. And there is no way you can generate another access_token with a cron. Generating access token should be done manually.
So to fix it, have a read : https://developers.facebook.com/roadmap/offline-access-removal/
and implement this : https://developers.facebook.com/docs/howtos/login/server-side-login/
And save the Access token to your database. When you run the cron, get the token from your database.
P.S : The access_token is valid for 60 days, and it should be extended again and can be done by the user logging in manually. The access_token generally "may" not change but just gets the expiry extended.
ADD :
Scheduling Posts :
You can also schedule the post for upto 6 months too. Just read about it and thought I would point out.
Read : https://developers.facebook.com/docs/reference/api/page/ scroll down to Posts Create sections
You can scrap the entire overhead of the Facebook API and follow this extremely simple approach.
Check what your page-specific email address is in the "Mobile" section of your page settings (https://www.facebook.com/pages/edit/?id=INSERT_YOUR_PAGE_ID_HERE&sk=mobile) and then use it here:
<?php
mail("thatEmailAddress#facebook.com", "New Status Update!", "");
?>
The body is empty because Facebook says "to update your status, write in the email subject line and leave the email body blank."
You can take a look here https://github.com/newbacknew/owloo.com. This is a base of scripts from owloo.com for get data from Facebook via the "ADS" Dashboard, also have to retrive analytics data from Twitter and Instagram.
With the base script you can get trends, interests, behavior, demographic, ages, gender qty of every country, city, stage, fanpage from facebook
The base of all script are in the WSERVICE folder of the backups folders.
I would like to post to my own Facebook page's wall from my website using PHP.
I have the following:
Facebook Application with AppID, AppSecret, ApiKey
Facebook Page with PageID
my own Facebook account - I'm the admin and the creator of the application and page mentioned above.
E.g. I write a blog post, and I'd like to get the name, the short description and a picture on my Facebook page's wall. Or I would like to publish some articles on the Facebook page every day automatically as a cron job.
Could you provide a step-by-step tutorial how to accomplish this?
I've read this article about Facebook Login:
https://developers.facebook.com/docs/facebook-login/
but I still don't know what to write in my code.
UPDATE 1
This is how I send a request for an App Access Token:
$url = 'https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_id='
.Yii::app()->params['FacebookAppID']
.'&client_secret='
.Yii::app()->params['FacebookSecret'];
The response is similar to this (fake symbols):
access_token=326584076429|ax3-D39YbpDcR9rMRQn_fMvNu_s
What access_token is it? Application Access Token? How to get a User Access Token?
I tried to use the access token from here:
https://developers.facebook.com/tools/explorer?method=GET&path=me%2Faccounts
but I got the following error message:
An active access token must be used to query information about the current user
So how should I obtain the right access token?
UPDATE 2:
How can I get the right Facebook tokens in my application without any client interaction?
I'm the admin and the creator of the Facebook Application and the Facebook Page.
Step by step
Authenticate a user that is a page admin (yourself)
Request an extended access token (to get a 60 day variety as offline_access is gone). See https://developers.facebook.com/docs/offline-access-deprecation/
Call Graph API me/accounts and search thru the resulting list to find the page you're interested in
Take the page access token from the page and start using that for the calls to post
It might be possible to get an extended access token for a page access token like described in step 2, please try and let us know if that can be done for page access token too.
You can experiment with the above at https://developers.facebook.com/tools/explorer
Happy Coding!
EDIT
For getting an access token without dialogs for any user, you can use https://developers.facebook.com/tools/access_token/ to get an access token.
Steps:
Request For manage_pages permission ( Allow this process ) :
https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&scope=manage_pages&response_type=token
Get Access token from URL :
If the administrator allows this permission. You should be redirected to URL below:
http://YOUR_URL/#access_token=AAABY5jBXQz0BAEzNKkb6FZC22D7aOoKIfFuozIjoOpkGHRJ6SyzBvqx24JGooMc31374EdRFNXkOyLZCBzETRD9vhZAZC8MZD&expires_in=0
Use Access token in the URL and you should get this:
AAABY5jBXQz0BAEzNKkb6FZC22D7aOoKIfFuozIjoOpkGHRJ6SyzBvqx24JGooMc31374EdRFNXkOyLZCBzETRD9vhZAZC8MZD
Check Access token using Graph API:
https://graph.facebook.com/me/accounts?access_token=TOKEN_FROM_ABOVE
Connection will return information and access token for each page.
Implement it in your code:
You can use App access token while call a Facebook Graph API method.
Update:
If you want use API method in Facebook SDK, DEPRECATED REST API or FQL Query...
You have to use users_accesstoken this way:
Method 1:
Use your account or users to login to your Facebook page with offline_access permissions and grab access_token while login success using $facebook->getAccessToken(), and save it in database so you can use it anytime.
You can check the expiration time of the token here, token with offline_access permissions never expire except when the user changes his password or maybe anything else.
Method 2:
You can update your access_token dynamically using the code below (say goodbye to expire token). Facebook shows this solution here, it's a sample code for executing an FQL Query:
Code:
<?php
$app_id = 'YOUR_APP_ID';
$app_secret = 'YOUR_APP_SECRET';
$my_url = 'POST_AUTH_URL';
$code = $_REQUEST["code"];
//auth user
if(empty($code)) {
$dialog_url = 'https://www.facebook.com/dialog/oauth?client_id='
. $app_id . '&redirect_uri=' . urlencode($my_url) ;
echo("<script>top.location.href='" . $dialog_url . "'</script>");
}
//get user access_token
$token_url = 'https://graph.facebook.com/oauth/access_token?client_id='
. $app_id . '&redirect_uri=' . urlencode($my_url)
. '&client_secret=' . $app_secret
. '&code=' . $code;
$access_token = file_get_contents($token_url);
Try this simple function to post onto a wall:
function doWallPost($postName = '', $postMessage = '', $postLink = '', $postCaption = '', $postDescription = '') {
$FB_APP_ID = 'xxxxxxxxxxxxxxxxxxxxxxxx';
$FB_APP_SECRET = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx';
$APP_RETURN_URL = ((substr($_SERVER['SERVER_PROTOCOL'], 0, 4) == "HTTP") ? "http://" : "https://") . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'];
$code = $_REQUEST["code"];
if (empty($code)) {
$dialog_url = "http://www.facebook.com/dialog/oauth?client_id=" . $FB_APP_ID . "&redirect_uri=" . $APP_RETURN_URL . "&scope=publish_stream";
header("Location:$dialog_url");
}
$token_url = "https://graph.facebook.com/oauth/access_token?client_id=" . $FB_APP_ID . "&redirect_uri=" . urlencode($APP_RETURN_URL) . "&client_secret=" . $FB_APP_SECRET . "&code=" . $code;
$access_token = file_get_contents($token_url);
$param1 = explode("&", $access_token);
$param2 = explode("=", $param1[0]);
$FB_ACCESS_TOKEN = $param2[1];
$url = "https://graph.facebook.com/me/feed";
$attachment = array(
'access_token' => $FB_ACCESS_TOKEN,
'name' => $postName,
'link' => $postLink,
'description' => $postDescription,
'message' => $postMessage,
'caption' => $postCaption
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $attachment);
$result = curl_exec($ch);
header('Content-type:text/html');
curl_close($ch);
return $result;
}
i have a problem with my facebook canvas app that is currently on development i'm working on http://localhost:8080
my canvas url is http://localhost:8080/fbcanvas/
on facebook the url is set to http://apps.facebook.com/app_name/
the problem is i'm getting a code as an $_GET['code'] variable after a user approves my app.
in facebook documentation it doesnt say anything about getting a $_GET['code'] it just says getting signed_request
this is the code i'm using from facebook examples.
require_once($_SERVER['DOCUMENT_ROOT'] . '/classes/Page.php');
require($_SERVER['DOCUMENT_ROOT'] . '/core/config.fb.php');
$canvas_page = 'http://apps.facebook.com/khawamusic/';
$auth_url = 'https://www.facebook.com/dialog/oauth?client_id=' . $app_id . '&redirect_uri=' . urlencode($canvas_page);
$signed_request = $_REQUEST['signed_request'];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
if(empty($data['user_id'])) {
echo('<script> top.location.href="' . $auth_url .'";</script>');
} else {
$page = new Page;
$styles = array('reset.css', 'fbcanvas.css');
$scripts = array(
'https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js',
'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js',
'http://connect.facebook.net/en_US/all.js#xfbml=1',
'/sources/js/fbcanvas.js'
);
$page->set_title('Khawa');
$page->set_styles($styles);
$page->set_scripts($scripts);
$page->start_page();
require($_SERVER['DOCUMENT_ROOT'] . '/fbcanvas/fb.tpl');
$page->end_page();
}
so what happens is a user approves my app then he gets redirected to http://apps.facebook.com/khawamusic/?code=blabla
i'm cnfused because in the documentation it doesn't say i'm suppose to get a $_GET['code']
If the user presses Allow, your app is authorized. The OAuth Dialog will redirect (via HTTP 302) the user's browser to the URL you passed in the redirect_uri parameter with an authorization code:
http://YOUR_URL?code=A_CODE_GENERATED_BY_SERVER
With this code in hand, you can proceed to the next step, app authentication, to gain the access token you need to make API calls.
Refer: https://developers.facebook.com/docs/authentication/
EDIT:
Here's a sample of the authentication, this won't show ?code=Blabla..
First download the latest Facebook PHP SDK from here: https://github.com/facebook/php-sdk/tree/master/src
Make sure you save all 3 files, facebook.php, base_facebook.php and fb_ca_chain_bundle.crt
Now replace the text "YOUR_APP_ID" and ""YOUR_APP_API_SECRET" with your Application ID and App Secret from facebook, I've added sample wall posting using graph api, if you don't want, you can remove it, if you go through my codes and comments, you'll understand what it does and you don't want to do anything to get access token, just use $access_token variable and it'll give you the access_token of the current user and if you want the user's ID then use $user variable, if you want user's basic information, use $userInfo variable and it'll fetch user's data using graph api and returns all information in an array, you'll get the current user's info like id,name,first_name,last_name,link,hometown,location,bio,work,education,gender,timezone.etc.
Change $RedirectUrl with your landing page URL or your canvas page url
<?php
require 'facebook.php';
define('FACEBOOK_APP_ID', "YOUR_APP_ID"); // Your App ID
define('FACEBOOK_SECRET', "YOUR_APP_API_SECRET"); // Your App API Secret
$RedirectUrl = "http://apps.facebook.com/myapp/"; // Your Landing Page URL, User's will be redirect to this URL after they allow your app.
function d($d){
echo "<pre>";
print_r($d);
echo "</pre>";
}
$user = null;
$facebook = new Facebook(array(
'appId' => FACEBOOK_APP_ID,
'secret' => FACEBOOK_SECRET,
'cookie' => true,
));
$user = $facebook->getUser(); // Get the UID of the connected user, or 0 if the Facebook user is not connected.
if(isset($_GET['code'])){
header("Location: $RedirectUrl");
}
if($user == 0) {
// If User is not connected to your app, then redirect User to Authentication Page.
/**
* Get a Login URL for use with redirects. By default, full page redirect is
* assumed. If you are using the generated URL with a window.open() call in
* JavaScript, you can pass in display=popup as part of the $params.
*
* The parameters:
* - redirect_uri: the url to go to after a successful login
* - scope: comma separated list of requested extended perms
*/
$login_url = $facebook->getLoginUrl($params = array('scope' => "publish_stream", 'redirect_uri' => $RedirectUrl));
echo("<script> top.location.href='" . $login_url . "'</script>");
} else {
// If User is connected to your app, then do something.
$signed_request = $facebook->getSignedRequest(); // Get the data from a signed_request token.
$access_token = $facebook->getAccessToken(); // Determines the access token that should be used for API calls.
$userInfo = $facebook->api("/me"); // Get's User Info
try {
// Posts to user's wall after the user allows your app.
$wallpost = array(
'message' => "I like this",
'link' => 'http://google.com',
'picture' => 'http://i.imgur.com/8iz6L.png',
'name' => 'This is cool',
'description'=> 'Checkout this cool app'
);
$publishStream = $facebook->api("/$user/feed", "post", $wallpost); // WallPost to User's Wall using Graph API
echo "Your post was successfully posted to UID: $user";
}
catch (FacebookApiException $e) {
d($e);
}
}
?>
i'm not yet sure but i think i have the answer to the process of authorizing / authenticating a facebook app...
step 1 : the first time a user access your app facebook sends you a signed request and you need to parse it validate it and check if the $data['user_id'] is set.
the code:
$data = $canvas->parse_signed_request($signed_request);
$auth_url = 'http://www.facebook.com/dialog/oauth?client_id=' . $app_id . '&redirect_uri=' . urlencode($canvas_page);
if(empty($data['user_id'])) {
echo '<script>top.location.href="' . $auth_url . '"</script>';
}
so if the $data['user_id'] is empty go authenticate.
step 2: the user authorizes your app facebook sends you a signed request and a code
if(isset($_REQUEST['code'])) {
$access_token = $canvas->get_access_token($_REQUEST['code']);
$user = $canvas->getUser($access_token);
$user_info = array(
'user_id' => $user->id,
'user_username' => $user->username,
'user_name' => $user->name
);
// install the application for the new user.
$user_obj = new User($user_info);
// registered or allready exists.
if($user_obj) {
echo '<script>top.location.href="' . $canvas->canvas_page . '";</script>';
}
exit();
}
so from what i understood facebook sends you $_REQUEST['code'] just one time: when the user approves your canvas application.
that's it the user is installed so now every time a user re enters your application you will get a signed_request
but this time because the user already approves the application the signed request will include an user_id and oauth_token with it u can get stuff from the graph api.
IF THE SIGNED_REQUEST HAVE A USER_ID THIS IS WHAT U DO.
if(isset($data['user_id'])) {
$user = false;
if(!$user) {
$user = $canvas->getUser($data['oauth_token']);
}
if(!ob_start('ob_gzhandler')) ob_start();
$styles = array(
'reset.css', 'jplayer.fbcanvas.css', 'fbcanvas.css'
);
$scripts = array(
'http://connect.facebook.net/en_US/all.js#xfbml=1',
'http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js',
'/sources/js/jplayer/jquery.transform.js',
'/sources/js/jplayer/jquery.grab.js',
'/sources/js/jplayer/jquery.jplayer.js',
'/sources/js/jplayer/mod.csstransforms.min.js',
'/sources/js/jplayer/circle.player.js',
'/sources/js/fbcanvas.js'
);
$results = $canvas->getLatestSongs();
// the canvas.
$page->set_title('Khawa');
$page->set_styles($styles);
$page->set_scripts($scripts);
$page->start_page();
require($_SERVER['DOCUMENT_ROOT'] . '/fbcanvas/fb.tpl');
$page->end_page();
ob_end_flush();
}
again i'm not sure but i think this is the process of authentication for FACEBOOK CANVAS APPS.