facebook_ads 0.1.12 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +8 -4
- data/.rubocop.yml +9 -6
- data/.travis.yml +5 -5
- data/CHANGELOG.md +10 -0
- data/Gemfile +1 -1
- data/LICENSE.md +0 -1
- data/README.md +9 -3
- data/Rakefile +3 -6
- data/bin/console +4 -3
- data/facebook_ads.gemspec +16 -12
- data/lib/facebook_ads/ad_campaign.rb +3 -2
- data/lib/facebook_ads/ad_creative.rb +18 -5
- data/lib/facebook_ads/ad_set.rb +21 -2
- data/lib/facebook_ads/base.rb +1 -0
- data/lib/facebook_ads.rb +17 -0
- data/spec/fixtures/cassettes/FacebookAds_AdAccount/_ad_campaigns/lists_campaigns.yml +1 -1
- data/spec/fixtures/cassettes/FacebookAds_AdAccount/_ad_creatives/lists_creatives.yml +1 -1
- data/spec/fixtures/cassettes/FacebookAds_AdAccount/_ad_images/lists_images.yml +1 -1
- data/spec/fixtures/cassettes/FacebookAds_AdAccount/_ad_sets/lists_ad_sets.yml +1 -1
- data/spec/fixtures/cassettes/FacebookAds_AdAccount/_ads/lists_ads.yml +1 -1
- data/spec/fixtures/cassettes/FacebookAds_AdAccount/_all/lists_all_accounts.yml +1 -1
- data/spec/fixtures/cassettes/FacebookAds_AdAccount/_create_ad_campaign/creates_a_new_ad_campaign.yml +1 -1
- data/spec/fixtures/cassettes/FacebookAds_AdAccount/_create_ad_images/creates_an_image.yml +1 -1
- data/spec/fixtures/cassettes/FacebookAds_AdAccount/_find_by/finds_a_specific_account.yml +1 -1
- data/spec/fixtures/cassettes/FacebookAds_AdAccount/_reach_estimate/estimates_the_reach_of_a_targeting_spec.yml +1 -1
- data/spec/fixtures/cassettes/FacebookAds_AdCampaign/_destroy/creates_a_new_ad_campaign.yml +3 -3
- data/spec/support/facebook_ads.rb +1 -0
- data/spec/support/vcr.rb +5 -2
- metadata +47 -11
- data/.approvals +0 -0
- data/.rubocop_todo.yml +0 -16
- data/Gemfile.lock +0 -118
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7450bd7b5cbf0923d6fd31c81789dbb4a41c6a6e
|
4
|
+
data.tar.gz: 4a96fdf4cd1940418b414a4b35f1d9dd16b7faf5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9aea51760cc15a61efcb50b2ba823162b56d6f5a7426efb803627913d586cc050405dede1c737e2f47e34ed34431bde4bb1d81cd0f26f4d4d8701aa6c859cd9d
|
7
|
+
data.tar.gz: a4835643fae536365837cf1071b5d6df228317aca5dbc28e15d1d82a51ec65f1ae733dcca4bfee00b86d5ba6fbe83c327516a35e13e39feb8e32b3c5bd9511bb
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,8 +1,4 @@
|
|
1
|
-
inherit_from: .rubocop_todo.yml
|
2
|
-
|
3
1
|
AllCops:
|
4
|
-
Exclude:
|
5
|
-
- bin/console
|
6
2
|
TargetRubyVersion: 2.2
|
7
3
|
|
8
4
|
Metrics/AbcSize:
|
@@ -11,6 +7,7 @@ Metrics/CyclomaticComplexity:
|
|
11
7
|
Enabled: false
|
12
8
|
Metrics/PerceivedComplexity:
|
13
9
|
Enabled: false
|
10
|
+
|
14
11
|
Metrics/LineLength:
|
15
12
|
Enabled: false
|
16
13
|
Metrics/ClassLength:
|
@@ -22,6 +19,9 @@ Metrics/BlockLength:
|
|
22
19
|
Metrics/ParameterLists:
|
23
20
|
Enabled: false
|
24
21
|
|
22
|
+
Lint/EndAlignment:
|
23
|
+
Enabled: false
|
24
|
+
|
25
25
|
Style/Documentation:
|
26
26
|
Enabled: false
|
27
27
|
Style/IndentationWidth:
|
@@ -30,6 +30,9 @@ Style/ElseAlignment:
|
|
30
30
|
Enabled: false
|
31
31
|
Style/GuardClause:
|
32
32
|
Enabled: false
|
33
|
+
Style/NumericLiterals:
|
34
|
+
Enabled: false
|
33
35
|
|
34
|
-
#
|
35
|
-
|
36
|
+
# This is temporary - it can be remove after updating rubocop to the latest.
|
37
|
+
Style/PercentLiteralDelimiters:
|
38
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
## 0.4 (2017-07-25)
|
2
|
+
- Added ability to pass `bid_amount` parameter when creating ad sets
|
3
|
+
- Ad Set `is_autobid` parameter now defaults to `nil` rather than `true`
|
4
|
+
|
5
|
+
## 0.3 (2017-07-24)
|
6
|
+
- Added ability to pass `app_link` parameter with ad creatives
|
7
|
+
|
8
|
+
## 0.2 (2017-07-20)
|
9
|
+
- Added ability to configure App Secret to be included with API requests
|
10
|
+
|
1
11
|
## 0.1.12 (2017-05-25)
|
2
12
|
- Added complete set of ad campaign objectives. (#9, @cte)
|
3
13
|
- Switched to rspec from minitest. (#8, @cte)
|
data/Gemfile
CHANGED
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
[![Gem Version](https://badge.fury.io/rb/facebook_ads.svg)](https://badge.fury.io/rb/facebook_ads)
|
2
|
-
[![Build Status](https://travis-ci.org/
|
3
|
-
[![Coverage Status](https://coveralls.io/repos/github/
|
2
|
+
[![Build Status](https://travis-ci.org/tophatter/facebook-ruby-ads-sdk.svg?branch=master)](https://travis-ci.org/tophatter/facebook-ruby-ads-sdk)
|
3
|
+
[![Coverage Status](https://coveralls.io/repos/github/tophatter/facebook-ruby-ads-sdk/badge.svg?branch=master)](https://coveralls.io/github/tophatter/facebook-ruby-ads-sdk?branch=master)
|
4
4
|
|
5
5
|
# [Facebook Marketing API](https://developers.facebook.com/docs/marketing-apis) SDK for Ruby
|
6
6
|
|
@@ -28,6 +28,12 @@ You'll need an [Access Token](https://developers.facebook.com/docs/marketing-api
|
|
28
28
|
FacebookAds.access_token = '[YOUR_ACCESS_TOKEN]'
|
29
29
|
```
|
30
30
|
|
31
|
+
You can also optionally include an [App Secret](https://developers.facebook.com/docs/accountkit/graphapi#app-tokens) if you need one for your application.
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
FacebookAds.app_secret = '[YOUR_APP_SECRET]'
|
35
|
+
```
|
36
|
+
|
31
37
|
## API Version
|
32
38
|
|
33
39
|
This gem currently uses v2.8 of the Marketing API (soon to be updated to 2.9). You can change the version as desired with the following:
|
@@ -151,7 +157,7 @@ ___
|
|
151
157
|
Notes:
|
152
158
|
* Images cannot be updated.
|
153
159
|
* You can upload the same image multiple times and Facebook will de-duplicate them server side.
|
154
|
-
* An image will always generate the same hash on Facebook's end -
|
160
|
+
* An image will always generate the same hash on Facebook's end - even across ad accounts.
|
155
161
|
* Image uploading via a URL currently assumes a \*nix system (Mac OS, linux). It likely will fail on Windows. A cross-platform tempfile-based solution is in the works.
|
156
162
|
* You can't destroy an image if its being used by a creative. You have to destroy the creative first.
|
157
163
|
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
@@ -2,8 +2,6 @@
|
|
2
2
|
|
3
3
|
require 'bundler/setup'
|
4
4
|
require 'facebook_ads'
|
5
|
-
require 'awesome_print'
|
6
|
-
require 'pry'
|
7
5
|
|
8
6
|
begin
|
9
7
|
FacebookAds.access_token = File.read('test_access_token').chop
|
@@ -23,5 +21,8 @@ end
|
|
23
21
|
FacebookAds.logger = Logger.new(STDOUT)
|
24
22
|
FacebookAds.logger.level = Logger::Severity::DEBUG
|
25
23
|
|
24
|
+
require 'awesome_print'
|
25
|
+
require 'pry'
|
26
|
+
|
26
27
|
AwesomePrint.pry!
|
27
|
-
|
28
|
+
Pry.start
|
data/facebook_ads.gemspec
CHANGED
@@ -1,24 +1,28 @@
|
|
1
|
-
#
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# To publish the next version:
|
2
4
|
# gem build facebook_ads.gemspec
|
3
|
-
# gem push facebook_ads-0.
|
5
|
+
# gem push facebook_ads-0.4.gem
|
4
6
|
Gem::Specification.new do |s|
|
5
7
|
s.name = 'facebook_ads'
|
6
|
-
s.version = '0.
|
8
|
+
s.version = '0.4'
|
7
9
|
s.platform = Gem::Platform::RUBY
|
8
10
|
s.licenses = ['MIT']
|
9
11
|
s.authors = ['Chris Estreich']
|
10
|
-
s.email = '
|
11
|
-
s.homepage = 'https://github.com/
|
12
|
+
s.email = 'chris@tophatter.com'
|
13
|
+
s.homepage = 'https://github.com/tophatter/facebook-ruby-ads-sdk'
|
12
14
|
s.summary = 'Facebook Marketing API SDK for Ruby.'
|
13
|
-
s.description = "This gem allows to easily manage your Facebook ads via
|
14
|
-
|
15
|
+
s.description = "This gem allows to easily manage your Facebook ads via Facebook's Marketing API in ruby."
|
16
|
+
|
15
17
|
s.extra_rdoc_files = ['README.md']
|
16
|
-
|
17
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map do |f|
|
18
|
-
File.basename(f)
|
19
|
-
end
|
20
|
-
s.require_paths = ['lib']
|
18
|
+
|
21
19
|
s.required_ruby_version = '~> 2.0'
|
20
|
+
|
22
21
|
s.add_dependency 'rest-client', '>= 1.6'
|
23
22
|
s.add_dependency 'hashie', '~> 3.4'
|
23
|
+
|
24
|
+
s.files = `git ls-files`.split("\n")
|
25
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
26
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
27
|
+
s.require_paths = ['lib']
|
24
28
|
end
|
@@ -60,7 +60,7 @@ module FacebookAds
|
|
60
60
|
AdSet.paginate("/#{id}/adsets", query: { effective_status: effective_status, limit: limit })
|
61
61
|
end
|
62
62
|
|
63
|
-
def create_ad_set(name:, promoted_object:, targeting:, daily_budget:, optimization_goal:, billing_event: 'IMPRESSIONS', status: 'ACTIVE', is_autobid:
|
63
|
+
def create_ad_set(name:, promoted_object:, targeting:, daily_budget:, optimization_goal:, billing_event: 'IMPRESSIONS', status: 'ACTIVE', is_autobid: nil, bid_amount: nil)
|
64
64
|
raise Exception, "Optimization goal must be one of: #{AdSet::OPTIMIZATION_GOALS.join(', ')}" unless AdSet::OPTIMIZATION_GOALS.include?(optimization_goal)
|
65
65
|
raise Exception, "Billing event must be one of: #{AdSet::BILLING_EVENTS.join(', ')}" unless AdSet::BILLING_EVENTS.include?(billing_event)
|
66
66
|
|
@@ -80,7 +80,8 @@ module FacebookAds
|
|
80
80
|
daily_budget: daily_budget,
|
81
81
|
billing_event: billing_event,
|
82
82
|
status: status,
|
83
|
-
is_autobid: is_autobid
|
83
|
+
is_autobid: is_autobid,
|
84
|
+
bid_amount: bid_amount
|
84
85
|
}
|
85
86
|
result = AdSet.post("/act_#{account_id}/adsets", query: query)
|
86
87
|
AdSet.find(result['id'])
|
@@ -6,7 +6,7 @@ module FacebookAds
|
|
6
6
|
CALL_TO_ACTION_TYPES = %w[SHOP_NOW INSTALL_MOBILE_APP USE_MOBILE_APP SIGN_UP DOWNLOAD BUY_NOW].freeze
|
7
7
|
|
8
8
|
class << self
|
9
|
-
def photo(name:, page_id:, instagram_actor_id: nil, message:, link:, link_title:, image_hash:, call_to_action_type:)
|
9
|
+
def photo(name:, page_id:, instagram_actor_id: nil, message:, link:, app_link: nil, link_title:, image_hash:, call_to_action_type:)
|
10
10
|
object_story_spec = {
|
11
11
|
'page_id' => page_id, # 300664329976860
|
12
12
|
'instagram_actor_id' => instagram_actor_id, # 503391023081924
|
@@ -19,6 +19,7 @@ module FacebookAds
|
|
19
19
|
'value' => {
|
20
20
|
# 'application' =>,
|
21
21
|
'link' => link,
|
22
|
+
'app_link' => app_link,
|
22
23
|
'link_title' => link_title
|
23
24
|
}
|
24
25
|
}
|
@@ -32,21 +33,33 @@ module FacebookAds
|
|
32
33
|
end
|
33
34
|
|
34
35
|
# https://developers.facebook.com/docs/marketing-api/guides/videoads
|
35
|
-
def carousel(name:, page_id:, instagram_actor_id: nil, link:, message:, assets:, call_to_action_type:, multi_share_optimized:, multi_share_end_card:)
|
36
|
+
def carousel(name:, page_id:, instagram_actor_id: nil, link:, app_link: nil, message:, assets:, call_to_action_type:, multi_share_optimized:, multi_share_end_card:)
|
36
37
|
object_story_spec = {
|
37
38
|
'page_id' => page_id, # 300664329976860
|
38
39
|
'instagram_actor_id' => instagram_actor_id, # 503391023081924
|
39
40
|
'link_data' => {
|
40
41
|
'link' => link, # https://tophatter.com/, https://itunes.apple.com/app/id619460348, http://play.google.com/store/apps/details?id=com.tophatter
|
41
42
|
'message' => message,
|
42
|
-
'call_to_action' => {
|
43
|
+
'call_to_action' => {
|
44
|
+
'type' => call_to_action_type,
|
45
|
+
'value' => {
|
46
|
+
'link' => link,
|
47
|
+
'app_link' => app_link
|
48
|
+
}
|
49
|
+
},
|
43
50
|
'child_attachments' => assets.collect do |asset|
|
44
51
|
{
|
45
|
-
'link' => link,
|
52
|
+
'link' => asset[:link] || link,
|
46
53
|
'image_hash' => asset[:hash],
|
47
54
|
'name' => asset[:title],
|
48
55
|
# 'description' => asset[:title],
|
49
|
-
'call_to_action' => {
|
56
|
+
'call_to_action' => { # Redundant?
|
57
|
+
'type' => call_to_action_type,
|
58
|
+
'value' => {
|
59
|
+
'link' => asset[:link] || link,
|
60
|
+
'app_link' => asset[:app_link] || app_link
|
61
|
+
}
|
62
|
+
}
|
50
63
|
}
|
51
64
|
end,
|
52
65
|
'multi_share_optimized' => multi_share_optimized,
|
data/lib/facebook_ads/ad_set.rb
CHANGED
@@ -24,7 +24,7 @@ module FacebookAds
|
|
24
24
|
id account_id campaign_id
|
25
25
|
name
|
26
26
|
status configured_status effective_status
|
27
|
-
bid_amount billing_event optimization_goal pacing_type
|
27
|
+
is_autobid bid_amount billing_event optimization_goal pacing_type
|
28
28
|
daily_budget budget_remaining lifetime_budget
|
29
29
|
promoted_object
|
30
30
|
targeting
|
@@ -33,7 +33,26 @@ module FacebookAds
|
|
33
33
|
|
34
34
|
STATUSES = %w[ACTIVE PAUSED DELETED PENDING_REVIEW DISAPPROVED PREAPPROVED PENDING_BILLING_INFO CAMPAIGN_PAUSED ARCHIVED ADSET_PAUSED].freeze
|
35
35
|
BILLING_EVENTS = %w[APP_INSTALLS IMPRESSIONS].freeze
|
36
|
-
OPTIMIZATION_GOALS = %w[
|
36
|
+
OPTIMIZATION_GOALS = %w[
|
37
|
+
NONE
|
38
|
+
APP_INSTALLS
|
39
|
+
BRAND_AWARENESS
|
40
|
+
CLICKS
|
41
|
+
ENGAGED_USERS
|
42
|
+
EVENT_RESPONSES
|
43
|
+
IMPRESSIONS
|
44
|
+
LEAD_GENERATION
|
45
|
+
LINK_CLICKS
|
46
|
+
OFFER_CLAIMS
|
47
|
+
OFFSITE_CONVERSIONS
|
48
|
+
PAGE_ENGAGEMENT
|
49
|
+
PAGE_LIKES
|
50
|
+
POST_ENGAGEMENT
|
51
|
+
REACH
|
52
|
+
SOCIAL_IMPRESSIONS
|
53
|
+
VIDEO_VIEWS
|
54
|
+
APP_DOWNLOADS
|
55
|
+
].freeze
|
37
56
|
|
38
57
|
# belongs_to ad_account
|
39
58
|
|
data/lib/facebook_ads/base.rb
CHANGED
@@ -84,6 +84,7 @@ module FacebookAds
|
|
84
84
|
|
85
85
|
def pack(hash, objectify:)
|
86
86
|
hash = hash.merge(access_token: FacebookAds.access_token)
|
87
|
+
hash = hash.merge(appsecret_proof: FacebookAds.appsecret_proof) if FacebookAds.app_secret
|
87
88
|
hash = hash.merge(fields: self::FIELDS.join(',')) if objectify
|
88
89
|
hash.delete_if { |_k, v| v.nil? }
|
89
90
|
end
|
data/lib/facebook_ads.rb
CHANGED
@@ -3,6 +3,7 @@ require 'json'
|
|
3
3
|
require 'rest-client'
|
4
4
|
require 'hashie'
|
5
5
|
require 'logger'
|
6
|
+
require 'openssl'
|
6
7
|
|
7
8
|
# Internal requires.
|
8
9
|
require 'facebook_ads/base'
|
@@ -40,6 +41,22 @@ module FacebookAds
|
|
40
41
|
@access_token
|
41
42
|
end
|
42
43
|
|
44
|
+
def self.app_secret=(app_secret)
|
45
|
+
@app_secret = app_secret
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.app_secret
|
49
|
+
@app_secret
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.appsecret_proof
|
53
|
+
OpenSSL::HMAC.hexdigest(
|
54
|
+
OpenSSL::Digest.new('sha256'),
|
55
|
+
@app_secret,
|
56
|
+
@access_token
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
43
60
|
def self.business_id=(business_id)
|
44
61
|
@business_id = business_id
|
45
62
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
http_interactions:
|
3
3
|
- request:
|
4
4
|
method: get
|
5
|
-
uri: https://graph.facebook.com/v2.8/act_10152335766987003/campaigns?access_token=<access_token>&effective_status%5B%5D=ACTIVE&fields=id,account_id,buying_type,can_use_spend_cap,configured_status,created_time,effective_status,name,objective,start_time,stop_time,updated_time,spend_cap&limit=100
|
5
|
+
uri: https://graph.facebook.com/v2.8/act_10152335766987003/campaigns?access_token=<access_token>&appsecret_proof=<appsecret_proof>&effective_status%5B%5D=ACTIVE&fields=id,account_id,buying_type,can_use_spend_cap,configured_status,created_time,effective_status,name,objective,start_time,stop_time,updated_time,spend_cap&limit=100
|
6
6
|
body:
|
7
7
|
encoding: US-ASCII
|
8
8
|
string: ''
|
@@ -2,7 +2,7 @@
|
|
2
2
|
http_interactions:
|
3
3
|
- request:
|
4
4
|
method: get
|
5
|
-
uri: https://graph.facebook.com/v2.8/act_10152335766987003/adcreatives?access_token=<access_token>&fields=id,name,object_story_id,object_story_spec,object_type,thumbnail_url,run_status&limit=100
|
5
|
+
uri: https://graph.facebook.com/v2.8/act_10152335766987003/adcreatives?access_token=<access_token>&appsecret_proof=<appsecret_proof>&fields=id,name,object_story_id,object_story_spec,object_type,thumbnail_url,run_status&limit=100
|
6
6
|
body:
|
7
7
|
encoding: US-ASCII
|
8
8
|
string: ''
|
@@ -2,7 +2,7 @@
|
|
2
2
|
http_interactions:
|
3
3
|
- request:
|
4
4
|
method: get
|
5
|
-
uri: https://graph.facebook.com/v2.8/act_10152335766987003/adimages?access_token=<access_token>&fields=id,hash,account_id,name,permalink_url,original_width,original_height&hashes%5B%5D=d8fc613662fb5ef6cf5fb9d1fe779315
|
5
|
+
uri: https://graph.facebook.com/v2.8/act_10152335766987003/adimages?access_token=<access_token>&appsecret_proof=<appsecret_proof>&fields=id,hash,account_id,name,permalink_url,original_width,original_height&hashes%5B%5D=d8fc613662fb5ef6cf5fb9d1fe779315
|
6
6
|
body:
|
7
7
|
encoding: US-ASCII
|
8
8
|
string: ''
|
@@ -2,7 +2,7 @@
|
|
2
2
|
http_interactions:
|
3
3
|
- request:
|
4
4
|
method: get
|
5
|
-
uri: https://graph.facebook.com/v2.8/act_10152335766987003/adsets?access_token=<access_token>&effective_status%5B%5D=ACTIVE&fields=id,account_id,campaign_id,name,status,configured_status,effective_status,bid_amount,billing_event,optimization_goal,pacing_type,daily_budget,budget_remaining,lifetime_budget,promoted_object,targeting,created_time,updated_time&limit=100
|
5
|
+
uri: https://graph.facebook.com/v2.8/act_10152335766987003/adsets?access_token=<access_token>&appsecret_proof=<appsecret_proof>&effective_status%5B%5D=ACTIVE&fields=id,account_id,campaign_id,name,status,configured_status,effective_status,is_autobid,bid_amount,billing_event,optimization_goal,pacing_type,daily_budget,budget_remaining,lifetime_budget,promoted_object,targeting,created_time,updated_time&limit=100
|
6
6
|
body:
|
7
7
|
encoding: US-ASCII
|
8
8
|
string: ''
|
@@ -2,7 +2,7 @@
|
|
2
2
|
http_interactions:
|
3
3
|
- request:
|
4
4
|
method: get
|
5
|
-
uri: https://graph.facebook.com/v2.8/act_10152335766987003/ads?access_token=<access_token>&effective_status%5B%5D=ACTIVE&fields=id,account_id,campaign_id,adset_id,adlabels,bid_amount,bid_info,bid_type,configured_status,conversion_specs,created_time,creative,effective_status,last_updated_by_app_id,name,tracking_specs,updated_time,ad_review_feedback&limit=100
|
5
|
+
uri: https://graph.facebook.com/v2.8/act_10152335766987003/ads?access_token=<access_token>&appsecret_proof=<appsecret_proof>&effective_status%5B%5D=ACTIVE&fields=id,account_id,campaign_id,adset_id,adlabels,bid_amount,bid_info,bid_type,configured_status,conversion_specs,created_time,creative,effective_status,last_updated_by_app_id,name,tracking_specs,updated_time,ad_review_feedback&limit=100
|
6
6
|
body:
|
7
7
|
encoding: US-ASCII
|
8
8
|
string: ''
|
@@ -2,7 +2,7 @@
|
|
2
2
|
http_interactions:
|
3
3
|
- request:
|
4
4
|
method: get
|
5
|
-
uri: https://graph.facebook.com/v2.8/me/adaccounts?access_token=<access_token>&fields=id,account_id,account_status,age,created_time,currency,name
|
5
|
+
uri: https://graph.facebook.com/v2.8/me/adaccounts?access_token=<access_token>&appsecret_proof=<appsecret_proof>&fields=id,account_id,account_status,age,created_time,currency,name
|
6
6
|
body:
|
7
7
|
encoding: US-ASCII
|
8
8
|
string: ''
|
data/spec/fixtures/cassettes/FacebookAds_AdAccount/_create_ad_campaign/creates_a_new_ad_campaign.yml
CHANGED
@@ -61,7 +61,7 @@ http_interactions:
|
|
61
61
|
recorded_at: Wed, 26 Apr 2017 00:48:41 GMT
|
62
62
|
- request:
|
63
63
|
method: get
|
64
|
-
uri: https://graph.facebook.com/v2.8/6076262393242?access_token=<access_token>&fields=id,account_id,buying_type,can_use_spend_cap,configured_status,created_time,effective_status,name,objective,start_time,stop_time,updated_time,spend_cap
|
64
|
+
uri: https://graph.facebook.com/v2.8/6076262393242?access_token=<access_token>&appsecret_proof=<appsecret_proof>&fields=id,account_id,buying_type,can_use_spend_cap,configured_status,created_time,effective_status,name,objective,start_time,stop_time,updated_time,spend_cap
|
65
65
|
body:
|
66
66
|
encoding: US-ASCII
|
67
67
|
string: ''
|
@@ -2811,7 +2811,7 @@ http_interactions:
|
|
2811
2811
|
recorded_at: Wed, 26 Apr 2017 00:48:43 GMT
|
2812
2812
|
- request:
|
2813
2813
|
method: get
|
2814
|
-
uri: https://graph.facebook.com/v2.8/act_10152335766987003/adimages?access_token=<access_token>&fields=id,hash,account_id,name,permalink_url,original_width,original_height&hashes%5B%5D=d8fc613662fb5ef6cf5fb9d1fe779315
|
2814
|
+
uri: https://graph.facebook.com/v2.8/act_10152335766987003/adimages?access_token=<access_token>&appsecret_proof=<appsecret_proof>&fields=id,hash,account_id,name,permalink_url,original_width,original_height&hashes%5B%5D=d8fc613662fb5ef6cf5fb9d1fe779315
|
2815
2815
|
body:
|
2816
2816
|
encoding: US-ASCII
|
2817
2817
|
string: ''
|
@@ -2,7 +2,7 @@
|
|
2
2
|
http_interactions:
|
3
3
|
- request:
|
4
4
|
method: get
|
5
|
-
uri: https://graph.facebook.com/v2.8/me/adaccounts?access_token=<access_token>&fields=id,account_id,account_status,age,created_time,currency,name
|
5
|
+
uri: https://graph.facebook.com/v2.8/me/adaccounts?access_token=<access_token>&appsecret_proof=<appsecret_proof>&fields=id,account_id,account_status,age,created_time,currency,name
|
6
6
|
body:
|
7
7
|
encoding: US-ASCII
|
8
8
|
string: ''
|
@@ -2,7 +2,7 @@
|
|
2
2
|
http_interactions:
|
3
3
|
- request:
|
4
4
|
method: get
|
5
|
-
uri: https://graph.facebook.com/v2.8/act_10152335766987003/reachestimate?access_token=<access_token>¤cy=USD&optimize_for=OFFSITE_CONVERSIONS&targeting_spec=%7B%22genders%22:%5B2%5D,%22age_min%22:18,%22age_max%22:20,%22geo_locations%22:%7B%22countries%22:%5B%22US%22%5D%7D%7D
|
5
|
+
uri: https://graph.facebook.com/v2.8/act_10152335766987003/reachestimate?access_token=<access_token>&appsecret_proof=<appsecret_proof>¤cy=USD&optimize_for=OFFSITE_CONVERSIONS&targeting_spec=%7B%22genders%22:%5B2%5D,%22age_min%22:18,%22age_max%22:20,%22geo_locations%22:%7B%22countries%22:%5B%22US%22%5D%7D%7D
|
6
6
|
body:
|
7
7
|
encoding: US-ASCII
|
8
8
|
string: ''
|
@@ -2,7 +2,7 @@
|
|
2
2
|
http_interactions:
|
3
3
|
- request:
|
4
4
|
method: get
|
5
|
-
uri: https://graph.facebook.com/v2.8/6076262142242?access_token=<access_token>&fields=id,account_id,buying_type,can_use_spend_cap,configured_status,created_time,effective_status,name,objective,start_time,stop_time,updated_time,spend_cap
|
5
|
+
uri: https://graph.facebook.com/v2.8/6076262142242?access_token=<access_token>&appsecret_proof=<appsecret_proof>&fields=id,account_id,buying_type,can_use_spend_cap,configured_status,created_time,effective_status,name,objective,start_time,stop_time,updated_time,spend_cap
|
6
6
|
body:
|
7
7
|
encoding: US-ASCII
|
8
8
|
string: ''
|
@@ -55,7 +55,7 @@ http_interactions:
|
|
55
55
|
recorded_at: Wed, 26 Apr 2017 00:52:19 GMT
|
56
56
|
- request:
|
57
57
|
method: delete
|
58
|
-
uri: https://graph.facebook.com/v2.8/6076262142242?access_token=<access_token>
|
58
|
+
uri: https://graph.facebook.com/v2.8/6076262142242?access_token=<access_token>&appsecret_proof=<appsecret_proof>
|
59
59
|
body:
|
60
60
|
encoding: US-ASCII
|
61
61
|
string: ''
|
@@ -110,7 +110,7 @@ http_interactions:
|
|
110
110
|
recorded_at: Wed, 26 Apr 2017 00:52:20 GMT
|
111
111
|
- request:
|
112
112
|
method: get
|
113
|
-
uri: https://graph.facebook.com/v2.8/6076262142242?access_token=<access_token>&fields=id,account_id,buying_type,can_use_spend_cap,configured_status,created_time,effective_status,name,objective,start_time,stop_time,updated_time,spend_cap
|
113
|
+
uri: https://graph.facebook.com/v2.8/6076262142242?access_token=<access_token>&appsecret_proof=<appsecret_proof>&fields=id,account_id,buying_type,can_use_spend_cap,configured_status,created_time,effective_status,name,objective,start_time,stop_time,updated_time,spend_cap
|
114
114
|
body:
|
115
115
|
encoding: US-ASCII
|
116
116
|
string: ''
|
@@ -1,4 +1,5 @@
|
|
1
1
|
FacebookAds.business_id = '760977220612233'
|
2
2
|
FacebookAds.access_token = ENV['FACEBOOK_ACCESS_TOKEN'] || 'fake-facebook-access-token'
|
3
|
+
FacebookAds.app_secret = ENV['FACEBOOK_APP_SECRET'] || 'fake-facebook-app-secret'
|
3
4
|
# FacebookAds.logger = Logger.new(STDOUT)
|
4
5
|
# FacebookAds.logger.level = Logger::Severity::DEBUG
|
data/spec/support/vcr.rb
CHANGED
@@ -7,10 +7,13 @@ VCR.configure do |c|
|
|
7
7
|
c.default_cassette_options = {
|
8
8
|
match_requests_on: [
|
9
9
|
:method,
|
10
|
-
VCR.request_matchers.uri_without_param(:access_token)
|
10
|
+
VCR.request_matchers.uri_without_param(:access_token, :app_secret)
|
11
11
|
]
|
12
12
|
}
|
13
13
|
c.filter_sensitive_data('<access_token>') do
|
14
|
-
|
14
|
+
FacebookAds.access_token
|
15
|
+
end
|
16
|
+
c.filter_sensitive_data('<appsecret_proof>') do
|
17
|
+
FacebookAds.appsecret_proof
|
15
18
|
end
|
16
19
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: facebook_ads
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.4'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Estreich
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -38,25 +38,22 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '3.4'
|
41
|
-
description: This gem allows to easily manage your Facebook ads via
|
42
|
-
|
43
|
-
email:
|
41
|
+
description: This gem allows to easily manage your Facebook ads via Facebook's Marketing
|
42
|
+
API in ruby.
|
43
|
+
email: chris@tophatter.com
|
44
44
|
executables:
|
45
45
|
- console
|
46
46
|
extensions: []
|
47
47
|
extra_rdoc_files:
|
48
48
|
- README.md
|
49
49
|
files:
|
50
|
-
- ".approvals"
|
51
50
|
- ".coveralls.yml"
|
52
51
|
- ".gitignore"
|
53
52
|
- ".rspec"
|
54
53
|
- ".rubocop.yml"
|
55
|
-
- ".rubocop_todo.yml"
|
56
54
|
- ".travis.yml"
|
57
55
|
- CHANGELOG.md
|
58
56
|
- Gemfile
|
59
|
-
- Gemfile.lock
|
60
57
|
- LICENSE.md
|
61
58
|
- README.md
|
62
59
|
- Rakefile
|
@@ -117,7 +114,7 @@ files:
|
|
117
114
|
- spec/support/facebook_ads.rb
|
118
115
|
- spec/support/rest_client.rb
|
119
116
|
- spec/support/vcr.rb
|
120
|
-
homepage: https://github.com/
|
117
|
+
homepage: https://github.com/tophatter/facebook-ruby-ads-sdk
|
121
118
|
licenses:
|
122
119
|
- MIT
|
123
120
|
metadata: {}
|
@@ -137,8 +134,47 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
134
|
version: '0'
|
138
135
|
requirements: []
|
139
136
|
rubyforge_project:
|
140
|
-
rubygems_version: 2.6.
|
137
|
+
rubygems_version: 2.6.12
|
141
138
|
signing_key:
|
142
139
|
specification_version: 4
|
143
140
|
summary: Facebook Marketing API SDK for Ruby.
|
144
|
-
test_files:
|
141
|
+
test_files:
|
142
|
+
- spec/facebook_ads/ad_account_spec.rb
|
143
|
+
- spec/facebook_ads/ad_campaign_spec.rb
|
144
|
+
- spec/facebook_ads/ad_creative_spec.rb
|
145
|
+
- spec/facebook_ads/ad_image_spec.rb
|
146
|
+
- spec/facebook_ads/ad_insight_spec.rb
|
147
|
+
- spec/facebook_ads/ad_product_catalog_spec.rb
|
148
|
+
- spec/facebook_ads/ad_product_feed_spec.rb
|
149
|
+
- spec/facebook_ads/ad_product_set_spec.rb
|
150
|
+
- spec/facebook_ads/ad_product_spec.rb
|
151
|
+
- spec/facebook_ads/ad_set_spec.rb
|
152
|
+
- spec/facebook_ads/ad_spec.rb
|
153
|
+
- spec/facebook_ads/ad_targeting_spec.rb
|
154
|
+
- spec/facebook_ads/facebook_ads_spec.rb
|
155
|
+
- spec/fixtures/approvals/facebookads_adaccount/ad_campaigns/lists_campaigns.approved.json
|
156
|
+
- spec/fixtures/approvals/facebookads_adaccount/ad_creatives/lists_creatives.approved.json
|
157
|
+
- spec/fixtures/approvals/facebookads_adaccount/ad_images/lists_images.approved.json
|
158
|
+
- spec/fixtures/approvals/facebookads_adaccount/ad_sets/lists_ad_sets.approved.json
|
159
|
+
- spec/fixtures/approvals/facebookads_adaccount/ads/lists_ads.approved.json
|
160
|
+
- spec/fixtures/approvals/facebookads_adaccount/all/lists_all_accounts.approved.json
|
161
|
+
- spec/fixtures/approvals/facebookads_adaccount/create_ad_campaign/creates_a_new_ad_campaign.approved.json
|
162
|
+
- spec/fixtures/approvals/facebookads_adaccount/create_ad_images/creates_an_image.approved.json
|
163
|
+
- spec/fixtures/approvals/facebookads_adaccount/find_by/finds_a_specific_account.approved.json
|
164
|
+
- spec/fixtures/approvals/facebookads_adaccount/reach_estimate/estimates_the_reach_of_a_targeting_spec.approved.json
|
165
|
+
- spec/fixtures/cassettes/FacebookAds_AdAccount/_ad_campaigns/lists_campaigns.yml
|
166
|
+
- spec/fixtures/cassettes/FacebookAds_AdAccount/_ad_creatives/lists_creatives.yml
|
167
|
+
- spec/fixtures/cassettes/FacebookAds_AdAccount/_ad_images/lists_images.yml
|
168
|
+
- spec/fixtures/cassettes/FacebookAds_AdAccount/_ad_sets/lists_ad_sets.yml
|
169
|
+
- spec/fixtures/cassettes/FacebookAds_AdAccount/_ads/lists_ads.yml
|
170
|
+
- spec/fixtures/cassettes/FacebookAds_AdAccount/_all/lists_all_accounts.yml
|
171
|
+
- spec/fixtures/cassettes/FacebookAds_AdAccount/_create_ad_campaign/creates_a_new_ad_campaign.yml
|
172
|
+
- spec/fixtures/cassettes/FacebookAds_AdAccount/_create_ad_images/creates_an_image.yml
|
173
|
+
- spec/fixtures/cassettes/FacebookAds_AdAccount/_find_by/finds_a_specific_account.yml
|
174
|
+
- spec/fixtures/cassettes/FacebookAds_AdAccount/_reach_estimate/estimates_the_reach_of_a_targeting_spec.yml
|
175
|
+
- spec/fixtures/cassettes/FacebookAds_AdCampaign/_destroy/creates_a_new_ad_campaign.yml
|
176
|
+
- spec/spec_helper.rb
|
177
|
+
- spec/support/approvals.rb
|
178
|
+
- spec/support/facebook_ads.rb
|
179
|
+
- spec/support/rest_client.rb
|
180
|
+
- spec/support/vcr.rb
|
data/.approvals
DELETED
File without changes
|
data/.rubocop_todo.yml
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
# This configuration was generated by
|
2
|
-
# `rubocop --auto-gen-config`
|
3
|
-
# on 2017-04-25 18:21:46 -0700 using RuboCop version 0.48.1.
|
4
|
-
# The point is for the user to remove these configuration records
|
5
|
-
# one by one as the offenses are removed from the code base.
|
6
|
-
# Note that changes in the inspected code, or installation of new
|
7
|
-
# versions of RuboCop, may require this file to be generated again.
|
8
|
-
|
9
|
-
# Offense count: 2
|
10
|
-
# Cop supports --auto-correct.
|
11
|
-
# Configuration parameters: EnforcedStyleAlignWith, SupportedStylesAlignWith, AutoCorrect.
|
12
|
-
# SupportedStylesAlignWith: keyword, variable, start_of_line
|
13
|
-
Lint/EndAlignment:
|
14
|
-
Exclude:
|
15
|
-
- 'lib/facebook_ads/ad_account.rb'
|
16
|
-
- 'lib/facebook_ads/base.rb'
|
data/Gemfile.lock
DELETED
@@ -1,118 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
facebook_ads (0.1.11)
|
5
|
-
hashie (~> 3.4)
|
6
|
-
rest-client (>= 1.6)
|
7
|
-
|
8
|
-
GEM
|
9
|
-
remote: https://rubygems.org/
|
10
|
-
specs:
|
11
|
-
addressable (2.5.1)
|
12
|
-
public_suffix (~> 2.0, >= 2.0.2)
|
13
|
-
approvals (0.0.22)
|
14
|
-
nokogiri (~> 1.6)
|
15
|
-
thor (~> 0.18)
|
16
|
-
ast (2.3.0)
|
17
|
-
awesome_print (1.7.0)
|
18
|
-
coderay (1.1.1)
|
19
|
-
coveralls (0.8.20)
|
20
|
-
json (>= 1.8, < 3)
|
21
|
-
simplecov (~> 0.14.1)
|
22
|
-
term-ansicolor (~> 1.3)
|
23
|
-
thor (~> 0.19.4)
|
24
|
-
tins (~> 1.6)
|
25
|
-
crack (0.4.3)
|
26
|
-
safe_yaml (~> 1.0.0)
|
27
|
-
diff-lcs (1.3)
|
28
|
-
docile (1.1.5)
|
29
|
-
domain_name (0.5.20170404)
|
30
|
-
unf (>= 0.0.5, < 1.0.0)
|
31
|
-
hashdiff (0.3.2)
|
32
|
-
hashie (3.5.5)
|
33
|
-
http-cookie (1.0.3)
|
34
|
-
domain_name (~> 0.5)
|
35
|
-
json (2.1.0)
|
36
|
-
method_source (0.8.2)
|
37
|
-
mime-types (3.1)
|
38
|
-
mime-types-data (~> 3.2015)
|
39
|
-
mime-types-data (3.2016.0521)
|
40
|
-
mini_portile2 (2.1.0)
|
41
|
-
multi_json (1.12.1)
|
42
|
-
netrc (0.11.0)
|
43
|
-
nokogiri (1.7.1)
|
44
|
-
mini_portile2 (~> 2.1.0)
|
45
|
-
parser (2.4.0.0)
|
46
|
-
ast (~> 2.2)
|
47
|
-
powerpack (0.1.1)
|
48
|
-
pry (0.10.4)
|
49
|
-
coderay (~> 1.1.0)
|
50
|
-
method_source (~> 0.8.1)
|
51
|
-
slop (~> 3.4)
|
52
|
-
public_suffix (2.0.5)
|
53
|
-
rainbow (2.2.2)
|
54
|
-
rake
|
55
|
-
rake (12.0.0)
|
56
|
-
rest-client (2.0.2)
|
57
|
-
http-cookie (>= 1.0.2, < 2.0)
|
58
|
-
mime-types (>= 1.16, < 4.0)
|
59
|
-
netrc (~> 0.8)
|
60
|
-
rspec (3.5.0)
|
61
|
-
rspec-core (~> 3.5.0)
|
62
|
-
rspec-expectations (~> 3.5.0)
|
63
|
-
rspec-mocks (~> 3.5.0)
|
64
|
-
rspec-core (3.5.4)
|
65
|
-
rspec-support (~> 3.5.0)
|
66
|
-
rspec-expectations (3.5.0)
|
67
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
68
|
-
rspec-support (~> 3.5.0)
|
69
|
-
rspec-mocks (3.5.0)
|
70
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
71
|
-
rspec-support (~> 3.5.0)
|
72
|
-
rspec-support (3.5.0)
|
73
|
-
rubocop (0.48.1)
|
74
|
-
parser (>= 2.3.3.1, < 3.0)
|
75
|
-
powerpack (~> 0.1)
|
76
|
-
rainbow (>= 1.99.1, < 3.0)
|
77
|
-
ruby-progressbar (~> 1.7)
|
78
|
-
unicode-display_width (~> 1.0, >= 1.0.1)
|
79
|
-
ruby-progressbar (1.8.1)
|
80
|
-
safe_yaml (1.0.4)
|
81
|
-
simplecov (0.14.1)
|
82
|
-
docile (~> 1.1.0)
|
83
|
-
json (>= 1.8, < 3)
|
84
|
-
simplecov-html (~> 0.10.0)
|
85
|
-
simplecov-html (0.10.0)
|
86
|
-
slop (3.6.0)
|
87
|
-
term-ansicolor (1.6.0)
|
88
|
-
tins (~> 1.0)
|
89
|
-
thor (0.19.4)
|
90
|
-
tins (1.13.2)
|
91
|
-
unf (0.1.4)
|
92
|
-
unf_ext
|
93
|
-
unf_ext (0.0.7.4)
|
94
|
-
unicode-display_width (1.2.1)
|
95
|
-
vcr (3.0.3)
|
96
|
-
webmock (3.0.1)
|
97
|
-
addressable (>= 2.3.6)
|
98
|
-
crack (>= 0.3.2)
|
99
|
-
hashdiff
|
100
|
-
|
101
|
-
PLATFORMS
|
102
|
-
ruby
|
103
|
-
|
104
|
-
DEPENDENCIES
|
105
|
-
approvals
|
106
|
-
awesome_print
|
107
|
-
coveralls
|
108
|
-
facebook_ads!
|
109
|
-
multi_json
|
110
|
-
pry
|
111
|
-
rake
|
112
|
-
rspec
|
113
|
-
rubocop
|
114
|
-
vcr
|
115
|
-
webmock
|
116
|
-
|
117
|
-
BUNDLED WITH
|
118
|
-
1.14.6
|