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.
Related
I have a PHP web application integrated with GoogleDriveAPI v3 which creates folders on Google Drive, sets different permissions to a list of users, shows to each user the folder content and the users should be able to get access to the files (which have the same permissions of the folder) opening them in a new window outside my application, directly in Google Docs. These users might not have a Google Account.
In my database, I store the folder Id got by Google Drive API and the permissions IDs got when the permissions are set.
When users views the folder content, my application calls the related API to get the list of files inside the folder (explained here https://developers.google.com/drive/api/v3/reference/files/list) and I manage the webViewLink json key which is the link of the document, but I don't know how to give the way to open the file, directly in Google Docs, passing the permissions for those users without a Google Account.
I tried to create and share a document outside my application, directly in a Google Drive folder, and I received an email with a link like this:
https://docs.google.com/document/d/xxxxxx-file-id/edit?usp=sharing_eip&ts=5d03b1c1 Note: I can't post the right link because of the reserved content.
By opening the link I was able to modify the document even if I was not logged in as a Google Account (my nickname is shown as an animal), so someway Google knows that opening the link I can edit the file.
//create Folder
public function createRootFolder($name, $folder_root)
{
$fileMetadata = new Google_Service_Drive_DriveFile(array(
'name' => $name,
"parents" => [$folder_root],
'mimeType' => 'application/vnd.google-apps.folder'));
$file = $this->service->files->create($fileMetadata, array(
'fields' => 'id'));
return $file;
}
//setPermission
public function setPermission($folderId, $typePermission = 'user' ,
$rolePermission , $emailAddress)
{
$return = false;
$this->service->getClient()->setUseBatch(true);
try {
$batch = $this->service->createBatch();
$userPermission = new Google_Service_Drive_Permission(array(
'type' => $typePermission,
'role' => $rolePermission,
'emailAddress' => $emailAddress,
'setDisplayName' => $emailAddress
));
$request = $this->service->permissions->create(
$folderId, $userPermission, array('fields' => 'id')
);
$batch->add($request, 'user');
$results = $batch->execute();
foreach ($results as $result) {
if ($result instanceof Google_Service_Exception) {
$return = null;
} else {
$return = $result->id ;
}
}
} finally {
$this->service->getClient()->setUseBatch(false);
}
return $return;
}
//getFileList
public function getFileList($folderId=null)
{
$l = [];
$optParams = array(
'fields' => '*',
'q' => '\''.$folderId.'\' in parents'
);
$response = $this->service->files->listFiles($optParams);
$ll = [];
foreach ($response->files as $file) {
array_push($l,
array(
'id'=>$file->id,'name'=>$file->name,
'modifiedTime'=>$file->modifiedTime,
'createdTime'=> $file->createdTime,
'webViewLink' => $file->webViewLink
));
array_push($ll ,array('file', $file));
}
return $l;
}
Here I would like open the Google Docs File
Apri
I expect as I can open and modify the file when I receive the link by email, I could generate the same link for users to open it through my application.
You are talking about a link accessible for everyone with the link, as you said the primary difference between this way and sharing the Google Doc with a specific google account is that if you use the anyoneWithTheLink way, even if you log in with your google account you’re going to be anonymous, meaning the edits you do will appear as anonymous [1].
If you want to obtain this editable link, you would have to use the following $userPermission variable rather than the one you’re using [2]:
$userPermission = new Google_Service_Drive_Permission(array(
'type' => ’anyone’,
'role' => ‘writer’,
‘allowFileDiscovery’ => false //If true, the link will be discoverable in internet
));
You could use the setPermission method once for each file, so they’ll all have the shareable link as editable by anyone with the link.
[1] https://support.google.com/drive/answer/2494822?hl=en&co=GENIE.Platform=Desktop
[2] https://developers.google.com/drive/api/v3/reference/permissions/create
I am trying to use FB App for auto posting. I have been trying to use the SDK from facebookapi as well as facebook-php-sdk-master
However, i am having trouble with setting up the Uris and domains on the FB App settings. I have tried all combinations - with 'localhost', with actual site domain 'landshoppe.com', with 'www', without 'www' etc. I am not able to understand what exactly needs to be entered into the Uri fields !
If somebody can explain and help me get the script working, I will be obliged.
I am attaching screenshots of what I am doing.
In the Basic FB settings, I have tried adding http://localhost as well as http://landshoppe.com
In the Site Url also I have tried same
In the Advanced settings, redirect Deauthorize Callback URL also I have tried these Uris
I have whitelisted IPs 127.0.0.1 and my server IP
Client OAuth Login, Web OAuth Login and
Embedded Browser OAuth Login tabs say 'Yes'
I have got 'http://localhost/fb-tokens/' in Valid OAuth redirect URIs
My Script settings are
$appid = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$appsecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$pageId = '530139960390619';
$msg = 'Buy/Sell/rent Property in India. Redevelopment, Joint Ventures, Auction Properties';
$title = 'Landshoppe-The Property Destination';
$uri = 'http://localhost/'; //I have tried all combinations here
$desc = 'Buy an Apartment, Rent an Apartment,Land for Redevelopment, Land for sale, Commercial Property';
$pic = 'http://www.landshoppe.com/images/logo.jpg';
$action_name = 'Post to FB';
$action_link = 'http://www.landshoppe.com/';
$facebook = new Facebook(array(
'appId' => $appid,
'secret' => $appsecret,
'cookie' => false,
));
$user = $facebook->getUser();
// Contact Facebook and get token
if ($user) {
// you're logged in, and we'll get user acces token for posting on the wall
try {
$page_info = $facebook->api("/$pageId?fields=access_token");
if (!empty($page_info['access_token'])) {
$attachment = array(
'access_token' => $page_info['access_token'],
'message' => $msg,
'name' => $title,
'link' => $uri,
'description' => $desc,
'picture'=>$pic,
'actions' => json_encode(array('name' => $action_name,'link' => $action_link))
);
$status = $facebook->api("/$pageId/feed", "post", $attachment);
} else {
$status = 'No access token recieved';
}
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
} else {
// you're not logged in, the application will try to log in to get a access token
header("Location:{$facebook->getLoginUrl(array('scope' => 'photo_upload,user_status,publish_stream,user_photos,manage_pages'))}");
}
echo $status;
I am getting errors like
>
URL Blocked: This redirect failed because the redirect URI is not whitelisted in the app’s Client OAuth Settings. Make sure Client and Web OAuth Login are on and add all your app domains as Valid OAuth Redirect URIs.
>
And
>
'Cannot Load Url' because it is not added in App Domains'
>
I am at my wits end ! Kindly help me understand what needs to be the Uris that should be used in all these places.
I'm developing with Laravel a package to post on facebook. My code responsible for obtaining and storing the access token of the page post a link besides test makes this operation correctly with an app that I have created test fb . The problem is to create another app on facebook to put it into production , this second app facebook created it with the same configuration that does work but when publishing gives me the following error: (# 200 ) The user hasn 't Authorized the application to perform this action .
This is the code snippet I use for testing .
public function getTest(){
//$accessToken = new AccessToken($this->getParam('TOKEN'));
try {
$page_post = (new FacebookRequest($this->session, 'POST', '/'.$this->getParam('PAGE_ID').'/feed', array(
'access_token' => $this->getParam('TOKEN'),
'link' => 'link',
'description' => 'Hola mundo desde laravel',
'picture' => 'link/img.png',
'message' => 'Messge',
) ))->execute()->getGraphObject()->asArray();
// return post_id
print_r( $page_post );
} catch(FacebookSDKException $e) {
var_dump($this->getParam('TOKEN'));
echo $e->getMessage();
// var_dump($e);
exit;
}
As for the authorization of the application is correctly even when you enter to view user applications see 2 ( The works and which not) , both with the same permissions accepted.
Fixed , I lacked a permit : ' publish_pages '
$params = array(
'scope' => 'manage_pages','publish_actions','publish_stream','publish_pages'
);
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.
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).