Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Facebook Ads Sdk doesn't allow to post ad via API. Subcode: 1487930

I've read a lot about facebook ads and stuff, using GUI it allow to do what I'm doing and for some reason on sdk it doesn't.

I get this suberror code on Facebook ads sdk subcode 1487930.

The message says:

You Must Select an Object to Promote, the user message says: Your campaign must > include an ad set with a selected object to promote related to your objective > > (ex: Page, URL, event). Please update your ad set to continue.

Response returns no fields to blame and error happens when creative is being created: $creative->create();

I setup my adset like this:

    use Facebook;
    use FacebookAds\Api;
    use FacebookAds\Object;
    use Facebook\Exceptions;

        $inventory = new Models\AdvertisingInventory();
        $item = $inventory->getListing($id)->getAttributes();
        $item['properties'] = json_decode($item['properties'], true);

        /**
         * Step 1 Instantiate an API
         *
         * @link https://developers.facebook.com/docs/marketing-api/sdks#init-sdk
         */

        try {
            Api::init($this->app_id, $this->app_secret, $this->access_token);
        } catch (\Exception $e) {
            return $this->AdvertisingRenderErrorMessage($e);
        }

        /**
         * Step 2 Query to create campaign
         * @var $campaign
         * @link https://developers.facebook.com/docs/marketing-api/reference/ad-campaign-group
         *
         * TODO: Implement ad image widget sizing: https://www.facebook.com/business/help/103816146375741
         */
        try {

            $account = new Object\AdAccount($this->current_facebook_ads_account);

            $campaign = new Object\Campaign(null, $this->current_facebook_ads_account); // Getting AdAccount instance

            $ad_campaigns = $account->getCampaigns($campaign::getFields())->getArrayCopy(); // Checks of there are any campaigns already created

            $current_campaign = null;

            if (!empty($ad_campaigns)) {
                foreach ($ad_campaigns as $ad_campaign) { // loops through campaigns
                    $campaign_data = $ad_campaign->exportAllData();
                    if ($campaign_data['name'] == 'Sell old inventory') { // If campaign name matches the name given to new campaign, created campaign is then used
                        $current_campaign = $ad_campaign;
                    }
                }
            }

            if (!is_null($current_campaign)) { // Checks if campaign is already assigned if yes, then its used.
                $campaign = $current_campaign;
            } else { // else new one is created
                $campaign->setData(array(
                    Object\Fields\CampaignFields::NAME => 'Sell old inventory',
                    Object\Fields\CampaignFields::OBJECTIVE => Object\Values\CampaignObjectiveValues::LINK_CLICKS,
                ));

                $campaign->validate()->create(array(
                    Object\Campaign::STATUS_PARAM_NAME => Object\Campaign::STATUS_PAUSED
                ));
            }

            //$campaignData = $campaign->getData();

            echo 'Campaign ID: ' . $campaign->id . " <br>\n";

        } catch (\Exception $e) {
            return $this->AdvertisingRenderErrorMessage($e);
        }

        /**
         * Step 3 Search for targeting topic
         * @var $targeting
         * @link https://developers.facebook.com/docs/marketing-api/targeting-specs/v2.7
         */
        try {
            $results = Object\TargetingSearch::search(
                Object\Search\TargetingSearchTypes::INTEREST,
                null,
                'Automobiles');

            $target = (count($results)) ? $results->current() : null;

            //if (!is_null($target)) {

            echo "Using target: " . $target->name . "<br/>";

            $targeting = new Object\Targeting();
            $targeting->{Object\Fields\TargetingFields::GEO_LOCATIONS} = array(
                'countries' => array('NZ')
            );
            $targeting->{Object\Fields\TargetingFields::INTERESTS} = array(
                array(
                    'id' => $target->id,
                    'name' => $target->name,
                ),
            );
            //}
        } catch (\Exception $e) {
            return $this->AdvertisingRenderErrorMessage($e);
        }

        /**
         * Step 4 Create an AdSet
         * @var $adset
         * @link https://developers.facebook.com/docs/marketing-api/reference/ad-campaign
         */
        try {

            $adset = new Object\AdSet(null, $this->current_facebook_ads_account);
            //$fields = $adset::getFields();

            $available_adsets = $campaign->getAdSets(array(Object\Fields\AdSetFields::NAME,Object\Fields\AdSetFields::ID));

            $current_adset = null;

            if (!empty($available_adsets)) {
                foreach ($available_adsets as $ad_set) { // loops through adsets
                    if ($adset->name == $item['title']) { // If adset name matches the name given to new campaign, created campaign is then used
                        $current_adset = $ad_set;
                    }
                }
            }

            if (!is_null($current_adset)) {
                $adset = $current_adset;
                /*$adset->read(array(
                    Object\Fields\AdSetFields::PROMOTED_OBJECT,
                    Object\Fields\AdSetFields::NAME
                ));
                echo $adset->name."<br>";
                echo $adset->promoted_object."<br>";*/
            } else {

                $start_time = (new \DateTime("+1 week"))->format(\DateTime::ISO8601);
                $end_time = (new \DateTime("+2 week"))->format(\DateTime::ISO8601);


                $adset->setData(array(
                    Object\Fields\AdSetFields::NAME => $item['title'],
                    Object\Fields\AdSetFields::OPTIMIZATION_GOAL => Object\Values\AdSetOptimizationGoalValues::LINK_CLICKS,
                    Object\Fields\AdSetFields::BILLING_EVENT => Object\Values\AdSetBillingEventValues::LINK_CLICKS,
                    Object\Fields\AdSetFields::BID_AMOUNT => 100,
                    Object\Fields\AdSetFields::DAILY_BUDGET => 500,
                    Object\Fields\AdSetFields::CAMPAIGN_ID => $campaign->id,
                    Object\Fields\AdSetFields::TARGETING => $targeting,
                    Object\Fields\AdSetFields::START_TIME => $start_time,
                    Object\Fields\AdSetFields::END_TIME => $end_time,
                    Object\Fields\AdSetFields::PROMOTED_OBJECT => (object) array(
                        Object\Fields\AdPromotedObjectFields::PAGE_ID => '178698438995498',
                    )
                ));
                $adset->create(array(
                    Object\AdSet::STATUS_PARAM_NAME => Object\AdSet::STATUS_PAUSED,
                ));
            }
            echo 'Adset ID: ' . $adset->id . " <br>\n";
        } catch (\Exception $e) {
            return $this->AdvertisingRenderErrorMessage($e);
        }


        //New method
        /**
         * Step 5 Create an AdImage
         * @var $image
         * @link https://developers.facebook.com/docs/marketing-api/reference/ad-image
         */
        try {
            $image = new Object\AdImage(null, $this->current_facebook_ads_account); // Invokes images preparation for Facebook ad instance
            $target_path = __DIR__ . '/assets/temp/'; // path where images will be streamed to

            if (!file_exists($target_path)) {
                mkdir($target_path, 0755); // creating path if one doesn't exist
            }

            $files_in_dir = array_diff(scandir($target_path), array('..', '.')); // checking for existing files in target directory
            $size = getimagesize($item['properties']['images_large'][0]); // getting image details
            $extension = image_type_to_extension($size[2]); // getting image extension from type
            $target_file_name = preg_replace(['/\./', '/\\s/', '/\\t/'], "_", strtolower($item['title'])) . $extension; // creating proper file name
            $target_file = $target_path . $target_file_name; // setting full target directory

            if (array_search($target_file_name, $files_in_dir) === false) { // checking if target file already exists

                $image_file = file_get_contents($item['properties']['images_large'][0]);

                file_put_contents($target_file, $image_file);
            }

            $image->{Object\Fields\AdImageFields::FILENAME} = $target_file; // Using target file as ad image

            $image->create();

            echo 'Image Hash: ' . $image->hash . " <br>\n";
        } catch (\Exception $e) {
            return $this->AdvertisingRenderErrorMessage($e);
        }

        /**
         * Step 6 Create an AdCreative
         */
        try {

            $creative = new Object\AdCreative(null, $this->current_facebook_ads_account);

            $available_creatives = $adset->getAdCreatives($creative::getFields());

            $current_creative = null;

            if (!empty($available_creatives)) {
                foreach ($available_creatives as $creative) { // loops through adsets
                    if ($creative->name == 'Creative of '.$item['title']) { // If adset name matches the name given to new campaign, created campaign is then used
                        $current_creative = $creative;
                    }
                }
            }

            if (!is_null($current_creative)) {
                $creative = $current_creative;
            } else {

                $creative = new Object\AdCreative(null, $this->current_facebook_ads_account);
                $creative->setData(array(
                    Object\Fields\AdCreativeFields::NAME => 'Creative of '.$item['title'],
                    Object\Fields\AdCreativeFields::TITLE => $item['title'],
                    Object\Fields\AdCreativeFields::BODY => $item['properties']['description'],
                    Object\Fields\AdCreativeFields::IMAGE_HASH => $image->hash,
                    Object\Fields\AdCreativeFields::LINK_URL => ipConfig()->get('globalPortalUrl'),
                    Object\Fields\AdCreativeFields::OBJECT_URL => ipConfig()->get('globalPortalUrl'),
                ));
                **$creative->create();**
            }
            echo 'Creative ID: ' . $creative->id . " <br>\n";
        } catch (\Exception $e) {
            return $this->AdvertisingRenderErrorMessage($e);
        }


        /**
         * Step 7 Create an Ad
         *
         * Then, use the image hash returned from above. Finally, create your ad along with ad creative.
         * Please note that the ad creative is not created independently, rather its data structure
         * is appended to the ad group
         *
         * @link https://developers.facebook.com/docs/marketing-api/reference/adgroup
         */
        try {

            $ad = new Object\Ad(null, $this->current_facebook_ads_account);

            $last_ad = $adset->getAds($ad::getFields())->end()->exportData();

            //var_dump($last_ad); exit();

            $ad->setData(array(
                Object\Fields\AdFields::NAME => $item['title'].' #1',
                Object\Fields\AdFields::ADSET_ID => $adset->id,
                Object\Fields\AdFields::CREATIVE => array('creative_id' => $creative->id),
            ));
            $ad->create(array(
                Object\Ad::STATUS_PARAM_NAME => Object\Ad::STATUS_PAUSED,
            ));
            echo 'Ad ID:' . $ad->id . " <br>\n";

        } catch (\Exception $e) {
            return $this->AdvertisingRenderErrorMessage($e);

        }

I assigned that page to my business account and that app which the query goes through as well the user is the owner of business account, the app and the page.

What else does it need if the the page id is provided? The Campaign objective is:

Object\Fields\CampaignFields::OBJECTIVE => Object\Values\CampaignObjectiveValues::LINK_CLICKS

I use valid page_id. I'm I missing some extra data for the (FYI tried this without (object) typehint):

Object\Fields\AdSetFields::PROMOTED_OBJECT => (object) array(
    Object\Fields\AdPromotedObjectFields::PAGE_ID => '178698438995498',
)

Or there are problems with app, page and business account settings?

Please someone answer my calls. Tried almost everything can't pass this point. Any other promoted objects do not work with the campaign objective.

P.S. Someone with reputation more then 1500 please create ne facebook-php-ads-sdk tag.

like image 214
juslintek Avatar asked Jul 22 '16 16:07

juslintek


1 Answers

I was having this error because I was using the wrong parameter name when creating an Adcreative. I was using page_id instead of object_id.

Hope it can help someone.

like image 199
Éric Bergeron Avatar answered Nov 15 '22 04:11

Éric Bergeron