Facebook Batch Request recognizing access token as user for page admin - php

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.

Related

Facebook - You don't have required permission to access this profile

I'm trying to build a service that let's users create facebook ads with a custom audience based on our database of emails.
Before creating the facebook ad I want to create a preview of the ad. This works just fine when I login in with my own account (admin of facebook app) but fails when logging in as test user.
This is what the user will do:
1. Visit the website of the service.
2. Login using Facebook account with scope: public_profile,email,manage_pages,publish_pages,business_management,ads_management
3. Select facebook page to use
4. Create AdCreative. From this an ad preview can be made. But it fails creating an Adcreative and gives me the following error:
"error":{"message":"Application does not have permission for this action","type":"OAuthException","code":10,"error_subcode":1341012,"is_transient":false,"error_user_title":"No permission to access this profile","error_user_msg":"You don't have required permission to access this profile","fbtrace_id":"EgTeMOXPCUp"}}
The access token as well as ad account belongs to the facebook app. I tried to use the page access token as well but then I don't have permission to access the ad account.
This is code:
function fbadcreative($url, $message, $carasoul, $fbtoken, $pageid){
$calength = count($carasoul);
$children = array();
for($i = 0; $i < $calength; $i++){
$caitem = $carasoul[$i];
$caitem['hash'] = fbaddimage($caitem['picture'], $caitem['id']);
$child = (new AdCreativeLinkDataChildAttachment())->setData(array(
AdCreativeLinkDataChildAttachmentFields::LINK => $caitem['link'],
AdCreativeLinkDataChildAttachmentFields::NAME => $caitem['name'],
AdCreativeLinkDataChildAttachmentFields::DESCRIPTION => $caitem['description'],
AdCreativeLinkDataChildAttachmentFields::IMAGE_HASH => $caitem['hash'],
));
$children[] = $child;
}
$link_data = new AdCreativeLinkData();
$link_data->setData(array(
AdCreativeLinkDataFields::LINK => $url,
AdCreativeLinkDataFields::CAPTION => $url,
AdCreativeLinkDataFields::MESSAGE => $message,
AdCreativeLinkDataFields::MULTI_SHARE_END_CARD => false,
AdCreativeLinkDataFields::MULTI_SHARE_OPTIMIZED => false,
AdCreativeLinkDataFields::CHILD_ATTACHMENTS => $children,
));
$object_story_spec = new AdCreativeObjectStorySpec();
$object_story_spec->setData(array(
AdCreativeObjectStorySpecFields::PAGE_ID => $pageid,
AdCreativeObjectStorySpecFields::LINK_DATA => $link_data,
));
$creative = new AdCreative(null, 'act_<accountid>');
$creative->setData(array(
AdCreativeFields::NAME => $url,
AdCreativeFields::OBJECT_STORY_SPEC => $object_story_spec,
));
try {
$creative->create();
return $creative->id;
//return $creative->read(array(AdCreativeFields::ID,));
} catch (FacebookAds\Http\Exception\AuthorizationException $e) {
echo 'Message: ' . var_dump($e);
$previousException = $e->getPrevious();
// Do some further processing on $previousException
exit;
}
I know this is an older post, but it might be interesting for others to read how to solve this.
You need to give the user that requests via api the Advertise and analyze permissions on the PAGE the ad creative will be created for.
Example request here using the graph explorer:
page_id/assigned_users?user=system_user_id&tasks=['ADVERTISE', 'ANALYZE']
In my case i am getting this same error due to giving the wrong page Id , i was giving the another page id that was not linked to this ad account.

Facebook - get profile picture php sdk

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!

Post to fan page as admin worked yesterday, not today

To post to facebook fan page, using a php script which is called by a cronjob, im using the following code, which worked yesterday while testing, it is no longer working.
include_once("../facebooksdk/src/facebook.php");
$facebook = new Facebook(array(
'appId' => 'XX',
'secret' => 'XX',
));
// Get User ID
$user = $facebook->getUser();
if ($user) {
try {
$page_id = 'XX';
$page_info = $facebook->api("/".$page_id."?fields=access_token");
if( !empty($page_info['access_token']) ) {
$args = array(
'access_token' => $page_info['access_token'],
'message' => "Welcome to TuneHub!"
);
$post_id = $facebook->api("/".$page_id."/feed","post",$args);
}
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
}
I cant figure out why it would work temporarily, then the following day when the code has been added to the live site, its no longer working (on the test or live site, it isnt working)
is there an API change that is killing the function?
or is there something I am doing wrong with the code that flagged Facebook to prevent it from posting?
(the code may have changed slightly from the script i had which was working, as ive been fiddling around with it to try and find the issue)
see
https://developers.facebook.com/docs/reference/api/page/#posts
Check your access token it may be expired, you need to have a valid access token with rights to post on wall, try getting the updated access token and try

post to the fan page's wall as page from another PHP site

I know that there are lot's of questons on this, but all seem to be needing a user to be logged in... I have been using code snippets from all possible tutorials, but none seem to work.
Here is the scenario:
I have a photo community running on PHP and I have a fan page on Facebook. When an image on the main site collects a certain amount of votes a function is triggered to post the image link to the Facebook wall. The link (post) is posted as a page and not as admin. Admin of course will not be online... Is this even possible to do these days? I have the latest PHP SDK and this is the function that I need to get working in stand alone mode before pluggin' into the main site.
OK. This code works perfectly if I am logged into the Facebook, but if I am not - it will not post... The App has all necessary and unnecessary :) permissions to interact with my page on my (admin) behalf. Any ideas will be appreciated.
<?php
//facebook application
$fbconfig['appid' ] = "1848740815xxxxx";
$fbconfig['secret'] = "a5aa62bb3a8ddcb98d5d9dbe4a3xxxxx";
$fbconfig['pageid'] = "121409594622865";
$user = null; //facebook user uid
try{
include_once "facebook.php";
}
catch(Exception $o){
error_log($o);
}
// Create our Application instance.
$facebook = new Facebook(array(
'appId' => $fbconfig['appid'],
'secret' => $fbconfig['secret']
));
//Facebook Authentication part
$user = $facebook->getUser();
$loginUrl = $facebook->getLoginUrl(
array(
'scope' => 'offline_access,publish_stream'
)
);
$logoutUrl = $facebook->getLogoutUrl();
$pageid = $fbconfig['pageid'];
if ($user) {
try {
$page_info = $facebook->api("/$pageid?fields=access_token");
if( !empty($page_info['access_token']) ) {
$args = array(
'access_token' => $page_info['access_token'],
'message' => 'This is a test feed message',
'link' => 'http://www.fotodvor.com',
'picture' => 'http://www.fotodvor.com/data/media/15/1319971991.jpg',
'name' => 'Test Picture',
'description'=> 'Description of the test picture!'
);
$post_id = $facebook->api("/$page_id/feed","post",$args);
}
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
}
?>
Thanks in advance
here is a modified script with explanations adjusted for the changes in the API
<?php
//facebook application
$fbconfig['userid'] = "5332534xx";
$fbconfig['appid' ] = "184874081548xxx";
$fbconfig['secret'] = "a5aa62bb3a8xxxb98d5d9dbe4a368xxx";
$fbconfig['pageid'] = "121409594622xxx";
$fbconfig['token1'] = "AAACoJFn1eLABAKpL9W0nZBrw0e3zzdSNVsTg6FWDMhSnOUeinjid6yAQ2z9JDxxxxxxc1hMHBC3GG18KZBwppGDehWMEwLe56wagZDZD"; // step 1 - returned by loggin in.
$fbconfig['token2'] = "AAACoJFn1eLABAC2Q8OLnqxjUSKzdn9CzaXhy8nsG61vzp2ufePr5iwHZA7TM7Ibxxxxxxyf868O04FeBxMrIo0RCumrNaB78hZAp2uRrbVlGVPXP"; // step 3 - this is a page access token as page
$fbconfig['my_ulr'] = 'http://'.$_SERVER['SERVER_NAME'];
include_once "facebook.php";
// Create our Application instance.
$facebook = new Facebook(array(
'appId' => $fbconfig['appid'],
'secret' => $fbconfig['secret'],
));
// 1. we need to get a user access_token first, (old approach with offline_access forces the tokens received not to expire (good examples here - http://developers.facebook.com/docs/authentication2/ and http://www.howtobe.pro/tag/graph-api)
// run the file and see step 1 instructions.
//offline_access has been deprecated in May 2012 and therefore excluded from the request below
$token_url1 = "https://www.facebook.com/dialog/oauth?"."client_id=".$fbconfig['appid']."&redirect_uri=".urlencode($fbconfig['my_ulr'])."&scope=manage_pages,publish_stream&response_type=token";
echo "<h2>This little working example should give you a working non expiring token to use in your PHP script to enable it to post to your Facebook page as a page and not as a user</h2><br>";
echo "1 - Click on the link below (this redirects to uri with token attached). Log in as admin of the page you are trying to post to. Then copy the token you will get in the address bar to be used in the script in step 2.<br>";
echo "<a href='".$token_url1."' target='_blank'>$token_url1</a>";
//2. then paste the token you received into "step 1" variable in the config section above. Run this script again when logged in to receive all info.
$token_url2 = "https://graph.facebook.com/me?access_token=".$fbconfig['token1'];
$me = json_decode(file_get_contents($token_url2), true);
//echo "<hr><br>this URL gives you all pages that you as admin have access to, but these are NOT what we need to post to the fan page as PAGE so this is just for the heck of it...<br>";
//echo "<a href='".$token_url2."' target='_blank'>$token_url2</a>";
//echo "<hr>this is a raw server reply<br>";
//echo d($me['id'])."<hr>";
//new changes to API - https://developers.facebook.com/roadmap/offline-access-removal/#extend_token
$new_token_url2 = "https://graph.facebook.com/oauth/access_token?client_id=".$fbconfig['appid']."&client_secret=".$fbconfig['secret']."&grant_type=fb_exchange_token&fb_exchange_token=".$fbconfig['token1'];
$new_token2 = file_get_contents($new_token_url2);
$vars = explode('&', $new_token2);
//d($vars);
echo "2. We now obtain a long lasting token (based on <a href='https://developers.facebook.com/roadmap/offline-access-removal/#extend_token' target='_blank'>this</a>)
<br><br>We send the request<br>'".$new_token_url2."'<br><br>and the reply is:<br>'".$new_token2."'<br><br>";
//http://developers.facebook.com/tools/explorer?method=GET&path=533253476&accounts&access_token=AAACoJFn1eLABAFZBftV0vtlBiHKA7ZAIrukrriyp2coWSavj3L4CbfJ9r3WY76IPi7pwUgt3wsubaI4iBbsr663PrbNyaLdZAhLxneOLAZDZD
echo"So now open this page <a href='http://developers.facebook.com/tools/explorer' target='_blank'>http://developers.facebook.com/tools/explorer</a>,
then put the token above to put into the 'Access Token: ' field and press enter... You will need to press 'accounts' link to the right from the response window.
<br>you will see another response and copy your page access token from there. Automating this task into one query did not work... I tried many times.. the token returned IS NOT THE SAME as you would get following the instructions step by step...
This approach does not work - <br>";
echo "http://developers.facebook.com/tools/explorer?method=GET&path=".$me['id']."%2Faccounts&".$vars[0]."<BR><BR><BR>";
echo "Please check it here <a href='http://developers.facebook.com/tools/debug' target='_blank'>https://developers.facebook.com/tools/debug</a> and make sure it never expires...";
$pageid = $fbconfig['pageid'];
try {
//Step 3. Run this script WHEN LOGGED IN to and paste the resulting token into step 3 variable above to check the functionality
/* $page_info = $facebook->api("/$pageid?fields=access_token&".$new_token2); //wrong approach to use this straight. THIS is the access token is that we need. BUT this will work only if user is logged in. so
echo "<hr>this is a page_info breakdown";
d($page_info);
echo "and the access token you needs to paste into fbconfig['token2'] variable is this:<br>";
echo $page_info['access_token']; */
$args = array(
'access_token' => $fbconfig['token2'], //do not attempt to plug the $page_info['access_token'] here... it will be empty once you log off Facebook
'message' => 'This is a test feed message',
'link' => 'http://www.test.com',
'picture' => 'https://www.google.com/intl/en_com/images/srpr/logo3w.png',
'name' => 'Test Picture',
'description'=> 'Description of the test picture!'
);
//uncomment this once you are ready to post and you can see all the access token in the last step. Then comment out all echo and d()'s to make the script silent...
//$post_id = $facebook->api("/$pageid/feed","post",$args);
echo "<hr>This will show once the message is posted - post_id is: <br>";
d($post_id);
} catch (FacebookApiException $e) {
error_log($e);
}
function d($d){
echo '<pre>';
print_r($d);
echo '</pre>';
}
?>
I think I have found the answer. After a long time of testing here is the solution:
Treat this as a little sample/guide for those who are new to this.
The code and output has all necessary info:
<?php
//facebook application
$fbconfig['appid' ] = "184874081XXXXXX";
$fbconfig['secret'] = "a5aa62bb3a8ddcb98d5d9dbe4aXXXXXX";
$fbconfig['pageid'] = "121409594XXXXXX";
$fbconfig['token1'] = "AAACoJFn1eLABAHn92JsWIHZCESQWXmkXZBCedXXXXXXcyUG5vrCYZBXcgsNHN0IUvBj0Sec9vOxVsUgtMHflXXF2cbOF1oZD"; // step 1 - returned by loggin in.
$fbconfig['token2'] = "AAACoJFn1eLABAAUAPthH5DaZCmasZCh5DGGSnZXXXXXXSDh8v1WYYUEWJYuFdua9E5EfJ63c03lfwXrVJbP4VQj35aVcztFgKRYZAheHPNfDeLfbkPys"; // step 3 - this is a page access token as page
$fbconfig['my_ulr'] = 'http://'.$_SERVER['SERVER_NAME'];
include_once "facebook.php";
// Create our Application instance.
$facebook = new Facebook(array(
'appId' => $fbconfig['appid'],
'secret' => $fbconfig['secret'],
));
// 1. we need to get a user access_token first, offline_access forces the tokens received not to expire (good examples here - http://developers.facebook.com/docs/authentication2/ and http://www.howtobe.pro/tag/graph-api)
//run the file and see step 1 instructions.
$token_url1 = "https://www.facebook.com/dialog/oauth?"."client_id=".$fbconfig['appid']."&redirect_uri=".urlencode($fbconfig['my_ulr'])."&scope=manage_pages,offline_access,publish_stream&response_type=token";
echo "1 - this redirects to uri with token attached. Copy and paste this line into your browser and log in as admin of the page you are trying to post to. Make sure you change redirect_uri to your own. Then copy the token you will get in the address bar to be used in the script in step 2.<br>";
echo $token_url1;
//2. then paste the token you received into "step 1" variable in the config section above. Run this script again when logged in to receive all info.
$token_url2 = "https://graph.facebook.com/me/accounts?access_token=".$fbconfig['token1'];
$app_token2 = file_get_contents($token_url2);
echo "<hr><br>2 - this URL gives you all pages that you as admin have access to, but these are NOT what we need to post to the fan page as PAGE<br>";
echo $token_url2;
echo "<hr>2 - this is a raw server reply<br>";
d($app_token2);
$pageid = $fbconfig['pageid'];
try {
//Step 3. Run this script WHEN LOGGED IN to and paste the resulting token into step 3 variable above
$page_info = $facebook->api("/$pageid?fields=access_token"); //wrong approach to use this straight. THIS is the access token is that we need. BUT this will work only if user is logged in. so
echo "this is a page_info breakdown";
d($page_info);
echo "and the access token you needs to paste into fbconfig['token2'] variable is this:<br>";
echo $page_info['access_token'];
$args = array(
'access_token' => $fbconfig['token2'], //do not attempt to plug the $page_info['access_token'] here... it will be empty once you log off Facebook
'message' => 'This is a test feed message',
'link' => 'http://www.test.com',
'picture' => 'https://www.google.com/intl/en_com/images/srpr/logo3w.png',
'name' => 'Test Picture',
'description'=> 'Description of the test picture!'
);
//uncomment this once you are ready to post and you can see all the access token in the last step. Then comment out all echo and d()'s to make the script silent...
//$post_id = $facebook->api("/$pageid/feed","post",$args);
echo "<hr>This will show once the message is posted - post_id is: <br>";
d($post_id);
} catch (FacebookApiException $e) {
error_log($e);
}
function d($d){
echo '<pre>';
print_r($d);
echo '</pre>';
}
?>
You should be using the page access token if i'm understanding what you're trying to do correctly - this is a token which allows your app to act as the page, not as one of the admins.
This is accessible at the /me/accounts endpoint when you have a user access token with manage_pages permission - if you use that access token to post to /{page id}/feed (or photos, etc) it'll appear as the page

Facebook PHP SDK - require login on specific account

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.

Categories