### [![build status](https://gitlab.ak-networks.com/ci/projects/8/status.png?ref=master)](https://gitlab.ak-networks.com/ci/projects/8?ref=master) Master (GitLab CI) ###[![](https://ci.solanolabs.com:443/AdParlor//badges/branches/master?badge_token=b5e0dec703fe9ae000ae346dceb0b7ddd53c91db)](https://ci.solanolabs.com:443/AdParlor/facebook_ruby_ads_sdk/suites/509306) Master (Solano CI) # Adparlor::Facebook The adparlor-facebook gem is a ruby library for interacting with the Facebook ads API. Supporting both REST and batch requests. ## Installation Add this line to your application's Gemfile: ```ruby gem 'adparlor-facebook', git: 'https://gitlab.ak-networks.com/adparlor/facebook_ruby_ads_sdk.git' ``` or locally for development ```bash bundle config local.adparlor-facebook ~/Projects/facebook_ruby_ads_sdk ``` ```ruby gem 'adparlor-facebook', branch: 'master' ``` And then execute: $ bundle ## Usage ### Graph API Once an access token is obtained [https://developers.facebook.com/docs/facebook-login/access-tokens](https://developers.facebook.com/docs/facebook-login/access-tokens) you can begin making requests to the GraphApi. ```ruby #Get an ad account by the id account = Adparlor::Facebook::GraphApi::AdAccount.get(account_id, access_token: 'access_token') account.name #-> 'the account name' account.account_status #-> 'the account status' #Get an ad creative by the id creative = Adparlor::Facebook::GraphApi::AdCreative.get(creative_id, access_token: 'access_token') creative.id #-> '11111111111111111' #The Get method also takes the fields option like the graph api by default only returning the minimal fields creative = Adparlor::Facebook::GraphApi::AdCreative.get(creative_id, access_token: 'access_token', fields: %w(body image_hash image_url ...)) #OR creative = Adparlor::Facebook::GraphApi::AdCreative.get(creative_id, access_token: 'access_token', fields: Adparlor::Facebook::GraphApi::AdCreative.fields(:all)) creative.id #-> '11111111111111111' creative.name #-> 'the creatives name' creative.thumbnail_url #-> 'https://facebook.com/image...' #You can also get objects by their edges as referred to in the Facebook documentation #which returns a memoized array of object types. account = Adparlor::Facebook::GraphApi::AdAccount.get(account_id, access_token: 'access_token') account.adcreatives.all #-> [Adparlor::Facebook::GraphApi::AdCreative<...>, Adparlor::Facebook::GraphApi::AdCreative<...>, Adparlor::Facebook::GraphApi::AdCreative<...>, ...] account.adimages.all #-> [Adparlor::Facebook::GraphApi::AdImage<...>, Adparlor::Facebook::GraphApi::AdImage<...>, Adparlor::Facebook::GraphApi::AdImage<...>, ...] account.campaigns.all #-> [Adparlor::Facebook::GraphApi::Campaign<...>, Adparlor::Facebook::GraphApi::Campaign<...>, Adparlor::Facebook::GraphApi::Campaign<...>, ...] #The all method also takes the fields option like the graph api by default only returning the minimal fields account.adcreatives.all.first #-> Adparlor::Facebook::GraphApi::AdCreative<@id => '1111111111111111'> account.adcreatives.all(Adparlor::Facebook::GraphApi::AdCreative.fields(:all))).first #-> Adparlor::Facebook::GraphApi::AdCreative<@id='1111111111111111', @body='...', @image_hash='...'> #The edges also implement create and delete options account.adimages.delete(hash: '6aec0dd976393abfad84e8f2511960a8') #-> response.body = {"success" => true} account.adimages.create(source: 'http://www.example.com/url/to/image.png') #OR account.adimages.create(source: '/path/to/image.png') #-> response.body = :images => { :url => 'https://facebook.com/image/localtion.png', :hash => 'd0f7567af280e1f6760457ff4df782d8' } ``` ### Batch requests If making large numbers of requests at the same time or requests that depend on each other the batch object can be used. ```ruby #The batch api requires an access token in the case some of the requests use different tokens #or one is not supplied for fallback purposes. account = Adparlor::Facebook::GraphApi::AdAccount.get(account_id, access_token: 'access_token') response = account.batch do |batch| batch.get account.id, AdImage, fields: [:id, :name, :hash] # uses the parent objects token batch.get account.id, Campaign, access_token: account.access_token # uses the parent objects token but it is supplied batch.get account2.id, AdImage, access_token: account2.access_token, fields: [:id, :name, :height] end response #-> [[AdImage, AdImage, ...],[Campaign, Campaign, ...],[AdImage, AdImage, ...]] #The object can also be created without an account if the requests are all different accounts or non account level objects #This will use the access token of the first object to be the top level access token response = Adparlor::Facebook::GraphObject.new.batch do |batch| batch.get nil, AdCreative, id: '6666666666666', access_token: 'access_token' batch.get nil, AdCreative, id: '7777777777777', access_token: 'access_token' end #Posting follows the same style request, files should be accompanied by the source key. response = account.batch do |batch| batch.post account.id, AdImage, source: 'http://www.example.com/url/for/image.png' # uses the parent objects token batch.post account2.id, AdImage, source: 'http://www.example.com/url/for/othe-image.png', access_token: account2.access_token # uses its own token end response #-> [AdImage, AdImage] #Deleting follows the same style request response = account.batch do |batch| batch.delete account.id, AdImage, hash: 'bee06e2e03f9b5a32419855e2c7a4225' batch.delete account.id, AdImage, hash: 'd8ebd0caddecb512ec3b782ae9498e13' end #You can mix up requests response = account.batch do |batch| batch.post account.id, AdImage, source: 'http://www.example.com/url/for/image.png' batch.post account2.id, AdImage, source: 'http://www.example.com/url/for/othe-image.png', access_token: account2.access_token batch.get account.id, AdImage, fields: [:id, :name, :hash] batch.get account.id, Campaign end response #-> [AdImage, AdImage, [AdImage, AdImage, ...],[Campaign, Campaign, ...]] #You can post requests that are dependent on other requests #In this case the post that another post is dependent on will supply a name to the options parameter #which is then referred to in dependents posts appropriate column. #in this case the campaign post gets the name 'create_campaign' the following request refers to it #using the JSONPath expression format required by the batch api '{result=create_campaign:$.id}' # for more information visit: https://developers.facebook.com/docs/marketing-api/batch-requests/v2.5 response = account.batch do |batch| batch.post account.id, Campaign, { name: 'A Test Campaign', objective: 'LOCAL_AWARENESS', status: 'PAUSED' }, name: 'create_campaign' batch.post account.id, AdSet, name: 'A Test AdSet', daily_budget: 135, start_time: '00:05:00', campaign_id: '{result=create_campaign:$.id}', bid_amount: 150, billing_event: 'IMPRESSIONS', optimization_goal: 'REACH', targeting: { geo_locations: { cities: [{ key: '2418956', radius: 12, distance_unit: 'mile' }] }, page_types: %w(desktopfeed mobilefeed) }, status: 'PAUSED', promoted_object: { page_id: your_page_id } end response #-> [null, AdSet] ``` ## Development After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. ## License The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). ## TODO * Create requests should probably return an instance of the object instead of the Faraday body * ?Delete requests should return true if deleted or error message? * Continue to add endpoints * More configurable tests for testing live instead of the vcr cassettes.