Until few months ago I was using this method to get the user's facebook profile picture and was working fine.
public function getUserProfilePic(){
$access_token = $this->facebook_obj->getAccessToken();
$user_id = $this->facebook_obj->getUser();
$response = $this->facebook_obj->api(
"/me/picture",
"GET",
array (
'redirect' => false,
'type' => 'large'
)
);
return (!empty($response['data']['url'])) ? $response['data']['url'] : 'images/default_profile.jpg';
}
But since the new PHP SDK I have some problems with this method. If I afk for 5 minutes on the main menu on my app and than go on the click to go the page where it calls this method I get
"OAuthException : An active access token must be used to query information about the current user" error.
Any thoughts?
Nothing to do with new/old SDK I guess. The user is logged-out, or access token is expired or your handling of the user in session is flawed.
This error is occurred whenever you try to make calls with /me but no user is logged-in to the app.
So, before making the calls, you should always validate the current user and then proceed, something like that-
$user_id = $this->facebook_obj->getUser();
if ($user_id) {
try {
$response = $this->facebook_obj->api(
"/me/picture",
"GET",
array (
'redirect' => false,
'type' => 'large'
)
);
} catch (FacebookApiException $e) {
error_log($e);
}
}else {
// redirect to Facebook login to get a fresh user access_token
$loginUrl = $this->facebook_obj->getLoginUrl();
header('Location: ' . $loginUrl);
}
Edit:
You dont need to do redirect: false and fetching the url from the json. You can directly use the url as the image source:
https://graph.facebook.com/{user-id}/picture?type=large
That's it!
Related
I am developing an app to post multiple post messages in one time. Say I have 5 fan pages and 10 groups. It will post them all. I have used graph api method and its working well when using for loop and executing one at a time. But I came to know about facebook batch request. Now the problem is when I to fan pages using fan page access token from (https://graph.facebook.com/100000598120816/accounts) its working fine
$param = array( 'message' => "Demo test " , 'access_token' => "<fan page access token>");
try {
$posted = $facebook->api('/425355934226513/feed/', 'post', $param);
if (strlen($posted["id"]) > 0 ) $success = TRUE;
} catch (FacebookApiException $e) {
$errMsg = $e->getMessage();
$error = TRUE;
}
But when I try to do the same using batch request, It post as the USER, not as PAGE ADMIN.
$arr1[] = array( "method"=>"POST", 'relative_url' => '<fan page id>/feed',"body" => "message=Apps testing..Please ignore this message for page." , 'access_token' => "<FAN PAGE TOKEN>");
$arr1[] = array( "method"=>"POST", 'relative_url' => '<my group id>/feed',"body" => "message=Apps testing..Please ignore this message for page." , 'access_token' => "<USER PAGE TOKEN>");
try {
$posted = $facebook->api("/?batch=".urlencode(json_encode($arr1)), 'post');
$success = TRUE;
} catch (FacebookApiException $e) {
$errMsg = $e->getMessage();
$error = TRUE;
}
P.S Both the above code runs successfully. But in fan page its showing as the USER not PAGE ADMIN.
Thanks in Advance.
I'm pretty sure that only Users can post to groups, not Pages. It works that way even manually posting to groups.
You should try specifying a "fallback" Access Token as described in https://developers.facebook.com/docs/graph-api/making-multiple-requests/#differentaccesstokens This Access Token should be an App Access Token.
Also, I'm not sure if you're not overwriting your $arr1[] variable...
try 'relative_url' => '/feed?access_token=' and the same for the group/user token.
There is a bug that doesn't look for the access_token in the json, even though the documentation states it is allowed.
Documentation says:
"redirect_uri - (optional) The URL to redirect the user to once the login/authorization process is complete. The user will be redirected to the URL on both login success and failure, so you must check the error parameters in the URL as described in the authentication documentation. If this property is not specified, the user will be redirected to the current URL (i.e. the URL of the page where this method was called, typically the current URL in the user's browser)."
So there is a method to catch if user refused autnentication/permissions, but link to corresponding documentation doesnt exist anymore (https://developers.facebook.com/docs/authentication/).
For the simplicity, redirect_uri is same address as a starting php file, and the php code is as simple as:
require 'facebook.php';
$facebook = new Facebook(array(
'appId' => 'X',
'secret' => 'Y',
));
$user = $facebook->getUser();
if ($user) {
try {
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
}
if (!$user) {
$params = array(
'scope' => 'read_stream, friends_likes',
'redirect_uri' => 'http://myapp.com/app'
);
$loginUrl = $facebook->getLoginUrl($params);
}
Anybody knows how to catch that information?
You can do following to check the permissions:
$permissions = $facebook->api("/me/permissions");
if( array_key_exists('publish_stream', $permissions['data'][0]) ) {
// Permission is granted!
// Do the related task
$post_id = $facebook->api('/me/feed', 'post', array('message'=>'Hello World!'));
} else {
// We don't have the permission
// Alert the user or ask for the permission!
header( "Location: " . $facebook->getLoginUrl(array("scope" => "publish_stream")) );
}
It should be noted that in the newest PHP facebook SDK, there is no method ->api. There also seems to be an issue using this check (sometimes) to get permissions. When using the older SDK, sometimes (randomly by user it seemed) some users were getting "OAuthException: (#412) User has not installed the application" even though a check on the FB access token debugger showed proper permissions. After I updated to new SDK, and figured out the new way to get a simple data list of permissions, everything worked again.
It took me a lot of digging in the FB website to find this solution, so I paste it here to hopefully save somebody else a few hours. They real life saver was my discovery of the getDecodedBody method (a very hard to find trick in FB docs). My example just checks for publish_actions.
$fb = new Facebook\Facebook([
'app_id' => your_app_id,
'app_secret' => your_secret,
'default_graph_version' => 'v2.2',
]);
$badperms=true; //start by assume bad permissions
try {
$response = $fb->get('/me/permissions', $at);
$perms = $response->getDecodedBody();
if($badperms){
foreach($perms['data'] AS $perm){
if($perm['permission']=='publish_actions' && $perm['status']=='granted') $badperms=false;
}
}
} catch(Facebook\Exceptions\FacebookResponseException $e) {
log("MSG-received facebook Response exception!! ".$e->getMessage());
} catch(Facebook\Exceptions\FacebookSDKException $e) {
log("MSG-received facebook SDK exception!! ".$e->getMessage());
}
if($badperms) {
//do something like reflow auth
}
I just had the same issue, I didn't know how to treat the cancel action (both in facebook php api and google oauth2).
The solution is much easier than expected.
The response in case of permission not accepted (at all) comes with at least one parameter/variable: error in the URL.
In facebook that response looks like:
error=access_denied&error_code=200&error_description=Permissions+error&error_reason=user_denied
for google you only get the
error=access_denied
but it should be enough.
I'm just checking if error is set and if it's set I am redirecting the response to my login page.
I hope it will help someone because it's really not documented this step.
By the way:
version of facebook API: v5
version of google API oAuth2: 2.0 (i think - google doc is really a mess when it comes to finding the latest versions)
I have been reading the Facebook documentation and I must be missing something, as I just cant understand how to get the access token for a page without actually logging in first. I am trying to create a PHP function using the PHP facebook API so that when I add new stories or tutorials on my site, my site's apps can then automatically post as the page a blurb about them on myy facebook page.
I have this function working but only when I get the access token from the Graph API Explorer, though the access tokens expire in about an hour. I can't seem to figure out how to programatically obtain the access_token for the page and query for a new one each time from within my PHP scripts so they don't expire and do not require user interaction.
function post_to_facebook($title, $message, $link, $picture) {
require '../facebook/src/facebook.php';
$page_token = 'xxx';
$page_id = 'xx';
$facebook = new Facebook(array(
'appId' => '<app_id>',
'secret' => '<app_secret>',
'cookie' => false,
));
$facebook->setAccessToken($page_token);
try {
$ret_obj = $facebook->api('/'.$page_id.'/feed', 'POST', array(
'caption' => $title,
'link' => $link,
'message' => $message,
'picture' => $picture
));
} catch(FacebookApiException $e) {
error_log($e->getType());
error_log($e->getMessage());
return false;
}
return true;
}
Can someone explain how I can go about retrieving the access token without manually having to look it up via graph api explorer or having a user login?
It's not possible.
The only correct (and legal) way to achieve the access token is with user interaction (through login process).
I am using the following code to post to Facebook:
require('facebook.php');
$fb = new Facebook(array('appId' => 'MY APP ID','secret' => 'MY APP SECRET','cookie' => true));
$result = false;
$feed_dir = '/401868882779/feed/'; //to the UID you want to send to
$acToken = "MY ACCESS TOKEN";
$url = 'URL';
$link = $url . 'event.php?id=' . $id;
if (isset($picture))
{
$picture = $url . 'uploads/' . $picture;
}
else
{
$picture = $url . 'images/blank100x70.png';
}
$msg_body = array('access_token' => $acToken,'name' => $noe_unsecured,'message' => $link,'link' => $link,'description' => $description_unsecured,'picture' => $picture);
try
{
$result = $fb->api($feed_dir, 'post', $msg_body);
}
catch (Exception $e)
{
$err_str = $e->getMessage();
}
but I need to update the access token manually every time it changes. I am sure there's solution but I cant find it.. I tried lots of scripts and nothing worked.
It is possible.
Check: http://developers.facebook.com/docs/reference/php/facebook-setAccessToken/
Depending on when you perform the wall post, you might need to request the offline_access permission. This will convert your access_token into a format that does not expire so there would be no need to refresh the token.
A simple solution...remove the access_token!
You simply don't need it as long as you got the publish_stream permission!
I believe there are multiple methods to do this:
- you can use the method already provided in the PHP SDK getAccessToken which returns the current access token being used by the sdk instance, more info at this url.
- However you need not use an access token to call the api() method, once you ask the user for the publish_stream permission, as already mentioned by #ifaour. Hence you can do something like this example, scroll to the subheading Post a link to a User's wall using the Graph API.
- Then, you have another three options
i) either get a new access token using the method here, if you are posting when the user is currently using your app, otherwise you can try the next 2 options
ii) get offline access
iii) i'm not sure of this, but you might want to try with an app access token which can be obtained this way.
I'm tired of digging through tons of tutorials/documentations which don't help me at all.
What I have now (everything is placed inside admin control panel):
If user is logged on correct account (administrator of page with granted rights), everything works fine, post on page is posted as impersonated site.
If he is logged on other account, nothing happens. Site redirects him to his wall.
If he isn't logged on any account, he's redirected to facebook login - if he logs onto correct account, he returns to acp (it's bad solution, because it'll clear his form)
I want to achieve:
If logged in, everything as it was
Else popup with login to specific (correct) account
At the moment I'm using only PHP, but solution with JS is permitted.
My code:
<?php
/*(...)*/
$facebook = new Facebook(array(
'appId' => $apiid,
'secret' => $secret,
'cookie' => true,
));
$session = $facebook->getSession();
$me = null;
if ($session) {
try {
$uid = $facebook->getUser();
$me = $facebook->api('/me');
} catch (FacebookApiException $e) {
error_log($e);
}
if($me) {
//In order to post to the page later on we need to generate an Access Token for that page, to do this we get me-accounts in the following api call
$accounts = $facebook->api('/me/accounts');
//Loop through the array off accounts to find the page with a matching ID to the one we need
foreach($accounts['data'] as $account){
if($account['id'] == PAGEID){
$ACCESS_TOKEN = $account['access_token'];
}
}
}
$message=$data['facebook_text'];
$attachment = array(
'message' => $data['facebook_text'],
'name' => $data['name'],
'description' => '',
'link'=>$someurl,
'access_token' => $ACCESS_TOKEN
);
if($image_url != NULL) $attachment['picture'] = $image_url;
try {
if($facebook->api('/PAGEID/feed', 'post', $attachment))
{
//other stuff
}
} catch (FacebookApiException $e) {
error_log($e);
//other stuff
}
}
else
{
$login_url = $facebook->getLoginUrl();
header("Location: $login_url");
exit;
}
/* (...) */
?>
Solution can't redirect anywhere, because it's inside form, so all data'll be lost.
I'm not really sure I understand what you want to do here, but this is what I use in a similar situation:
$session = $this->get_admin_session_of_page ($page_id);
$session = unserialize ($session);
$facebook->setSession ($session, false);
In the facebook php SDK there is a method to manually set the session, setSession. I save the page admin user session in DB with serialize, with the offline access and manage pages permission. Then when you need some admin privileges for the application you just unserialize it, and then use setSession. The second parameter is set to FALSE, so that this session is not saved in a cookie and logout the current user.
This way it's not important who is logged in, the work is always done as an admin of the page. I think this is safe to use in an automated script, for example to upload a user photo in a page album.
Of course, you must use caution with this if it gets more involved then that, or implement your own security.