GithubHelp home page GithubHelp logo

facebook-nodejs-business-sdk's Introduction

Facebook Business SDK for NodeJS

License

Introduction

The Facebook Business SDK is a one-stop shop to help our partners better serve their businesses. Partners are using multiple Facebook API's to serve the needs of their clients. Adopting all these API's and keeping them up to date across the various platforms can be time consuming and ultimately prohibitive. For this reason Facebook has developed the Business SDK bundling many of its APIs into one SDK to ease implementation and upkeep. The Business SDK is an upgraded version of the Marketing API SDK that includes the Marketing API as well as many Facebook APIs from different platforms such as Pages, Business Manager, Instagram, etc.

This SDK can be used for both server side as well as client side. It comes with ECMAScript 5 bundled minified distribution with source maps of AMD, CommonJS modules, IIFE, as UMD and as Browser Globals.

Quick Start

Business SDK Getting Started Guide

Pre-requisites

Dependencies

Gulp and Bower should be installed globally. Install dependencies:

npm install
bower install

Checkout gulpfile.js for all available tasks.

Register An App

To get started with the SDK, you must have an app registered on developers.facebook.com.

To manage the Marketing API, please visit your App Dashboard and add the Marketing API product to your app.

IMPORTANT: For security, it is recommended that you turn on 'App Secret Proof for Server API calls' in your app's Settings->Advanced page.

Obtain An Access Token

When someone connects with an app using Facebook Login and approves the request for permissions, the app obtains an access token that provides temporary, secure access to Facebook APIs.

An access token is an opaque string that identifies a User, app, or Page.

For example, to access the Marketing API, you need to generate a User access token for your app and ask for the ads_management permission; to access Pages API, you need to generate a Page access token for your app and ask for the manage_page permission.

Refer to our Access Token Guide to learn more.

For now, we can use the Graph Explorer to get an access token.

Installation

NPM

npm install --save facebook-nodejs-business-sdk

Bower

bower install --save facebook-nodejs-business-sdk

Usage

Access Token

When someone connects with an app using Facebook Login and approves the request for permissions, the app obtains an access token that provides temporary, secure access to Facebook APIs.

An access token is an opaque string that identifies a User, app, or Page.

For example, to access the Marketing API, you need to generate a User access token for your app and ask for the ads_management permission; to access Pages API, you need to generate a Page access token for your app and ask for the manage_page permission. Refer to our Access Token Guide to learn more.

For now, we can use the Graph Explorer to get an access token.

const adsSdk = require('facebook-nodejs-business-sdk');
const accessToken = '<VALID_ACCESS_TOKEN>';
const api = adsSdk.FacebookAdsApi.init(accessToken);

Api main class

The FacebookAdsApi object is the foundation of the Business SDK which encapsulates the logic to execute requests against the Graph API. Once instantiated, the Api object will allows you to start making requests to the Graph API.

Facebook Objects

Facebook Ads entities are defined as classes under the src/objects directory.

// instantiating an object
const adsSdk = require('facebook-nodejs-business-sdk');
const AdAccount = adsSdk.AdAccount;
const account = new AdAccount('act_<AD_ACCOUNT_ID>');
console.log(account.id) // fields can be accessed as properties

Fields

Due to the high number of field names in the existing API objects, in order to facilitate your code maintainability, enum-like field objects are provided within each node class. The fields are stored within node object classes which are stored under the src/objects directory. You can access object properties like this:

const adsSdk = require('facebook-nodejs-business-sdk');
const accessToken = '<VALID_ACCESS_TOKEN>';
const api = adsSdk.FacebookAdsApi.init(accessToken);
const AdAccount = adsSdk.AdAccount;
const Campaign = adsSdk.Campaign;
const account = new AdAccount('act_<AD_ACCOUNT_ID>');

console.log(account.id) // fields can be accessed as properties
account
  .createCampaign(
    [Campaign.Fields.Id],
    {
      [Campaign.Fields.name]: 'Page likes campaign', // Each object contains a fields map with a list of fields supported on that object.
      [Campaign.Fields.status]: Campaign.Status.paused,
      [Campaign.Fields.objective]: Campaign.Objective.page_likes
    }
  )
  .then((result) => {
  })
  .catch((error) => {
  });

Read Objects

const adsSdk = require('facebook-nodejs-business-sdk');
const accessToken = '<VALID_ACCESS_TOKEN>';
const api = adsSdk.FacebookAdsApi.init(accessToken);
const AdAccount = adsSdk.AdAccount;
const account = new AdAccount('act_<AD_ACCOUNT_ID>');
account
  .read([AdAccount.Fields.name, AdAccount.Fields.age])
  .then((account) => {
    console.log(account);
  })
  .catch((error) => {
  });

Requesting an high number of fields may cause the response time to visibly increase, you should always request only the fields you really need.

Create Objects

const adsSdk = require('facebook-nodejs-business-sdk');
const accessToken = '<VALID_ACCESS_TOKEN>';
const api = adsSdk.FacebookAdsApi.init(accessToken);
const AdAccount = adsSdk.AdAccount;
const Campaign = adsSdk.Campaign;
const account = new AdAccount('act_<AD_ACCOUNT_ID>');
account
  .createCampaign(
    [],
    {
      [Campaign.Fields.name]: 'Page likes campaign',
      [Campaign.Fields.status]: Campaign.Status.paused,
      [Campaign.Fields.objective]: Campaign.Objective.page_likes
    }
  )
  .then((campaign) => {
  })
  .catch((error) => {
  });

Update Objects

const adsSdk = require('facebook-nodejs-business-sdk');
const accessToken = '<VALID_ACCESS_TOKEN>';
const api = adsSdk.FacebookAdsApi.init(accessToken);
const Campaign = adsSdk.Campaign;
const campaignId = <CAMPAIGN_ID>;
new Campaign(campaignId, {
  [Campaign.Fields.id]: campaign.id,
  [Campaign.Fields.name]: 'Campaign - Updated' })
  .update();

Delete Objects

const adsSdk = require('facebook-nodejs-business-sdk');
const accessToken = '<VALID_ACCESS_TOKEN>';
const api = adsSdk.FacebookAdsApi.init(accessToken);
const Campaign = adsSdk.Campaign;
const campaignId = <CAMPAIGN_ID>;
new Campaign(campaignId).delete();

Pagination

Since the release of the Facebook Graph API 2.0, pagination is handled through cursors.

Here cursors are defined as in src\cursor.js. When fetching nodes related to another (Edges) or a collection in the graph, the results are paginated in a Cursor class. Here the Cursor is a superpowered Array (with all it's native helpful operations) with next and previous methods that when resolved fills itself with the new set of objects.

const adsSdk = require('facebook-nodejs-business-sdk');
const accessToken = '<VALID_ACCESS_TOKEN>';
const api = adsSdk.FacebookAdsApi.init(accessToken);
const AdAccount = adsSdk.AdAccount;
const Campaign = adsSdk.Campaign;
const account = new AdAccount('act_<AD_ACCOUNT_ID>');
account.getCampaigns([Campaign.Fields.name], { limit: 2 })
.then((campaigns) => {
  if (campaigns.length >= 2 && campaigns.hasNext()) {
    return campaigns.next();
  } else {
    Promise.reject(
      new Error('campaigns length < 2 or not enough campaigns')
    );
  }
})
.then((campaigns) => {
  if (campaigns.hasNext() && campaigns.hasPrevious()) {
    return campaigns.previous();
  } else {
    Promise.reject(
      new Error('previous or next is not true')
    );
  }
  return campaigns.previous();
})
.catch((error) => {
});

If you are using cursor to iterate all of your object under your Ad Account, this practice is recommended.

const adsSdk = require('facebook-nodejs-ads-sdk');
const accessToken = '<VALID_ACCESS_TOKEN>';
const api = adsSdk.FacebookAdsApi.init(accessToken);
const AdAccount = adsSdk.AdAccount;
const account = new AdAccount('act_<AD_ACCOUNT_ID>');

void async function () {
    let campaigns = await account.getCampaigns([Campaign.Fields.name], {limit: 20});
    campaigns.forEach(c => console.log(c.name));
    while (campaigns.hasNext()) {
        campaigns = await campaigns.next();
        campaigns.forEach(c => console.log(c.name));
    }
}();

Debugging

A FacebookAdsApi object offers a debugging mode that will log all requests. To enable it just call api.setDebug(true) on an API instance.

const adsSdk = require('facebook-nodejs-business-sdk');
const accessToken = '<VALID_ACCESS_TOKEN>';
const api = adsSdk.FacebookAdsApi.init(accessToken);
api.setDebug(true);

Style

This package uses type safe javascript. Flow. Inconsistent code will break builds.

SDK Codegen

Our SDK is autogenerated from SDK Codegen. If you want to learn more about how our SDK code is generated, please check this repository.

Join the Facebook Marketing Developer community

License

Facebook Business SDK for NodeJS is licensed under the LICENSE file in the root directory of this source tree.

facebook-nodejs-business-sdk's People

Contributors

jingping2015 avatar vicdus avatar HeyMultiverse avatar marksliva avatar zanyaziz avatar davit-y avatar donglinw-fb avatar supasate avatar codytwinton avatar ellentao avatar facebook-github-bot avatar flarnie avatar hsimah avatar hieptuanle avatar josescasanova avatar Mxiim avatar michaelwclark avatar stcheng avatar simoncpu avatar kongxinzhu avatar windsfantasy6 avatar

Stargazers

 avatar Amjad Rana avatar Kevin avatar Mint Academy avatar Paulo avatar Ferdian Ahmad R avatar Muhammad Zakir Ramadhan avatar Raihan Muhammad avatar Nusendra Hanggarawan avatar Sanishka avatar Rohan Rajpal avatar  avatar stone avatar Frantisek Blaha avatar  avatar  avatar  avatar  avatar Quan Nguyen avatar Anton Novik avatar Brahim Akarouch avatar  avatar Faisal Ramdan avatar Marcus Mello avatar John Munson avatar Alejandro Jesus del Campillo Jaime avatar Mihail Ilinov avatar xianda avatar  avatar Carr.z.w avatar  avatar  avatar  avatar Princeallan avatar Felipe Magno de Almeida avatar Danilo Alves avatar Sergey Leschev avatar Joseph D. Sumner avatar chvndler avatar Yeji Choi avatar Nathan Lucy avatar Vitalii Apostolyuk avatar  avatar  avatar fahmi irfan avatar  avatar Kyrylo Avramenko avatar  avatar khomkrit Uparakham  avatar Serhii Matrunchyk avatar Shaun avatar Leo Vujanić avatar Hamed Baatour avatar  avatar Carl-W avatar  avatar Patrick Chan avatar DanFael.me avatar Oleksii Kholiavko avatar  avatar  avatar Leo avatar  avatar Iarlen Aquiles avatar Edoardo Mazzon avatar Simone Fusco avatar Thuraya Gaber avatar World Elite avatar Le Van Loc avatar  avatar antx avatar 卓文理 avatar aleks khram avatar Keany Vy KHUN avatar  avatar  avatar Shane Beeston avatar Giri Laya Bahari avatar Dan Pappo avatar Alexandre Pereira Nunes avatar Ai avatar Rajesh Koilpillai avatar Andrew Ross avatar Mohamed Hany avatar Alessandro avatar Ramin  avatar José Paucar avatar Sam avatar Wichai Sawangpongkasame avatar Nick Treffiletti avatar Matthew Spach avatar João Vitor M. Lopes avatar Coby Eastwood avatar CIM Soluções Web avatar  avatar copter.js avatar Chien Nghe avatar Karl Pawlowicz avatar Sudarshana Dayananda avatar Xavier Roussel avatar

Watchers

Supasate "Ping" Choochaisri avatar Lars Enevold avatar  avatar  avatar James Cloos avatar Flarnie Marchan avatar Michael W Clark avatar Thomas Donnelly avatar jose avatar Cemal Karabulaklı avatar Cody Winton avatar Joe Susnick avatar Seo avatar Harry avatar Oleksandr avatar Josue Brizuela avatar  avatar  avatar John Tsai avatar Mouwu Lin avatar spcent avatar Jing Ping avatar DanFael.me avatar Moyang avatar Zain Aziz avatar Per Engberg Habazin avatar  avatar  avatar  avatar u4bi avatar DAVID TIM avatar Ram avatar  avatar Danilo Alves avatar  avatar  avatar  avatar  avatar Caleb Daniel avatar NiNeW avatar  avatar  avatar  avatar  avatar  avatar

facebook-nodejs-business-sdk's Issues

How can I create a campaign as an A / B test?

I have made adStudy.
but It is not reflected in the advertisement manager.

To create a campaign as an A / B test, create a campaign with iterative_split_test_configs ?
please tell me iterative_split_test_configs's sample.

Or update a campaign with adStudy's id ??

Versioning Issues

Hi ,

I am pretty much a noob to nodejs, javascript and the facebook API. So I apologies if this bug report isn't as helpfull as it could be.

I created a new Facebook App (today) and I am trying to get some ad insights (account.getInsights) but running into a versioning issue :

FacebookRequestError: (#2635) You are calling a deprecated version of the Ads API. Please update to the latest version: v2.12.
at FacebookRequestError.FacebookError [as constructor] (/Users/yoann/dev/src/track.jackmedia.io/node_modules/facebook-nodejs-ads-sdk/dist/cjs.js:319:16)
at new FacebookRequestError (/Users/yoann/dev/src/track.jackmedia.io/node_modules/facebook-nodejs-ads-sdk/dist/cjs.js:341:129)
at /Users/yoann/dev/src/track.jackmedia.io/node_modules/facebook-nodejs-ads-sdk/dist/cjs.js:507:15
at runCallback (timers.js:781:20)
at tryOnImmediate (timers.js:743:5)
at processImmediate [as _immediateCallback] (timers.js:714:5)

Guessing this is related to yesterday 2.12 release :
https://developers.facebook.com/ads/blog/post/2018/01/30/graph-api-212-release/

Any tips would be much appreciated ...

screen shot 2018-02-01 at 2 42 46 pm

Token Refresh

Hi, is there a way to refresh access token here? or it is auto managed by the sdk given the first initial access token? thanks!

Effective status filter fails

I'm attempting to fetch all ads that are currently active, accoring to the Ads Manager page, that should be about 130 ads. Yet when this is ran I'm easily getting over 300 (I killed the server at that point). I'm getting ads that have been completed or ended months and sometimes years ago. Not sure if my query is setup incorrectly or if I'm confusing how the effective status is set for the ads. All I need is just the list of current ads that are being delivered.

This is what I'm using to get all the ads:

const ad_fields = [
  Ad.Fields.name,
  Ad.Fields.id,
  Ad.Fields.effective_status,
  Ad.Fields.created_time,
  Ad.Fields.updated_time,
  Ad.Fields.status
];
const ad_filters = {
  [Ad.Fields.effective_status]: [Ad.ConfiguredStatus.active],
}

account
.getAds(ad_fields, ad_filters)
.then(handle_res)
.catch(err => console.error(err));

Anyone had this issue before or have any advice?

Error upon updating the AdSet flexible_spec when it contains inactive Ads

I'm updating a bunch of adsets, and not sure why the part of them is throwing the error on update. I haven't found the description of this error in facebook docs nor here hence opening an issue. My use case is to remove flexible_spec field, so I'm pushing an empty array as a value of the property. It works for most of my adset updates but there are certain cases when it doesn't. Thank you for taking a look

Error

  status: 400,
  response:
   { error:
      { message: 'Invalid parameter',
        type: 'OAuthException',
        code: 100,
        error_subcode: 1885502,
        is_transient: false,
        error_user_title: 'Unable To Generate Display Formats',
        error_user_msg: 'Could not generate display formats for this ad',
        fbtrace_id: 'CIWB3GjOsxv' } },
  method: 'POST',
  url:
   'GRAPH_API_URL',
  data:
   { id: 'ID',
     targeting:
      { age_max: 55,
        age_min: 30,
        flexible_spec: [],
        geo_locations: [Object],
        targeting_optimization: 'expansion_all',
        publisher_platforms: [Array],
        facebook_positions: [Array],
        instagram_positions: [Array],
        device_platforms: [Array],
        custom_audiences: [Array] } } }

[FacebookRequestError] (#2663) Terms of service has not been accepted.

I ran the sample code from the docs of facebook marketing api. And I am continuously getting this error.

{"name":"FacebookRequestError","message":"(#2663) Terms of service has not been accepted. To accept, go to https://www.facebook.com/customaudiences/app/tos/?act=xxxxxxxxx","stack":"Error\n at FacebookRequestError.FacebookError [as constructor] (/app/node_modules/facebook-nodejs-ads-sdk/dist/cjs.js:319:16)\n at new FacebookRequestError (/app/node_modules/facebook-nodejs-ads-sdk/dist/cjs.js:341:129)\n at /app/node_modules/facebook-nodejs-ads-sdk/dist/cjs.js:507:15\n at tryCatcher (/app/node_modules/bluebird/js/release/util.js:16:23)\n at Promise._settlePromiseFromHandler (/app/node_modules/bluebird/js/release/promise.js:512:31)\n at Promise._settlePromise (/app/node_modules/bluebird/js/release/promise.js:569:18)\n at Promise._settlePromise0 (/app/node_modules/bluebird/js/release/promise.js:614:10)\n at Promise._settlePromises (/app/node_modules/bluebird/js/release/promise.js:689:18)\n at Async._drainQueue (/app/node_modules/bluebird/js/release/async.js:133:16)\n at Async._drainQueues (/app/node_modules/bluebird/js/release/async.js:143:10)\n at Immediate.Async.drainQueues (/app/node_modules/bluebird/js/release/async.js:17:14)\n at runCallback (timers.js:789:20)\n at tryOnImmediate (timers.js:751:5)\n at processImmediate [as _immediateCallback] (timers.js:722:5)","status":400,"response":{"error":{"message":"(#2663) Terms of service has not been accepted. To accept, go to https://www.facebook.com/customaudiences/app/tos/?act=xxxxxxxx","type":"OAuthException","code":2663,"fbtrace_id":"xxxxxx"}},"method":"POST","url":"https://graph.facebook.com/v2.11/act_xxxxxxx/customaudiences?access_token=xxxxxx","data":{"name":"Past 30 days","pixel_id":"xxxxxx","prefill":true,"rule":{"url":{"i_contains":""}},"subtype":"WEBSITE","retention_days":"30","id":"act_xxxxxxxx"}}

The error provides a link which is invalid (facebook says). May be this error is not related with the implementation of this package. But is there anyone who knows the reason for this error.

AdVideo example needed

I am trying to figure out how to build a creative that uses a video. However, there aren't any docs or examples that show how to accomplish this. I tried the following based on a working AdImage function that I have

async function createAdVideo(accountId, filepath) {
  const AdAccount = adsSdk.AdAccount;
  const account = new AdAccount(accountId);
  const AdVideo = adsSdk.AdVideo;
  
  var video = await account
  .createAdVideo(
    [],
    {
      [AdVideo.Fields.filepath]: filepath
    }
  )
  
  return video
}

But all I ever get is "FacebookRequestError: Video Upload Time Out: Your video upload timed out before it could be completed. This is probably because of a slow network connection or because the video you're trying to upload is too large. Please try again."

Code with problems on README.md

Hey guys,

Sorry to bother with this, however I code in JS (node, react, angular, etc) and I have never seen the way you write code before.

That said, I am having some issues with the tutorial code on the README.md file. I would really appreciate if you could explain it to me.

I am trying to read some campaign and account objects, but I have some doubts here:

const adsSdk = require('facebook-nodejs-ads-sdk');
const accessToken = '<VALID_ACCESS_TOKEN>';
const api = adsSdk.FacebookAdsApi.init(accessToken);
const AdAccount = adsSdk.AdAccount;
const account = new AdAccount('act_<AD_ACCOUNT_ID>');
account
 .read([AdAccount.Fields.name, AdAccount.Fields.age])
 .then((account) => {
   logPassedTest(test1 + ':Pass', account);
 })
 .catch((error) => {
 });
  1. Where is logPassedTest defined?
  2. Where is test1 defined and used before logging?
  3. How can I iterate over all campaigns of one ad_account?

Thanks!

Wrong case of properties in ads-insight object

Got this error when calling the API using properties from the ads-insight object:

"(#100) breakdowns[0] must be one of the following values: age, country, dma, gender, frequency_value, hourly_stats_aggregated_by_advertiser_time_zone, hourly_stats_aggregated_by_audience_time_zone, impression_device, place_page_id, publisher_platform, platform_position, device_platform, product_id, region"

The HTTP call sent has the breakdowns in uppercase like this:
breakdowns: PUBLISHER_PLATFORM,IMPRESSION_DEVICE

Made a pull request to fix:
#14

package.json dependancies seem off and bloated.

package.json

here
"mixwith": "~0.1.1",
"request": "^2.81.0",
"request-promise": "~4.1.1",
Are the only deps that make sense to me here. Not sure why all the others made it in. They should be in dev dependancies. Unneeded bloat for everyone who uses your package.

Error: read ECONNRESET when updating targeting in AdSet

Here is the piece of the code that does the update. My use case is to query the adsets, filter them by needed AdSet ID and then add/remove the custom_audience withing the targeting. Am I doing it the wrong way or it is the bug withing sdk? Thank you

Code snippet

 return new AdSet(searchAdSet.id, {
              [AdSet.Fields.id]: searchAdSet.id,
              [AdSet.Fields.targeting]: {
                age_max: 80,
                age_min: 25,
                custom_audiences: [
                  {
                    id: 'ID',
                    name: 'NAME'
                  },
                ],
                geo_locations: {
                  cities: [
                    {
                      country: 'US',
                      distance_unit: 'mile'
                    }
                  ]
                }
              }
            }).update();

Stack trace

FacebookRequestError: Error: read ECONNRESET
. StackTrace:
 Error
    at FacebookRequestError.FacebookError [as constructor] (./node_modules/facebook-nodejs-business-sdk/dist/cjs.js:319:16)
    at new FacebookRequestError (./node_modules/facebook-nodejs-business-sdk/dist/cjs.js:341:129)
    at ./node_modules/facebook-nodejs-business-sdk/dist/cjs.js:507:15
    at tryCatcher (./node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (./node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (./node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (./node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (./node_modules/bluebird/js/release/promise.js:689:18)
    at Async._drainQueue (./node_modules/bluebird/js/release/async.js:133:16)
    at Async._drainQueues (./node_modules/bluebird/js/release/async.js:143:10)
    at Immediate.Async.drainQueues [as _onImmediate] (/Users/aam/wip/fb/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:696:18)
    at tryOnImmediate (timers.js:667:5)
    at processImmediate (timers.js:649:5)```

Add support for v2.10

I have created a new application and I cannot use older version of the API. This is the error I get:

{ error:
  {
     message: '(#2635) You are calling a deprecated version of the Ads API. Please update to the latest version: v2.10.',
     type: 'OAuthException',
     code: 2635,
     fbtrace_id: 'HcmbKfHlScm' 
  }
},

Appsecret Proof?

IMPORTANT: For security, it is recommended that you turn on 'App Secret
Proof for Server API calls' in your app's Settings->Advanced page.

There does not appear to be any way to set or generate the appsecret_proof for calls to the APIs. This renders this whole new SDK useless to those of us who adhere to the above quote.

Am I missing something in the code or docs that is obvious or does this still need to be built?

If it's the later, I have built a generator and injector in my own npm module for accessing the graph apis and would gladly assist in bringing it into this project if this is needed..

TypeError: response.data.map is not a function

I'm trying to use getReachEstimate with a null fields array and a default set of params, but i'm not getting a proper response.
Response: {"data":{"users":242000000,"estimate_ready":true}}
above is the only response even if i modify the targeting_spec in any way.

Successful API Call not resolving correctly after http status 200

I'm getting this error thrown after the SDK has made a successful API-call (when checking network in Chrome devtools the API-call was successful and the correct data was returned from the API).

TypeError: Cannot read property 'error' of undefined
at new FacebookRequestError (cjs.js:339)
at eval (cjs.js:466)
at ZoneDelegate.invoke (zone.js:391)
at Object.onInvoke (core.es5.js:3890)
at ZoneDelegate.invoke (zone.js:390)
at Zone.run (zone.js:141)
.....

I've debugged the SDK and the problem seems to be in the XmlHttpRequest request method in http.js on line 54, request.status is a number 200 for me and HTTP_STATUS.OK is a string "200" so the types doesn't not match and the promise is incorrectly rejected even thought the http request was successfull:

if (request.status === HTTP_STATUS.OK) {
resolve(response);
} else {
reject(
new Error({
body: response,
status: request.status
})
);
}

Unable to create adCreative with multiple image slider

When I am executing following code I am getting an error like : "Ads creative post was created by an app that is in development mode. It must be in public to create this ad."

var main_page_id = "262809350963870"
var page_url = "https://www.facebook.com/Development-Page-262809350963870";
fb.api('/oauth/access_token', {
client_id: config.facebook_api_key,
client_secret: config.facebook_api_secret,
redirect_uri: 'https://localhost:4430/auth/callback',
code: req.query.code
}, function (res_accesstoken) {
if(!res_accesstoken || res_accesstoken.error) {
console.log(!res_accesstoken ? 'error occurred' : res_accesstoken.error);
return;
}
var accessToken = res_accesstoken.access_token;
fb.api('/me/adaccounts', { access_token: accessToken }, function (res_adaccounts) {
console.log(res_adaccounts);
const adsSdk = require('facebook-nodejs-business-sdk');
const api = adsSdk.FacebookAdsApi.init(accessToken);
api.setDebug(true);
const AdAccount = adsSdk.AdAccount;
const Campaign = adsSdk.Campaign;
const AdSet = adsSdk.AdSet;
const AdImage = adsSdk.AdImage;
const AdCreative = adsSdk.AdCreative;
const AdCreativeLinkData = adsSdk.AdCreativeLinkData;
const AdCreativeObjectStorySpec = adsSdk.AdCreativeObjectStorySpec;
const AdPromotedObject = adsSdk.AdPromotedObject;
const Targeting = adsSdk.Targeting;
const account = new AdAccount(res_adaccounts.data[0].id);
account
.createCampaign(
[Campaign.Fields.Id],
{
[Campaign.Fields.name]: 'Page likes campaign',
[Campaign.Fields.status]: Campaign.Status.paused,
[Campaign.Fields.objective]: Campaign.Objective.page_likes
}
)
.then((created_campaign) => {
account.createAdSet(
[AdSet.Fields.Id],
{
[AdSet.Fields.name]: "my ad set api",
[AdSet.Fields.bid_strategy]: "LOWEST_COST_WITHOUT_CAP",
[AdSet.Fields.daily_budget]: 15000,
[AdSet.Fields.billing_event]: "OFFER_CLAIMS",
[AdSet.Fields.campaign_id]: created_campaign.id,
[AdSet.Fields.name]: "my ad set api",
[AdSet.Fields.optimization_goal]: "REACH",
[AdSet.Fields.billing_event]: "IMPRESSIONS",
[AdSet.Fields.daily_budget]: 10000,
[AdSet.Fields.campaign_id]: created_campaign.id,
[AdSet.Fields.promoted_object]: {
[AdPromotedObject.Fields.page_id]:main_page_id
},
[AdSet.Fields.targeting]: {
[Targeting.Fields.geo_locations]: {"countries":["IN"]},
},
}
)
.then((created_adset) => {
var fs = require('fs'),
file = "/opt/abs/public/uploads/approved_images/1f355040-7b83-11e8-9362-4b330a745001.jpeg",
imageData = fs.readFileSync(file);
account.createAdImage(
[],
{
'bytes': imageData.toString('base64')
}).then((created_image) => {
account.createAd(
[],
{
adset_id:created_adset.id,
name : "first ad",
status:"PAUSED",
creative:{
"name": "ffffggggggg",
"object_type": "SHARE",
"thumbnail_url": "https://external.xx.fbcdn.net/safe_image.php?d=AQD_ypGlE3vlU0Pq&w=64&h=64&url=https\u00253A\u00252F\u00252Fwww.facebook.com\u00252Fads\u00252Fimage\u00252F\u00253Fd\u00253DAQIL6FlkVoGVS8VrET9FY0Gy3XnOi66jenFEK2A7z4pFpLe6eDBy5Gz4iX0L7MHGuBX-_pwR8m47naKzu5g4PVuhwCd1YYD8RNSRFXJuCITlelyBuk4VYd6STKLHhR1gYYs57qf4iEhaoJCx8sUDNILQ&cfs=1&_nc_hash=AQAFc20W4J002P2c",
"title": "Google",
"use_page_actor_override": false,
object_story_spec:{
page_id:main_page_id,
link_data:{
link:"http://google.co.in",
"attachment_style": "link",
"call_to_action": {
"type": "LEARN_MORE"
},
child_attachments:[{
link:"http://google.co.in",
name:"1111",
image_hash:created_image.images.bytes.hash,
"call_to_action": {
"type": "LEARN_MORE"
}
},{
link:"http://google.co.in",
name:"2222",
image_hash:created_image.images.bytes.hash,
"call_to_action": {
"type": "LEARN_MORE"
}
}],
"multi_share_end_card": true,
"multi_share_optimized": true
}
}
}
}
).then((created_ad)=>{
console.log("---------*------------")
console.log(created_ad);
}).catch((error) => {
console.log(error)
});
}).catch((error) => {
console.log(error)
});
})
.catch((error) => {
console.log(error)
});
})
.catch((error) => {
console.log(error)
});
});
});
res.end();

Business.getAssignedPages only returns id not a request field

Hey,

I'm trying to request all pages of an ad account, but this method call only returns the page id and not the corresponding name.

Any help here?

new Business(BUSINESS_ID).getAssignedPages([
        Business.Fields.name
    ], {}, true).then((result)=>{
    //console.log("....", result);
    if(result){
        result.forEach((page)=>{
            console.log("getAssignedPages", "----------------->", page);
        })
    }
}).catch((err)=>{

});```

Zero documentation

I should not have to dig into the source code to see what a function returns.

You should either:
Get fully working maps
OR
Provide documentation, there is literally ZERO

Creating several objects with the same AdAccount instance returns an error

When trying to create several objects, for example a campaign and an adset using the same instance of AdAccount, eg:

const account = new AdAccount(ACCOUNT_ID);

account.createCampaign(...)
.then(campaign => {
    account.createAdSet(...)
})

Facebook returns an error Unsupported post request. Object with ID '.....' does not exist, cannot be loaded due to missing permissions, or does not support this operation. Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api for the second create call

The problem disapears if I replace this with:

new AdAccount(ACCOUNT_ID).createCampaign(...)
.then(campaign => {
    new AdAccount(ACCOUNT_ID).createAdSet(...)
})

AdAccount endpoint doesn't work

While trying to use this library I noticed that some of the paths are not up to date. For example, when I try to access an AdAccount with the correct access token, it tries to hit the endpoint:

POST https://graph.facebook.com/v3.0/<account_id>/campaigns?access_token=<access_token>

FacebookRequestError: Unsupported post request. Object with ID '<account_id>' does not exist, cannot be loaded due to missing permissions, or does not support this operation. Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api

But it looks like when I do the same exact request via Curl with the endpoint:

POST https://graph.facebook.com/v3.0/act_<account_id>/campaigns?access_token=<access_token>

It works. I'm assuming this has to do with the version of the graph API that is being used. Would appreciate some help on this. Thank you!

creating users under customaudience with external identifiers

I am using customaudience.js to create custom audience. Through the samples provided, I can create custom audience successfully. After creating custom audience, I am trying to addUsers and CreateUsers with External Identifiers. I feel the required field name is EXTERN_ID and not present in the sdk file custom-audience.js. Are there any nodejs samples available for this? My request payload will be like this
payload={"schema":"EXTERN_ID","data":["ExternIDTest123","ExternIDTest456"]} and I tried createUser([fields],parameters). fields=['EXTERN_ID'] and parameters=payload. Am I doing something wrong here? This is my error : ```
(node:8184) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): FacebookRequestError: (#100) Missing required parameter: payload

Error message is undefined

I have tried to create a new AdAccount for my business, and I can see in the network panel of the browser devtools that I get an error with a message One or more of the ad accounts in your business manager are currently in bad standing or in review. All of your accounts must be in good standing in order to create or add new ad accounts.

However, when I try to display the error message to the user, the message is undefined.

I can see when I console log the FacebookRequestError that the message field is indeed undefined. When looking at the source, it seems that the generation of the Error object expects a name property on the object returned by Facebook, but it is not present (maybe a legacy thing).

Adding a general case in https://github.com/facebook/facebook-nodejs-ads-sdk/blob/master/src/exceptions.js#L68 would at least allow a non-conventional value for the name to not ignore the message returned.

Timeout errors break SDK

Hey folks,

If a request times out (happens on our end if we're hammering the API quickly), then the SDK crashes.

Here's the error:

{ handle: 14,
  type: 'error',
  className: 'Error',
  constructorFunction: { ref: 15 },
  protoObject: { ref: 16 },
  prototypeObject: { ref: 11 },
  properties: 
   [ { name: 'stack', attributes: 2, propertyType: 0, ref: 17 },
     { name: 'message', attributes: 2, propertyType: 0, ref: 18 },
     { name: 'code', propertyType: 0, ref: 19 },
     { name: 'errno', propertyType: 0, ref: 19 },
     { name: 'syscall', propertyType: 0, ref: 20 },
     { name: 'hostname', propertyType: 0, ref: 21 },
     { name: 'host', propertyType: 0, ref: 21 },
     { name: 'port', propertyType: 0, ref: 22 } ],
  text: 'Error: getaddrinfo ENOTFOUND graph.facebook.com graph.facebook.com:443' }

It happens here: /.../node_modules/facebook-nodejs-ads-sdk/dist/cjs.js:340

AdVideo.getThumbnails throws "Error: No endpoint specified for the target edge."

The method getThumbnails is defined as follow:

getThumbnails (fields: Object, params: Object): Cursor {
    return this.getEdge(VideoThumbnail, fields, params, 'thumbnails');
  }

The call to getEdge misses the parameter fetchFirstPage in 4th position, thus having the parameter endpoint not provided, which ends up in an exception raised when creating the Cursor.

Replacing the definition of getThumbnails with

getThumbnails(fields: Object, params: Object): Cursor {
    var fetchFirstPage = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
    return this.getEdge(adsSdk.VideoThumbnail, fields, params, fetchFirstPage, 'thumbnails');
}

fixes the problem.

Error upon getting certain fields across objects

I'm trying to get all data related to campaigns within the account, but when I requesting it with all fields selected I'm getting the following error. If I omit those fields, the data comes back just fine. They all seem to be related to budget, so I am guessing it is a permission error, but I allowed all types of requests within my facebook app and I am a bit at a loss at this point. Thank you

Fields that are erroring

Campaign.Fields.bid_strategy
Campaign.Fields.budget_remaining,
Campaign.Fields.daily_budget,
Campaign.Fields.lifetime_budget,

Error stack

 name: 'FacebookRequestError',
  message:
   'Syntax error "Expected name." at character 200: name,id,status,account_id,adlabels,boosted_object_id,brand_lift_studies,budget_rebalance_flag,buying_type,can_create_brand_lift_study,can_use_spend_cap,configured_status,created_time,effective_status,,stop_time',
  
stack:
   'Error at FacebookRequestError.FacebookError [as constructor] (./node_modules/facebook-nodejs-business-sdk/dist/cjs.js:319:16)
at new FacebookRequestError (./node_modules/facebook-nodejs-business-sdk/dist/cjs.js:341:129)
at ./node_modules/facebook-nodejs-business-sdk/dist/cjs.js:507:15
at tryCatcher (./node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (./node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (./node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (./node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (./node_modules/bluebird/js/release/promise.js:689:18)
at Async._drainQueue (./node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (./node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues [as _onImmediate] (./node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:696:18)
at tryOnImmediate (timers.js:667:5)
at processImmediate (timers.js:649:5)',
  status: 400,
  response:
   { error:
      { message:
         'Syntax error "Expected name." at character 200: name,id,status,account_id,adlabels,boosted_object_id,brand_lift_studies,budget_rebalance_flag,buying_type,can_create_brand_lift_study,can_use_spend_cap,configured_status,created_time,effective_status,,stop_time',
        type: 'OAuthException',
        code: 2500,
        fbtrace_id: 'GftS8YdATcr' } },

TypeError: Cannot read property 'error_user_msg' of undefined

SDK crashes when network error occurs with the following error.

TypeError: Cannot read property 'error_user_msg' of undefined
    at new FacebookRequestError (/Users/supasate/try/try-nodejs-ads-sdk-original/node_modules/facebook-nodejs-ads-sdk/dist/cjs.js:340:25)
    at /Users/supasate/try/try-nodejs-ads-sdk-original/node_modules/facebook-nodejs-ads-sdk/dist/cjs.js:466:15
    at tryCatcher (/Users/supasate/try/try-nodejs-ads-sdk-original/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/Users/supasate/try/try-nodejs-ads-sdk-original/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/Users/supasate/try/try-nodejs-ads-sdk-original/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/Users/supasate/try/try-nodejs-ads-sdk-original/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/Users/supasate/try/try-nodejs-ads-sdk-original/node_modules/bluebird/js/release/promise.js:689:18)
    at Async._drainQueue (/Users/supasate/try/try-nodejs-ads-sdk-original/node_modules/bluebird/js/release/async.js:133:16)
    at Async._drainQueues (/Users/supasate/try/try-nodejs-ads-sdk-original/node_modules/bluebird/js/release/async.js:143:10)
    at Immediate.Async.drainQueues (/Users/supasate/try/try-nodejs-ads-sdk-original/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:789:20)
    at tryOnImmediate (timers.js:751:5)
    at processImmediate [as _immediateCallback] (timers.js:722:5)

Reproduction steps:

  1. Turn off network
  2. Make a call via SDK e.g. create or read a campaign

How would you add users to custom audience?

I've created custom audiences based off some of the examples, but I don't see anywhere that says how to add the users to the custom audience. I've tried looking through the other SDK's and it looks they each have a specific function that adds the users to it. I tried using the custom-audience-data-source object to put the hashes in but still no luck. Also tried just placing the schema type and data source in the fields and params when calling the function but neither seem to do anything either. Can it be done with the SDK or do I just have to use something else?

Creating objects returns instance of AdAccount

When using an AdAccount to create an object, such as a campaign, the returned object is an AdAccount where the fields are those of the created object.
eg:

const account = new AdAccount(ACCOUNT_ID);
account.createCampaign(
    ['id', 'name'],
    {
        'name': 'My Campaign',
        'status': 'ACTIVE',
    }
).then(campaign => {
    // do something with the campaign
});

Here the variable campaign is an AdAccount with its name set as My Campaign and its id being the id of the campaign created.

The returned object should be of the type of the object created.

Limit of the requested fields

Currently, it seems like if I try getting more than certain amount of fields(it depends on the type of the object and how much data those fields hold) from the object it throws the following error. I think it would be good to document it somewhere.

  status: 500,
  response:
   { error:
      { code: 1,
        message:
         'Please reduce the amount of data you\'re asking for, then retry your request' } },
  method: 'GET',

Error deleting users from an audience

What am I doing?
I am trying to remove 10K+ users at once from an audience, like so:

(new CustomAudience(audienceId))
    .deleteUsers({payload: {
        schema: ['EMAIL'],
        data: [
            [<hashed_email>],
            [<hashed_email>],
            [<hashed_email>],
            ... 12000 more emails
        ]
    })
    .then(response => {
        callback(null, response);

        return null;
    })
    .catch(error => {
        callback({
            message: 'removeUsersFromAudience_error',
            data: {
                message: error.message || error,
                stack: error.stack || null
            }
        });
    });

What I expect to happen?
I expect to remove the users from audience and receive the response

{
    "audience_id": "<audience_id>",
    "session_id": "<session_id>",
    "num_received": <number_of_emails>,
    "num_invalid_entries": 0,
    "invalid_entry_samples": {}
}

What is actually happening?
I get the following error

{
	"message": "removeUsersFromAudience_error",
	"data": {
		"message": "Unexpected token < in JSON at position 0",
		"stack": "SyntaxError: Unexpected token < in JSON at position 0
				   at JSON.parse (<anonymous>)
				   at constructErrorResponse (/data/proj/node_modules/facebook-nodejs-business-sdk/dist/cjs.js:381:46)
				   at new FacebookRequestError (/data/proj/node_modules/facebook-nodejs-business-sdk/dist/cjs.js:339:25)
				   at /data/proj/node_modules/facebook-nodejs-business-sdk/dist/cjs.js:507:15
				   at tryCatcher (/data/proj/node_modules/bluebird/js/release/util.js:16:23)
				   at Promise._settlePromiseFromHandler (/data/proj/node_modules/bluebird/js/release/promise.js:512:31)
				   at Promise._settlePromise (/data/proj/node_modules/bluebird/js/release/promise.js:569:18)
				   at Promise._settlePromise0 (/data/proj/node_modules/bluebird/js/release/promise.js:614:10)
				   at Promise._settlePromises (/data/proj/node_modules/bluebird/js/release/promise.js:689:18)
				   at Async._drainQueue (/data/proj/node_modules/bluebird/js/release/async.js:133:16)
				   at Async._drainQueues (/data/proj/node_modules/bluebird/js/release/async.js:143:10)
				   at Immediate.Async.drainQueues (/data/proj/node_modules/bluebird/js/release/async.js:17:14)
				   at runCallback (timers.js:810:20)
				   at tryOnImmediate (timers.js:768:5)
				   at processImmediate [as _immediateCallback] (timers.js:745:5)"
	}
}

Other observations
It works if I make the request the old way:

request.delete(
    'https://graph.facebook.com/v2.12/<audience_id>/users',
    {
        form: {
            payload: {
	        schema: ['EMAIL'],
		data: [
		    [<hashed_email>],
		    [<hashed_email>],
		    [<hashed_email>],
		    ... 12000 more emails
		]
	    },
	    access_token: <access_token>
        }
    },
    function(error, response, body) {
      ...  
    });

"facebook-nodejs-business-sdk": "^3.0.5"

Bug in FacebookAdsApiBatch callbacks

Hello, guys, I started to use your library and found a pretty nasty bug in FacebookAdsApiBatch.
In the constructor we could pass successCallback as a parameter, so it'll be saved in the pool of callbacks:

constructor (
    api: FacebookAdsApi,
    successCallback?: Function,
    failureCallback?: Function
  ) {

    ...

    if (successCallback != null) {
      this._successCallbacks.push(successCallback);
    }

    if (failureCallback != null) {
      this._failureCallbacks.push(failureCallback);
    }
  }

When we're adding requests to the batch, we could pass successCallback as well, but during execution callbacks applied from the common pool of callbacks (including general success callback, which we passed in constructor):

for (let index = 0; index < responses.length; index++) {
  const response = responses[index];

  if (response != null) {
    const apiResponse = new APIResponse(response, this._batch[index]);

    // Call the success callback if provided
    if (apiResponse.isSuccess) {
      if (this._successCallbacks[index]) {
        this._successCallbacks[index](apiResponse);
      }
    } else {
      // Call the failure callback if provided
      if (this._failureCallbacks[index]) {
        this._failureCallbacks[index](apiResponse);
      }
    }
  } else {
    // Do not get response, so, we keep track of the index to retry
    retryIndices.push(index);
  }
}

So here index is an index of response, but when we add general success callback, amount of callbacks will be always response.length + 1, so last success callback will never be called.

And it seems the same situation with failureCallbacks.

Add support for v2.11

When someone creates a new application from now on, he cannot use any older version of the api than the latest.

Concurrency and sdk mutation

We have a bunch of jobs that we would like to run concurrently. However, if we do so we have no guarantee that the appropriate token will be used. Simple reproduction case follows:

const adsSdk = require('facebook-nodejs-business-sdk');
const Promise = require('bluebird');

const { AdAccount } = adsSdk;

async function runForAccount(actId, token, waitTime) {
  adsSdk.FacebookAdsApi.init(token);

  console.log('waiting for', waitTime, 'ms (', token, ')');
  await Promise.delay(waitTime);
  const account = new AdAccount(actId);

  try {
    const info = await account.read([AdAccount.Fields.name, AdAccount.Fields.age]);
    console.log(info._data);
  } catch (err) {
    console.log('bad token failed');
  }
}

const actId = '<act_id>';
const badToken = '<bad_token>';
const goodToken = '<good_token>';

runForAccount(actId, goodToken, 2000);
runForAccount(actId, badToken, 10);

desired output:

bad token failed
{ id: '<id>', name: '<name>', age: '<age>' }

actual output

bad token failed
bad token failed

Is there some way to work around this so that we can have multiple instances of the sdk running at the same time? Or is there a plan to support this kind of use in the future? Javascript in particular is heavily asynchronous, this side-effect behavior is not desirable. We've resorted to making the requests directly ourselves for now but would prefer to use the official sdk if possible.

pulling ads information

I'm trying to pull ads info/insight on an account but am confused how it works. I'm using the code below,:

account
.read([AdAccount.Fields.name])
.then((account) => {
// logPassedTest(test1 + ':Pass', account);
console.log(account: ${JSON.stringify(account)})
})
.catch((error) => {
console.log(error: ${error})
});

// this returns the below format, data is omitted.

{
"_data": {
"id": "",
"name": ""
},
"_fields": [],
"_changes": {},
"id": "",
"name": "",
"_api": {
"accessToken": "",
"locale": "en_US",
"_debug": false
}
}

How do i pull info on the fields returned, since just an array of field name returns? How can I get the values from these field names? How can I pull general analytics data on the Ads Account?

Pass in access token during create/update call

Hi,

I am working on a system where there are multiple users with different access tokens to create campaigns. How do I pass in access token during Campaign.create() call as oppose to sdk.init(access_token) which is global? otherwise, I am going to run into race condition.

The dist code[cjs.js] seems has mistake.

I am trying use this SDK upload video to my AdAccount:

let api = adsSdk.FacebookAdsApi.init(<token>)
api.setDebug(true)
let AdVideo = adsSdk.AdVideo
let advideo = new AdVideo(null, {[AdVideo.Fields.filepath]: "/path/to/video.mp4"}, "<ad account id>")
advideo.create().then(res=>{
    console.log(res)
})

And encountered an error says "_this8 is undefined".

The error trigged in dist/cjs.js/VideoUploadTransferRequestManager.sendRequest:

'use strict';
value: function sendRequest(context) {
    function _recursive() {
         var _this8 = this;
         if (_this8._startOffset !== _this8._endOffset) {
             ....
         }
    }
    ...
    ...
    return Promise.resolve().then(function () {
        ...
        ...
        return _recursive();
    }
}

As the announce 'use strict', this is undefined in function _recursive

And this function in source code is a while loop:

async sendRequest (context: VideoUploadRequestContext): Object {
    ...
    this._startOffset = context.startOffset;
    this._endOffset = context.endOffset;
    ...
    while (this._startOffset !== this._endOffset) {
        ...
    }
    ...
}

I'm not familiar with flow, just want to figure out is this a compile error?

Problem on installing package

I was trying to install facebook-nodejs-business-sdk but kept getting this error:

npm install facebook-nodejs-business-sdk
npm WARN deprecated [email protected]: gulp-util is deprecated - replace it, following the guidelines at https://medium.com/gulpjs/gulp-util-ca3b1f9f9ac5
npm WARN rm not removing /Volumes/jackie/Working/Precita/CodeCommit/precita-serverless/facebook/ads/product_catalog/node_modules/.bin/gulp as it wasn't installed by /Volumes/jackie/Working/Precita/CodeCommit/precita-serverless/facebook/ads/product_catalog/node_modules/gulp-cli
npm WARN [email protected] No repository field.

+ [email protected]
updated 1 package and moved 1 package in 15.6s
[!] 6 vulnerabilities found [8486 packages audited]
    Severity: 3 Low | 3 Moderate
    Run `npm audit` for more detail

Please help!

Intermittent problem when calling account.createCampaign

While 3/4 calls work, every other call I'm getting the following error message when calling account.createCampaign:

{ message: 'Unsupported post request. Object with ID \'SOME_CAMPAIGN_ID\' does not exist, cannot be loaded due to missing permissions, or does not support this operation. Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api',
        type: 'GraphMethodException',
        code: 100,
        error_subcode: 33,
        fbtrace_id: 'DV8Huvneiyi' }

is it possible something is being cached in the background from a previous call?

Best roundrobin

For context: I'm calling the method from within a Express endpoint.

Ad Comments

Hi,
Is there any way to retrieve comments on an ad?

I understand that each ad is actually a post from a page- I can use the graph api to retrieve these comments as I would any other post. But I was wondering if anything in here would allow me to do the same. I would assume this is done with the PagePost object, but I can't seem to find comments.

I see things such as "comments_mirroring_domain" or "child_attachments," but they dont seem to contain the comments.

thanks

Can I opt out users using this SDK with a call to `usersofanyaudience`?

The instructions here tell me that I can opt out my users out of ALL custom audiences by making a call to https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/usersofanyaudience

This appears to be supported by the Python SDK: https://github.com/facebook/facebook-python-business-sdk/blob/fcc2fe015136a9222334b364c3003a56475ec76c/facebook_business/adobjects/helpers/adaccountmixin.py#L72

Unfortunately, this Node SDK does not appear to support it. I am new to the SDK, so I am not yet sure if there is a simple way to make "raw" or extensible queries where some things are parameterized (like the API version, AD_ACCOUNT_ID, and other auth-related fields), but I decide the endpoint, etc.

Any help would be appreciated!

Insights API

Hi -

I am having trouble getting data using Insights API. Below is the piece of code I have -

const adsSdk = require('facebook-nodejs-business-sdk');

const accessToken = "XXXXX";

const account = new AdAccount('act_XXXXXX');

account.getInsights([AdInsight.Fields.impressions,AdInsight.Fields.spend,AdInsight.Fields.cpc, AdInsight.Fields.cpm], {
level: AdInsight.Level.adset
})
.then((insights) => {

console.log(insights.length) // returns 0

})
.catch((error) => {
console.log(error)
});

It always returns 0 insights; i have tried couple of combinations. Am i doing something wrong here?

thanks.

Using adsSdk.AdCreativeObjectStorySpec to create an AdCreative returns an error

When using an object of type adsSdk.AdCreativeObjectStorySpec to assign to the field object_story_spec to create a new AdCreative, Facebook returns an error stating:

object_story_spec param is invalid
Object story spec is ill formed. Maybe missing Page ID or creative details, or invalid fields exist

Replacing the ObjectStorySpec instantiation by a simple JavaScript object {} fixes the problem.

Vulnerable dependencies

There are 4 vulnerabilities because of obsolete dependencies used.
The outputs below were generated by npm 6.1.0.
npm audit fix cannot fix the vulnerabilities, so please update your dependencies.

> npm install --production

found 4 vulnerabilities (1 low, 3 moderate)
  run `npm audit fix` to fix them, or `npm audit` for details
> npm audit

                       === npm audit security report ===                        
                                                                                
┌──────────────────────────────────────────────────────────────────────────────┐
│                                Manual Review                                 │
│            Some vulnerabilities require your attention to resolve            │
│                                                                              │
│         Visit https://go.npm.me/audit-guide for additional guidance          │
└──────────────────────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Moderate      │ Prototype pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ hoek                                                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ > 4.2.0 < 5.0.0 || >= 5.0.3                                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ facebook-nodejs-business-sdk                                 │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ facebook-nodejs-business-sdk > gulp-cli > wreck > boom >     │
│               │ hoek                                                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/566                       │
└───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Moderate      │ Prototype pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ hoek                                                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ > 4.2.0 < 5.0.0 || >= 5.0.3                                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ facebook-nodejs-business-sdk                                 │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ facebook-nodejs-business-sdk > gulp-cli > wreck > hoek       │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/566                       │
└───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Moderate      │ Memory Exposure                                              │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ tunnel-agent                                                 │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ >=0.6.0                                                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ facebook-nodejs-business-sdk                                 │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ facebook-nodejs-business-sdk > gulp-flowtype > flow-bin >    │
│               │ bin-wrapper > download > caw > tunnel-agent                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/598                       │
└───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Low           │ Prototype Pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ lodash                                                       │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ >=4.17.5                                                     │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ facebook-nodejs-business-sdk                                 │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ facebook-nodejs-business-sdk > gulp-flowtype > jshint >      │
│               │ lodash                                                       │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/577                       │
└───────────────┴──────────────────────────────────────────────────────────────┘
found 4 vulnerabilities (1 low, 3 moderate) in 5048 scanned packages
  4 vulnerabilities require manual review. See the full report for details.
> npm audit fix

fixed 0 of 4 vulnerabilities in 5048 scanned packages
  4 vulnerabilities required manual review and could not be updated

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.