zuck 0.2.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.travis.yml +0 -1
- data/CHANGELOG.markdown +12 -1
- data/Gemfile +4 -4
- data/Gemfile.lock +40 -11
- data/README.markdown +6 -6
- data/VERSION +1 -1
- data/lib/zuck/facebook/ad_interest.rb +44 -0
- data/lib/zuck/facebook/targeting_spec.rb +23 -22
- data/spec/fixtures/ad_interest_search_disney.yml +54 -0
- data/spec/fixtures/ad_interest_search_moviepilot.yml +138 -0
- data/spec/fixtures/{ad_keyword_search_nonexistant.yml → ad_interest_search_nonexistant.yml} +12 -12
- data/spec/fixtures/reach_for_invalid_interest.yml +186 -0
- data/spec/fixtures/reach_for_valid_keywords.yml +56 -11
- data/spec/fixtures/reach_for_valid_keywords_male_young.yml +65 -14
- data/spec/lib/zuck/facebook/ad_interest_spec.rb +23 -0
- data/spec/lib/zuck/facebook/targeting_spec_spec.rb +35 -34
- data/zuck.gemspec +24 -23
- metadata +61 -102
- data/lib/zuck/facebook/ad_keyword.rb +0 -45
- data/spec/fixtures/ad_keyword_search_disney.yml +0 -53
- data/spec/fixtures/ad_keyword_search_moviepilot.yml +0 -48
- data/spec/fixtures/reach_for_invalid_keyword.yml +0 -48
- data/spec/lib/zuck/facebook/ad_keyword_spec.rb +0 -23
@@ -1,45 +0,0 @@
|
|
1
|
-
module Zuck
|
2
|
-
module AdKeyword
|
3
|
-
extend Zuck::Helpers
|
4
|
-
extend self
|
5
|
-
|
6
|
-
# Given a keyword, make a guess on what the closest keyword
|
7
|
-
# on the facebook ads api is. It tends to use a # prefixed
|
8
|
-
# keyword if available, and also a more popular one over a less
|
9
|
-
# popular one
|
10
|
-
def best_guess(graph, keyword)
|
11
|
-
search(graph, keyword).sort do |a,b|
|
12
|
-
if a[:audience].to_i > 0 || b[:audience].to_i > 0
|
13
|
-
a[:audience].to_i <=> b[:audience].to_i
|
14
|
-
else
|
15
|
-
b[:keyword].length <=> a[:keyword].length
|
16
|
-
end
|
17
|
-
end.last
|
18
|
-
end
|
19
|
-
|
20
|
-
# Checks the ad api to see if the given keywords are valid
|
21
|
-
# @return [Hash] The keys are the (lowercased) keywords and the values their validity
|
22
|
-
def validate(graph, keywords)
|
23
|
-
keywords = normalize_array(keywords).map{|k| k.gsub(',', '%2C')}
|
24
|
-
search = graph.search(nil, type: 'adkeywordvalid', keyword_list: keywords.join(","))
|
25
|
-
results = {}
|
26
|
-
search.each do |r|
|
27
|
-
results[r['name']] = r['valid']
|
28
|
-
end
|
29
|
-
results
|
30
|
-
end
|
31
|
-
|
32
|
-
# Ad keyword search
|
33
|
-
def search(graph, keyword)
|
34
|
-
results = graph.search(keyword, type: :adkeyword).map do |r|
|
35
|
-
audience = r['description'].scan(/[0-9]+/).join('').to_i rescue nil
|
36
|
-
{
|
37
|
-
keyword: r['name'],
|
38
|
-
id: r['id'],
|
39
|
-
audience: audience
|
40
|
-
}
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
---
|
2
|
-
http_interactions:
|
3
|
-
- request:
|
4
|
-
method: get
|
5
|
-
uri: https://graph.facebook.com/search?access_token=CAAEvJ5vzhl8BAH8aCPOx0Ft9uNB147TF8weJ8hK0g7YVDRWU4eEih7tEKdJgmfk0vABZClZACJbEzyhSMbiShL6RpsfkZASfX1C9nv1AlFvjJajflqkyYZAlpE2edT0FJHjdh4NFg0ZCt0sBgq0kZABtKsjuU18aMURLE7rjKHR4X8NkXBUafg1T4uZARRNqboZD&q=disney&type=adkeyword
|
6
|
-
body:
|
7
|
-
encoding: US-ASCII
|
8
|
-
string: ''
|
9
|
-
headers:
|
10
|
-
User-Agent:
|
11
|
-
- Faraday v0.8.7
|
12
|
-
Accept-Encoding:
|
13
|
-
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
14
|
-
Accept:
|
15
|
-
- ! '*/*'
|
16
|
-
response:
|
17
|
-
status:
|
18
|
-
code: 200
|
19
|
-
message: OK
|
20
|
-
headers:
|
21
|
-
Access-Control-Allow-Origin:
|
22
|
-
- ! '*'
|
23
|
-
Cache-Control:
|
24
|
-
- private, no-cache, no-store, must-revalidate
|
25
|
-
Content-Type:
|
26
|
-
- application/json; charset=UTF-8
|
27
|
-
Etag:
|
28
|
-
- ! '"ddd1522d71e8cbd1a1e68ee5ff6cf1e5dbde04cb"'
|
29
|
-
Expires:
|
30
|
-
- Sat, 01 Jan 2000 00:00:00 GMT
|
31
|
-
Pragma:
|
32
|
-
- no-cache
|
33
|
-
X-Fb-Rev:
|
34
|
-
- '934677'
|
35
|
-
X-Fb-Debug:
|
36
|
-
- EMkma5AVfp17cYzoavOVQXmuVbL15If4/tXmFADlVHw=
|
37
|
-
Date:
|
38
|
-
- Thu, 12 Sep 2013 13:21:33 GMT
|
39
|
-
Connection:
|
40
|
-
- keep-alive
|
41
|
-
Content-Length:
|
42
|
-
- '587'
|
43
|
-
body:
|
44
|
-
encoding: US-ASCII
|
45
|
-
string: ! '{"data":[{"name":"Disney Channel","id":6003711659516},{"name":"Disneyland","id":6003361056187},{"name":"Disney","id":6003663755307},{"name":"#The
|
46
|
-
Walt Disney Company","description":"Audience: 78,100,000","id":6003270522085},{"name":"#Disneyland","description":"Audience:
|
47
|
-
26,200,000","id":6003274193708},{"name":"#Disney Channel","description":"Audience:
|
48
|
-
22,600,000","id":6003327130854},{"name":"#The Walt Disney Company#Walt Disney
|
49
|
-
Pictures","description":"Audience: 9,200,000","id":6004710425192},{"name":"#Walt
|
50
|
-
Disney Pictures","description":"Audience: 9,200,000","id":6003050377616}]}'
|
51
|
-
http_version:
|
52
|
-
recorded_at: Thu, 12 Sep 2013 13:21:33 GMT
|
53
|
-
recorded_with: VCR 2.3.0
|
@@ -1,48 +0,0 @@
|
|
1
|
-
---
|
2
|
-
http_interactions:
|
3
|
-
- request:
|
4
|
-
method: get
|
5
|
-
uri: https://graph.facebook.com/search?access_token=CAAEvJ5vzhl8BAH8aCPOx0Ft9uNB147TF8weJ8hK0g7YVDRWU4eEih7tEKdJgmfk0vABZClZACJbEzyhSMbiShL6RpsfkZASfX1C9nv1AlFvjJajflqkyYZAlpE2edT0FJHjdh4NFg0ZCt0sBgq0kZABtKsjuU18aMURLE7rjKHR4X8NkXBUafg1T4uZARRNqboZD&q=moviepilot&type=adkeyword
|
6
|
-
body:
|
7
|
-
encoding: US-ASCII
|
8
|
-
string: ''
|
9
|
-
headers:
|
10
|
-
User-Agent:
|
11
|
-
- Faraday v0.8.7
|
12
|
-
Accept-Encoding:
|
13
|
-
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
14
|
-
Accept:
|
15
|
-
- ! '*/*'
|
16
|
-
response:
|
17
|
-
status:
|
18
|
-
code: 200
|
19
|
-
message: OK
|
20
|
-
headers:
|
21
|
-
Access-Control-Allow-Origin:
|
22
|
-
- ! '*'
|
23
|
-
Cache-Control:
|
24
|
-
- private, no-cache, no-store, must-revalidate
|
25
|
-
Content-Type:
|
26
|
-
- application/json; charset=UTF-8
|
27
|
-
Etag:
|
28
|
-
- ! '"5af1c2df3403480db8f57d9e9bfd2ed4a6f925ef"'
|
29
|
-
Expires:
|
30
|
-
- Sat, 01 Jan 2000 00:00:00 GMT
|
31
|
-
Pragma:
|
32
|
-
- no-cache
|
33
|
-
X-Fb-Rev:
|
34
|
-
- '934677'
|
35
|
-
X-Fb-Debug:
|
36
|
-
- 1gdeJKsX7G0woVPQzROCOkunT0R3FhMp/a/w9gdoUpE=
|
37
|
-
Date:
|
38
|
-
- Thu, 12 Sep 2013 13:21:33 GMT
|
39
|
-
Connection:
|
40
|
-
- keep-alive
|
41
|
-
Content-Length:
|
42
|
-
- '95'
|
43
|
-
body:
|
44
|
-
encoding: US-ASCII
|
45
|
-
string: ! '{"data":[{"name":"Moviepilot","id":6003327847780},{"name":"Moviepilotcom","id":6003495809986}]}'
|
46
|
-
http_version:
|
47
|
-
recorded_at: Thu, 12 Sep 2013 13:21:33 GMT
|
48
|
-
recorded_with: VCR 2.3.0
|
@@ -1,48 +0,0 @@
|
|
1
|
-
---
|
2
|
-
http_interactions:
|
3
|
-
- request:
|
4
|
-
method: get
|
5
|
-
uri: https://graph.facebook.com/search?access_token=CAAEvJ5vzhl8BAH8aCPOx0Ft9uNB147TF8weJ8hK0g7YVDRWU4eEih7tEKdJgmfk0vABZClZACJbEzyhSMbiShL6RpsfkZASfX1C9nv1AlFvjJajflqkyYZAlpE2edT0FJHjdh4NFg0ZCt0sBgq0kZABtKsjuU18aMURLE7rjKHR4X8NkXBUafg1T4uZARRNqboZD&keyword_list=Eminem,invalidsssssssssssssss&type=adkeywordvalid
|
6
|
-
body:
|
7
|
-
encoding: US-ASCII
|
8
|
-
string: ''
|
9
|
-
headers:
|
10
|
-
User-Agent:
|
11
|
-
- Faraday v0.8.7
|
12
|
-
Accept-Encoding:
|
13
|
-
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
14
|
-
Accept:
|
15
|
-
- ! '*/*'
|
16
|
-
response:
|
17
|
-
status:
|
18
|
-
code: 200
|
19
|
-
message: OK
|
20
|
-
headers:
|
21
|
-
Access-Control-Allow-Origin:
|
22
|
-
- ! '*'
|
23
|
-
Cache-Control:
|
24
|
-
- private, no-cache, no-store, must-revalidate
|
25
|
-
Content-Type:
|
26
|
-
- application/json; charset=UTF-8
|
27
|
-
Etag:
|
28
|
-
- ! '"1b6af91a08d48aeee5ffa0cf3437f38b61281b68"'
|
29
|
-
Expires:
|
30
|
-
- Sat, 01 Jan 2000 00:00:00 GMT
|
31
|
-
Pragma:
|
32
|
-
- no-cache
|
33
|
-
X-Fb-Rev:
|
34
|
-
- '934677'
|
35
|
-
X-Fb-Debug:
|
36
|
-
- J8DeY1E4Yqw7bJX0tlNMHLA1W2i+1busrhuPm8oG1vg=
|
37
|
-
Date:
|
38
|
-
- Thu, 12 Sep 2013 13:21:34 GMT
|
39
|
-
Connection:
|
40
|
-
- keep-alive
|
41
|
-
Content-Length:
|
42
|
-
- '108'
|
43
|
-
body:
|
44
|
-
encoding: US-ASCII
|
45
|
-
string: ! '{"data":[{"name":"Eminem","valid":true,"id":6003170652434},{"name":"invalidsssssssssssssss","valid":false}]}'
|
46
|
-
http_version:
|
47
|
-
recorded_at: Thu, 12 Sep 2013 13:21:34 GMT
|
48
|
-
recorded_with: VCR 2.3.0
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Zuck::AdKeyword do
|
4
|
-
let(:graph){ Koala::Facebook::API.new(test_access_token)}
|
5
|
-
|
6
|
-
it "finds the best keyword with a #" do
|
7
|
-
VCR.use_cassette('ad_keyword_search_disney') do
|
8
|
-
Zuck::AdKeyword.best_guess(graph, 'disney')[:keyword].should == '#The Walt Disney Company'
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
it "finds the best keyword when no keyword with # is available" do
|
13
|
-
VCR.use_cassette('ad_keyword_search_moviepilot') do
|
14
|
-
Zuck::AdKeyword.best_guess(graph, 'moviepilot')[:keyword].should == 'Moviepilot'
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
it "returns nil when nothing could be found" do
|
19
|
-
VCR.use_cassette('ad_keyword_search_nonexistant') do
|
20
|
-
Zuck::AdKeyword.best_guess(graph, 'ick spickeby').should be_nil
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|