Class: Zuck::TargetingSpec

Inherits:
Object
  • Object
show all
Defined in:
lib/zuck/facebook/targeting_spec.rb

Overview

Some helpers around https://developers.facebook.com/docs/reference/ads-api/targeting-specs/ Use like this:

> ts = Facebook::TargetingSpec.new(graph, ad_account, keyword: 'foo', countries: ['US'])
> ts.spec
=> {
   :countries => [
     [0] "US"
   ],
    :keywords => [
     [0] "foo"
   ]
}
> ts.fetch_reach
=> 12345

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(graph, ad_account, spec = nil) ⇒ TargetingSpec

Returns a new instance of TargetingSpec.

Parameters:

  • graph (Koala::Facebook::API)

    The koala graph object to use

  • ad_account (String)

    The ad account you want to use to query the facebook api

  • spec (Hash) (defaults to: nil)

    The targeting spec. Supported keys:

    • :countries: Array of uppercase two letter country codes
    • :genders (optional): Can be an array with 2 (female) and 1 (male)
    • :gender (optional): Set it to 'male' or 'female' to autoconfigure the genders array
    • :age_min (optional): In years
    • :age_max (optional): In years
    • :age_class (optional): Set it to young or old to autoconfigure age_min and age_max for people older or younger than 25
    • :locales (optional): [disabled] Array of integers, valid keys are here https://graph.facebook.com/search?type=adlocale&q=en
    • :keywords: Array of strings with keywords


68
69
70
71
72
73
# File 'lib/zuck/facebook/targeting_spec.rb', line 68

def initialize(graph, , spec = nil)
  @validated_keywords = {}
  @graph = graph
  @ad_account = "act_#{}".gsub('act_act_', 'act_')
  self.spec = spec
end

Instance Attribute Details

#graphObject (readonly)

Returns the value of attribute graph.



52
53
54
# File 'lib/zuck/facebook/targeting_spec.rb', line 52

def graph
  @graph
end

#specObject

Returns the value of attribute spec.



52
53
54
# File 'lib/zuck/facebook/targeting_spec.rb', line 52

def spec
  @spec
end

Class Method Details

.batch_reaches(graph, ad_account, specs) ⇒ Array<Hash>

Fetches a bunch of reach estimates from facebook at once.

Parameters:

  • graph

    Koala graph instance

  • specs (Array<Hash>)

    An array of specs as you would pass to #initialize

Returns:

  • (Array<Hash>)

    Each spec you passed in as the requests parameter with the [:success] set to true/false and [:reach]/[:error] are filled respectively



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/zuck/facebook/targeting_spec.rb', line 128

def self.batch_reaches(graph, , specs)

  # Make all requests
  reaches = []
  specs.each_slice(50) do |specs_slice|
    reaches += graph.batch do |batch_api|
      specs_slice.each do |spec|
        targeting_spec = Zuck::TargetingSpec.new(batch_api, , spec)
        targeting_spec.fetch_reach
      end
    end
  end

  # Structure results
  result = []
  reaches.each_with_index do |res, i|
    result[i] = specs[i].dup
    if res.class < StandardError
      result[i][:success] = false
      result[i][:error]   = res
    else
      result[i][:success] = true
      result[i][:reach]   = res.with_indifferent_access
    end
  end
  result
end

.fetch_reach(graph, ad_account, options) ⇒ TargetingSpec

Convenience method, parameters are the same as in #initialize

Returns:



158
159
160
161
# File 'lib/zuck/facebook/targeting_spec.rb', line 158

def self.fetch_reach(graph, , options)
  ts = Zuck::TargetingSpec.new(graph, , options)
  ts.fetch_reach
end

.validate_keywords(graph, keywords) ⇒ Hash

Checks the ad api to see if the given keywords are valid

Returns:

  • (Hash)

    The keys are the (lowercased) keywords and the values their validity



113
114
115
116
117
118
119
120
121
# File 'lib/zuck/facebook/targeting_spec.rb', line 113

def self.validate_keywords(graph, keywords)
  keywords = normalize_array(keywords).map{|k| k.gsub(',', '%2C')}
  search = graph.search(nil, type: 'adkeywordvalid', keyword_list: keywords.join(","))
  results = {}
  search.each do |r|
    results[r['name']] = r['valid']
  end
  results
end

Instance Method Details

#fetch_reachHash

Returns:



83
84
85
86
87
88
89
90
# File 'lib/zuck/facebook/targeting_spec.rb', line 83

def fetch_reach
  validate_spec
  json = @spec.to_json
  o = "#{@ad_account}/reachestimate"
  result = graph.get_object(o, targeting_spec: json)
  return false unless result
  result.with_indifferent_access
end

#validate_keyword(keyword) ⇒ Object

Validates a single keyword from the cache or calls validate_keywords.to validate the keywords via facebook's api.

Parameters:

  • keyword (String)

    A single keyword

Returns:

  • boolean



103
104
105
106
107
108
109
# File 'lib/zuck/facebook/targeting_spec.rb', line 103

def validate_keyword(keyword)
  if @validated_keywords[keyword] == nil
    keywords = normalize_array([@spec[:keywords]] + [keyword])
    @validated_keywords = self.class.validate_keywords(@graph, keywords)
  end
  @validated_keywords[keyword] == true
end

#validate_keywordsObject



92
93
94
95
96
# File 'lib/zuck/facebook/targeting_spec.rb', line 92

def validate_keywords
  @spec[:keywords].each do |w|
    raise(InvalidKeywordError, w) unless validate_keyword(w)
  end
end