Creating AdSet via FB Marketing API - php

I'm trying to create AdSet via FB Marketng API, but getting Error 100 (Invalid parameter). I'm even try to paste sample code from FB Developers Docs, but it is the same Error. Please help.
This is my code:
use FacebookAds\Object\Targeting;
use FacebookAds\Object\Fields\TargetingFields;
$targeting = new Targeting();
$targeting->{TargetingFields::GEO_LOCATIONS} =
array(
'countries' => array('US')
);
/**
* Step 4 Create the AdSet
*/
use FacebookAds\Object\AdSet;
use FacebookAds\Object\Fields\AdSetFields;
use FacebookAds\Object\Values\AdSetBillingEventValues;
use FacebookAds\Object\Values\AdSetOptimizationGoalValues;
try{
$start_time = (new \DateTime("+1 week"))->format(DateTime::ISO8601);
$end_time = (new \DateTime("+2 week"))->format(DateTime::ISO8601);
$adset = new AdSet(null, $account_id);
$adset->setData(array(
AdSetFields::NAME => 'Adslondon1',
AdSetFields::CAMPAIGN_ID => '6070381098103',
AdSetFields::LIFETIME_BUDGET => '50',
AdSetFields::TARGETING => $targeting,
AdSetFields::OPTIMIZATION_GOAL => AdSetOptimizationGoalValues::LINK_CLICKS,
AdSetFields::BILLING_EVENT => AdSetBillingEventValues::LINK_CLICKS,
AdSetFields::BID_AMOUNT => '10',
AdSetFields::START_TIME => $start_time,
AdSetFields::END_TIME => $end_time
));
$adset->create(array(
AdSet::STATUS_PARAM_NAME => AdSet::STATUS_PAUSED,
));
echo 'AdSet ID: '. $adset->id . "\n";
}

Related

Cannot create Ad Set using Facebook Business SDK

We are using Laravel 5.7, PHP 7.1 and XAMPP 3.2.2
We want to create Facebook Campaigns using the PHP Business SDK and Marketing API.
The campaign is created successfully through the following source code
/* Start Campaign*/
$fields = array(
);
$params = array(
'name' => $request->campaign_name,
'objective' => 'LINK_CLICKS',
'status' => 'PAUSED',
);
$campaignData = ((new AdAccount($account_id))->createCampaign(
$fields,
$params
)->exportAllData());
/* End Campaign*/
this, I try to write the source code for the AdSet but I get the following error
"$parent_id as a parameter of constructor is being deprecated, please try not to use this in new code."
At the following line
$adset = new AdSet(null, $account_id);
Below you will find all of my source code for the creation of the AdSet
$start_time = (new DateTime("+1 week"))->format(DateTime::ISO8601);
$end_time = (new DateTime("+2 week"))->format(DateTime::ISO8601);
$adset = new AdSet(null,$account_id);
$adset->setData(array(
AdSetFields::NAME => 'My Ad Set',
AdSetFields::OPTIMIZATION_GOAL => AdSetOptimizationGoalValues::REACH,
AdSetFields::BILLING_EVENT => AdSetBillingEventValues::IMPRESSIONS,
AdSetFields::BID_AMOUNT => 2,
AdSetFields::DAILY_BUDGET => 1000,
AdSetFields::CAMPAIGN_ID => $campaignData['id'],
AdSetFields::TARGETING => $targeting,
AdSetFields::START_TIME => $start_time,
AdSetFields::END_TIME => $end_time,
));
$adset->create(array(
AdSet::STATUS_PARAM_NAME => AdSet::STATUS_PAUSED,
));
Trying to solve the issue I faced, I have modified the following
$adset = new AdSet(null, $account_id);
to
$adset = new AdSet($account_id);
And my new source code is the following.
$adset = new AdSet($account_id);
$adset->setData(array(
AdSetFields::NAME => 'My Ad Set',
AdSetFields::OPTIMIZATION_GOAL => AdSetOptimizationGoalValues::REACH,
AdSetFields::BILLING_EVENT => AdSetBillingEventValues::IMPRESSIONS,
AdSetFields::BID_AMOUNT => 2,
AdSetFields::DAILY_BUDGET => 1000,
AdSetFields::CAMPAIGN_ID => $campaignData['id'],
AdSetFields::TARGETING => $targeting,
AdSetFields::START_TIME => $start_time,
AdSetFields::END_TIME => $end_time,
));
$adset->create(array(
AdSet::STATUS_PARAM_NAME => AdSet::STATUS_PAUSED,
));
And now I get the error "Object has already an ID" on the following line
$adset->create(array(
Can you please help me to find out what is going and where I making the mistake?
You are getting the "Object has already an ID" error because the first value of the
constructor is the ad set id so the save method fails instantly.
The "$parent_id as a parameter of constructor is being deprecated" is just a warning in the latest sdk so you can ignore it for demonstration purposes.
I would suggest attempting to create the ad set without any target and calling validate. Also catch the Request Exception and dump the body to get a detailed explanation as to why a request failed.
use FacebookAds\Http\Exception\RequestException;
$adset = new AdSet(null, 'act_xxx');
$adset->setData([
AdSetFields::NAME => 'Demo Ad Set',
AdSetFields::OPTIMIZATION_GOAL => AdSetOptimizationGoalValues::REACH,
AdSetFields::BILLING_EVENT => AdSetBillingEventValues::IMPRESSIONS,
AdSetFields::BID_AMOUNT => 2,
AdSetFields::DAILY_BUDGET => 1000,
AdSetFields::CAMPAIGN_ID => $facebookCampaignId
]);
try {
$adset->validate([AdSet::STATUS_PARAM_NAME => AdSet::STATUS_ACTIVE]);
} catch (RequestException $e) {
// Super helpful debugging information
$response = json_decode($e->getResponse()->getBody(), true);
var_dump($response);
}

Can't get an unenrolled 3d-secure card authenticaited (secrure trading)

I am running a PHP 7.3, running on apache server. I used composer to get this library:
https://github.com/SecureTrading/PHP-API
For the code provided, I am now using the test site reference. I already managed to use for regular transitions. I now started managing 3D secure transactions, with the test MAESTRO card provided by secure trading here: https://docs.securetrading.com/document/testing/. the one designed not to demand 3D auth - that is 5000000000000421
The code provided next, will sum up the way I think thought this should work: I start by creating AUTH request, get error 30004, using CACHETOKENISE request to get a token, run THREEDQUERY to figure out if I need a full auth sceme on this card, get N as an answer, and run another AUTH request, this time with the transactionreference.
I am providing a version of the code I am testing (obviously, username, password and site reference name was removed to protect my privacy, but the code otherwise is the same)
<?php
$configData = array(
'username' => 'api#gigsberg.com',
'password' => 'xq!Kq$j4',
);
$site_refrance = 'test_gigsberg74319';
?>
<?php
$configData = array(
'username' => '*****',
'password' => '*****',
);
$site_refrance = '*****';
if (!($autoload = realpath(__DIR__ . '/vendor/autoload.php'))) {
throw new \Exception('Composer autoloader file could not be found.');
}
require_once($autoload);
$api = \Securetrading\api($configData);
$requestData = array(
'sitereference' => $site_refrance,
'requesttypedescription' => 'AUTH',
'accounttypedescription' => 'ECOM',
'currencyiso3a' => 'GBP',
'mainamount' => '1000',
'pan' => '5000000000000421',
'expirymonth' => '12',
'expiryyear' => '2030',
'securitycode' => '123',
);
echo '<pre>';
print_r($requestData);
$response = $api->process($requestData)->toArray();
print_r( $response['responses'] ); // $response['responses'][0]['errorcode'] == 30004
echo "\n--------------------------------------\n";
$transactionreference = $response['responses'][0]['transactionreference'];
$requestData = array(
'sitereference' => $site_refrance,
'expirymonth' => '12',
'expiryyear' => '2030',
'requesttypedescriptions' => array('CACHETOKENISE'),
'securitycode' => '123',
'orderreference' => $transactionreference,
'pan' => '5000000000000421'
);
print_r($requestData);
$response = $api->process($requestData)->toArray();
echo "\n--------------------------------------\n";
$cachetoken = $response['responses'][0]['cachetoken'];
$requestData = array(
'termurl' => 'https://termurl.com',
'accept' => 'text/html,*/*',
'currencyiso3a' => 'GBP',
'requesttypedescription' => 'THREEDQUERY',
'accounttypedescription' => 'ECOM',
'sitereference' => $site_refrance,
'baseamount' => '1000',
'pan' => '5000000000000421',
'expirymonth' => '12',
'expiryyear' => '2030',
'cachetoken' => $cachetoken,
);
print_r($requestData);
$response = $api->process($requestData)->toArray(); // $response['responses'][0]['enrolled'] == 'N'
/* Copying from the docs here: https://docs.securetrading.com/document/api/security/3-d-secure/
* If the enrolled value returned in the response is “Y”, the customer’s card is enrolled in 3-D secure. Please refer to the following table for enrolled values:
* .
* .
* N - The card is not enrolled in the card issuer’s 3-D Secure scheme. - Perform an AUTH Request, including the transactionreference returned in the THREEDQUERY response.
* .
* .
*/
print_r( $response['responses'] );
echo "\n--------------------------------------\n";
$transactionreference = $response['responses'][0]['transactionreference'];
$requestData = array(
'sitereference' => $site_refrance,
'requesttypedescription' => 'AUTH',
'accounttypedescription' => 'ECOM',
'currencyiso3a' => 'GBP',
'mainamount' => '1000',
'pan' => '5000000000000421',
'expirymonth' => '12',
'expiryyear' => '2030',
'securitycode' => '123',
'transactionreference' => $transactionreference
);
print_r($requestData);
$response = $api->process($requestData)->toArray();
print_r( $response['responses'] ); // Still get $response['responses'][0]['errorcode'] == 30004
I expected it to give me a note that all works well, but I still got error 30004, as if the transactionreference wasn't provided. Any idea what I can do, to fix this code, and prevent this error?
Thanks in advance
Yair
Well, I read the Api tests, and I found my error. On the last request data, instead of
$requestData = array(
.
.
'transactionreference' => $transactionreference
.
.
);
I should use
$requestData = array(
.
.
'parenttransactionreference' => $transactionreference
.
.
);
Anyway, home this helps somone

Invalid parameter Facebook video ad creative in Facebook Marketing API

I am getting the same error while creating Ad Creative via Facebook Marketing API. I followed their guide but doesn't work. Facebook video ad creative reference
$config = Config::get('facebook');
$data['account_id'] = 'act_'.$config['ad_account_id'];
$data['page_id'] = $config['page_id'];
// Init facebook
$api = Api::init($config['app_id'], $config['app_secret'], $config['access_token']);
// Create product catalog
$product_catalog = new ProductCatalog(null, $config['business_id']);
$product_catalog->setData(array(
ProductCatalogFields::NAME => "Catalog",
));
$product_catalog->create();
$product_catalog_id = $product_catalog->id;
// Setup Feed
$product_feed = new ProductFeed(null, $product_catalog_id);
$product_feed->setData(array(
ProductFeedFields::NAME => 'Campaign Feed',
ProductFeedFields::SCHEDULE => array(
ProductFeedScheduleFields::INTERVAL => 'DAILY',
ProductFeedScheduleFields::URL => 'http://example.com/facebook/dpa_product_catalog_sample_feed.csv',
ProductFeedScheduleFields::HOUR => 22,
),
));
$product_feed = $product_feed->create();
// Create Product Set
$product_set = new ProductSet(null, $product_catalog_id);
$product_set->setData(array(
ProductFeedFields::NAME => 'All Product',
));
$product_set->create();
$data['product_set_id'] = $product_set->id;
$video = new Advideo(null, $data['account_id']);
$video->{AdVideoFields::SOURCE} = public_path().'/facebook/video-demo.mp4';
$video->create();
$video_data = new AdCreativeVideoData();
$video_data->setData(array(
AdCreativeVideoDataFields::IMAGE_URL => 'http://example.com/facebook/resize-image.jpg',
AdCreativeVideoDataFields::VIDEO_ID => $video->id,
AdCreativeVideoDataFields::CALL_TO_ACTION => array(
'type' => AdCreativeCallToActionTypeValues::LIKE_PAGE,
'value' => array(
'page' => $data['page_id'],
),
),
));
$object_story_spec = new AdCreativeObjectStorySpec();
$object_story_spec->setData(array(
AdCreativeObjectStorySpecFields::PAGE_ID => $data['page_id'],
AdCreativeObjectStorySpecFields::VIDEO_DATA => $video_data,
));
Above these code working and return response but when I call ad creative, the API return "Invalid parameter"
$creative = new AdCreative(null, $data['account_id']);
$creative->setData(array(
AdCreativeFields::NAME => 'Video Ad Template Creative Sample',
AdCreativeFields::OBJECT_STORY_SPEC => $object_story_spec,
AdCreativeFields::PRODUCT_SET_ID => $data['product_set_id'],
));
$creative->create();
Might be your issue is in creating AdCreativeVideoData.
search for line
AdCreativeVideoDataFields::IMAGE_URL => public_path().'/facebook/resize-image.jpg',
Here IMAGE_URL requires url path like http://example.com/myimage.jpg. You are giving directory path that might cause problem.
If your image is not directly accessible from URL then you should create IMAGE_HASH. For this see below.
try {
$image = new AdImage(null, $data['account_id']);
$image->{AdImageFields::FILENAME} = public_path().'/facebook/resize-image.jpg';
$image->create();
// Image_hash = $image->hash
} catch (Exception $e) {
echo 'Error message: ' . $e->getMessage() . "\n" . "<br/>";
echo 'Error Code: ' . $e->getCode() . "<br/>";
}
And replace IMAGE_URL to IMAGE_HASH in your AdCreativeVideoData like this
$video_data = new AdCreativeVideoData();
$video_data->setData(array(
AdCreativeVideoDataFields::IMAGE_HASH => $image->hash,
AdCreativeVideoDataFields::VIDEO_ID => $video->id,
AdCreativeVideoDataFields::CALL_TO_ACTION => array(
'type' => AdCreativeCallToActionTypeValues::LIKE_PAGE,
'value' => array(
'page' => $data['page_id'],
),
),
));

Facebook Ad API Error

I am getting error while creating Creative using the FB Ads PHP SDK
$parent_id as a parameter of constructor is being deprecated, please try not to use this in new code.
The code was working before the 2.9 and 2.10 update.
The Code I am using to create Creative is:
$link_data = new AdCreativeLinkData();
$link_data->setData(array(
AdCreativeLinkDataFields::MESSAGE => 'Product Description',
AdCreativeLinkDataFields::LINK => $url_of_website,
AdCreativeLinkDataFields::IMAGE_HASH => $image->hash,
AdCreativeLinkDataFields::DESCRIPTION => 'Link Description',
AdCreativeLinkDataFields::CALL_TO_ACTION => array(
'type' => AdCreativeCallToActionTypeValues::LEARN_MORE,
'value' => array(
'link_title' => 'View Similar Products Now!',
'lead_gen_form_id' => $form_id,
),
),
));
$story = new AdCreativeObjectStorySpec();
$story->setData(array(
AdCreativeObjectStorySpecFields::PAGE_ID => $page_id,
AdCreativeObjectStorySpecFields::LINK_DATA => $link_data,
));
$creative = new AdCreative(null, $account_id);
$creative->setData(array(
AdCreativeFields::NAME => $nm,
AdCreativeFields::OBJECT_STORY_SPEC => $story,
AdCreativeFields::URL_TAGS => 'product=' . $p_id,
));
$creative->create();
I do not see any parent id in this statement. Please help
$parent_id is deprecated
The issue was reported on facebook github with issue# 314
Response from Facebook Developer
"We are depreciating creation with parent_id. We are seeing multiple endpoints that can create the same type of object. We do not have good ways to decide which one we should use if you are creating new object with parent_id. Moving forward, please instantiate the parent object with the parent_id and call create_XXX function to create the object you want."
Sample Code:
use FacebookAds\Object\AdCreative;
use FacebookAds\Object\AdCreativeLinkData;
use FacebookAds\Object\Fields\AdCreativeLinkDataFields;
use FacebookAds\Object\AdCreativeObjectStorySpec;
use FacebookAds\Object\Fields\AdCreativeObjectStorySpecFields;
use FacebookAds\Object\Fields\AdCreativeFields;
$link_data = new AdCreativeLinkData();
$link_data->setData(array(
AdCreativeLinkDataFields::MESSAGE => 'try it out',
AdCreativeLinkDataFields::LINK => '<URL>',
AdCreativeLinkDataFields::IMAGE_HASH => '<IMAGE_HASH>',
));
$object_story_spec = new AdCreativeObjectStorySpec();
$object_story_spec->setData(array(
AdCreativeObjectStorySpecFields::PAGE_ID => <PAGE_ID>,
AdCreativeObjectStorySpecFields::LINK_DATA => $link_data,
));
$creative = new AdCreative(null, 'act_<AD_ACCOUNT_ID>');
$creative->setData(array(
AdCreativeFields::NAME => 'Sample Creative',
AdCreativeFields::OBJECT_STORY_SPEC => $object_story_spec,
));
$creative->create();
Hope this helps.
Use setParentId($parrent_id).
Sample code:
$product_catalog = new ProductCatalog();
$product_catalog->setParentId($parrent_id);
$product_catalog->setData(
[
ProductCatalogFields::NAME => "Testjon Autojon Catalog",
ProductCatalogFields::VERTICAL => "vehicles",
]
);
$product_catalog->create();
I found even though the accepted answer mentioned in here, which is the use of $parent_id is deprecated, the sample code shared there is still shows the old way of doing it.
In that example, the second argument passed to in AdCreative() is still the $parent_id.
$creative = new AdCreative(null, 'act_<AD_ACCOUNT_ID>');
For clarity mentioned below is the method signature of the constructor of \FacebookAds\Object\AbstractCrudObject which is what \FacebookAds\Object\AdCreative is extended from and, you'd see the deprecation notice there.
/**
* #deprecated deprecate constructor with null and parent_id
* #param string $id Optional (do not set for new objects)
* #param string $parent_id Optional, needed for creating new objects.
* #param Api $api The Api instance this object should use to make calls
*/
public function __construct($id = null, $parent_id = null, Api $api = null) {
parent::__construct();
//...
}
Said that as for the new approach, this is the way it should be done now :)
require __DIR__ . '/vendor/autoload.php';
use FacebookAds\Api;
use FacebookAds\Logger\CurlLogger;
use FacebookAds\Object\AdAccount;
$access_token = '<ACCESS_TOKEN>';
$app_secret = '<APP_SECRET>';
$app_id = '<APP_ID>';
$id = '<AD_ACCOUNT_ID>';
$api = Api::init($app_id, $app_secret, $access_token);
$api->setLogger(new CurlLogger());
$fields = array();
$params = array(
'name' => 'Sample Creative',
'object_story_spec' => ['page_id' => '<pageID>',
'video_data' => ['IMAGE_URL' => '<imageURL>',
'video_id' => '<videoID>',
'call_to_action' => ['type' => 'LIKE_PAGE',
'value' => ['page' => '<pageID>']
]
]
],
);
$adCreative = (new AdAccount($id))->createAdCreative($fields, $params);
echo json_encode($adCreative->exportAllData(), JSON_PRETTY_PRINT);
I found this example here. Please note even though the title of this document is "Create an Ad Video Creative" it actually shows how to create the Ad creative. There are numerous inconsistencies in the Facebook Marketing API reference and this is such a case :)

Missing end time Google Calendar when insert event

I trying to insert an event in the Google Calendar. The authentication and to fetch events works without any problems. Unfortunately I got the following error message:
{
error: {
errors: [
{
domain: "global",
reason: "required",
message: "Missing end time."
}
],
code: 400,
message: "Missing end time."
}
}
I request the site with cURL in PHP. To count the Content-Length for the request I using the function countArrayChars(). The following is my code:
$start = date("c", strtotime($start));
$end = date("c", strtotime($end));
$data_array = array(
"end"=>array("dateTime"=>$end),
"start"=>array("dateTime"=>$start),
"summary"=>$name
);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'https://www.googleapis.com/calendar/v3/calendars/primary/events',
CURLOPT_POST => 1,
CURLOPT_HTTPHEADER => array("Content-length: ".countArrayChars($data_array),"Content-type: application/json","Authorization: Bearer $access_token\r\n"),
CURLOPT_POSTFIELDS => $data_array
));
$resp = curl_exec($curl);
curl_close($curl);
echo $resp;
function countArrayChars(array $array){
$charNumber = 0;
array_walk_recursive($array, function($val, $key) use (&$charNumber)
{
$charNumber += strlen($val) + strlen($key);
});
return $charNumber;
}
What I also tried is to set the data as a http_build_query, as well as a json_encode result. Unfortunately this also didn't work.
Thanks for every response.
UPDATE:
$data_array = array(
"end"=>array("dateTime"=>$end,"timeZone"=>"Europe/Zurich"),
"start"=>array("dateTime"=>$start,"timeZone"=>"Europe/Zurich"),
"summary"=>$name
);
UPDATE 2:
This is the output of $end
string(25) "2017-03-10T00:00:00+01:00"
I don't know if this will help you, but this is the code I use to add events to google calendar through the API:
$event = new Google_Service_Calendar_Event(array(
'summary' => $summary,
'location' => $location,
'description' => $description,
'start' => array(
'dateTime' => $startdatetime,
'timeZone' => 'America/Los_Angeles',
),
'end' => array(
'dateTime' => $enddatetime,
'timeZone' => 'America/Los_Angeles',
),
'reminders' => array(
'useDefault' => FALSE,
),
));
You usually need to add a timezone, like I have, which could be your problem. I would suggest trying that out first.
Update:
I can't find anything else that could be wrong with your code, it's probably something having to do with how Google accepts data. All I can offer you now is exactly how I do mine, which I know works:
First, follow the instructions here to setup service account, if not done already. Make sure to create a .p12 file, instead of JSON.
You can download the PHP Google Calendar File here as well, without needing to use composer.
Next, work with the code below to suit your needs, but this should work for you. (The dateTime was properly formatted before it was sent in POST, so you may need to change that)
header('Content-type: application/json');
require_once __DIR__ . '/google-api-php-client/src/Google/autoload.php';
$summary = $_POST["summary"];
$location = $_POST["location"];
$description = $_POST["description"];
$startdatetime = $_POST["startdatetime"];
$enddatetime = $_POST["enddatetime"];
$client_email = "clientemail"; //client email setup when you create the authorization in Google Developer Console.
$private_key = file_get_contents("privatekey.p12"); //location on your server where the .p12 file you created is stored
$scopes = array('https://www.googleapis.com/auth/calendar');
$user_to_impersonate = "primary"; //This can also be an email address associated with the current gmail login if you don't want to use the default one
$credentials = new Google_Auth_AssertionCredentials(
$client_email,
$scopes,
$private_key,
'notasecret', // Default P12 password
'http://oauth.net/grant_type/jwt/1.0/bearer', // Default grant type
$user_to_impersonate
); //Keep everything in this array the same
$client = new Google_Client();
$client->setAssertionCredentials($credentials);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion();
}
$event = new Google_Service_Calendar_Event(array(
'summary' => $summary,
'location' => $location,
'description' => $description,
'start' => array(
'dateTime' => $startdatetime,
'timeZone' => 'America/Los_Angeles',
),
'end' => array(
'dateTime' => $enddatetime,
'timeZone' => 'America/Los_Angeles',
),
'reminders' => array(
'useDefault' => FALSE,
),
));
$service = new Google_Service_Calendar($client);
$calendarId = $useremail;
$event = $service->events->insert($calendarId, $event);
echo json_encode($event);
Check that $start is less than $end.
the error of google is not correct.
you have to check al inputfield for strange symbols. I had Straße in locationfield...that gave the missing endtime error.
Hi the problem may be on special characters in the variable, must try to encode UTF-8.
please try this
'summary' => utf8_encode($summary),
'description' => utf8_encode($descripcion),
'location' => utf8_encode($location),
regards,
Luis

Categories