Facebook Ads API SDK for Javascript
A Javascript SDK for Facebook Ads API development in both client and server-side. ECMAScript 5 bundled minified distribuitions with sourcemaps are also available as AMD and CommonJS modules, as an IIFE (under the fb
variable), as UMD if you want it all, and even as Browser Globals. Runs "anywhere" thanks to Babel and Rollup. It is consistent with many concepts from Python and PHP SDKs in a JS fashion, with some simplifications and tweaks. This is not an official library.
Example
const adsSdk = require('facebook-ads-sdk');
const accessToken = 'VALID_ACCESS_TOKEN'
const accountId = 'AD_ACCOUNT_ID'
const FacebookAdsApi = adsSdk.FacebookAdsApi.init(accessToken)
const AdAccount = adsSdk.AdAccount
const Campaign = adsSdk.Campaign
const account = new AdAccount({ 'id': accountId })
const insightsFields = ['impressions', 'frequency', 'unique_clicks', 'actions', 'spend', 'cpc']
const insightsParams = { date_preset: Campaign.DatePreset.last_90_days }
var campaigns
account.read([AdAccount.Fields.name])
.then((account) => {
account.getInsights(insightsFields, insightsParams)
.then((actInsights) => console.log(account, actInsights))
.catch(console.error)
return account.getCampaigns([Campaign.Fields.name], { limit: 10 })
})
.then((result) => {
campaigns = result
const campaign_ids = campaigns.map((campaign) => campaign.id)
const campaignInsightsParams = Object.assign({
level: 'campaign',
filtering: [{ field: 'campaign.id', operator: 'IN', value: campaign_ids }]
}, insightsParams)
const campaigsInsightsFields = insightsFields.concat('campaign_id')
return account.getInsights(campaigsInsightsFields, campaignInsightsParams)
})
.then((insights) => console.log(campaigns, insights))
.catch(console.error)
Installation
NPM
npm install --save facebook-ads-sdk
Bower
bower install --save facebook-ads-sdk
Promises
This SDK returns Promises, a neat way to handle asynchronous requests. You should provide a polyfill if you intend to make this available in not supporting environments (check a compatibility table). Bluebird seems a good choice and it's used here in Node through request-promise and in browser unit tests.
Usage
Access Token
To instantiate an Api object you will need a valid access token for an app with the ads_management
permission. A quick way to obtaining a short-lived token is using the Graph API Explorer. Instantiate the API using the token:
const FacebookAdsApi = require('facebook-ads-sdk').FacebookAdsApi;
const api = FacebookAdsApi.init(accessToken)
Once instantiated, the Api object be refered by the Graph objects. You can also directly assign an Api instance to an object, which enables using different tokens.
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.
Facebook Objects
The currently supported objects are located in 'src/objects'. If the object need is not available or it doesn't posses a method you want you may add it and make a Pull Request, or ask for it in the Issues if you can't.
const AdAccount = require('facebook-ads-sdk').AdAccount;
const account = new AdAccount({'id': 'AD_ACCOUNT_ID'})
console.log(account.id)
CRUD operations
Most of Facebook's Objects can perform Create, Read, Update, and Delete operations. Enums such as Fields
and other constants are provided by the classes to improve maintainability.
Create
const Campaign = require('facebook-ads-sdk').Campaign;
const accountId = 'AD_ACCOUNT_ID'
const data = {
[Campaign.Fields.name]: 'Campaign Name',
[Campaign.Fields.status]: Campaign.Status.paused
}
new Campaign(data, accountId)
.create()
.then((campaign) => { console.log(campaign.id) })
.catch(errorFunction)
Read
const Campaign = require('facebook-ads-sdk').Campaign;
const campaignId = 'CAMPAIGN_ID'
new Campaign({ 'id': campaignId })
.read([Campaign.Fields.name])
.then((campaign) => { console.log(campaign.name) })
.catch(errorFunction)
An easy way to read a set of objects is to get them by their ids:
const campaignIds = ['CAMPAIGN_A_ID', 'CAMPAIGN_B_ID']
Campaign.getByIds(campaignIds)
.then((campaigns) => { console.log(campaigns[0], campaigns[1]) })
.catch(errorFunction)
Update
const Campaign = require('facebook-ads-sdk').Campaign;
const campaignId = 'CAMPAIGN_ID'
const newName = 'New Campaign Name'
new Campaign({ [Campaign.Fields.id]: campaignId, [Campaign.Fields.name]: newName })
.udpate()
.then((result) => { console.log(result.success) })
.catch(errorFunction)
Delete
const Campaign = require('facebook-ads-sdk').Campaign;
const campaignId = 'CAMPAIGN_ID'
new Campaign({ 'id': campaignId })
.delete()
.then((result) => { console.log(result.success) })
.catch(errorFunction)
Edges and Cursor-based Pagination
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. This should be great for reactive template systems.
Here's an example suposing we have currently 17 campaigns in an Ad Account:
const AdAccount = require('facebook-ads-sdk').AdAccount;
const account = new AdAccount({'id': 'AD_ACCOUNT_ID'})
account.getCampaigns([Campaign.Fields.name], { limit: 10 })
.then((campaigns) => {
console.log(campaigns.length)
console.log(campaigns.hasNext())
return campaigns.next()
}
.then((campaigns) => {
console.log(campaigns.length)
console.log(campaigns.hasNext())
console.log(campaigns.hasPrevious())
return campaigns.previous()
}
.then((campaigns) => {
console.log(campaigns.length)
}
.catch(errorFunction)
Development
Dependencies
Gulp and Bower should be installed globally. Install depencencies:
npm install
bower install
Checkout gulpfile.js
for all available tasks.
Style
This package uses StandardJS. Inconsistent code will break tests.
Unit Tests
Unit tests run in Node.js, PhantomJS, and in Browsers. Travis CI will run both Node and PhantomJS tests to ensure isomorphism.
- The default
gulp
task will watch the files and run the Node tests repeatedly. gulp test
will run the Node tests.gulp test-phantom
will run tests against the PhatomJS headless browser.gulp test-browser
will open your system browser with the tests.
Front-end tests rely on a bundle processed before the tests. You can use gulp watch-bundle
to bundle as the code changes.
Integration Tests
Integration tests run a few basic operations to ensure API connectivity. To run them, you'll need to setup a config.json
file in tests/integration
. Copy the config.sample
and fill accessToken
and accountId
.
gulp integration
will run integration tests on Node.gulp integration-browser
will open your system browser with the tests. Useful if you'd like to inspect the requests.