Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Adparams #5

Closed
wants to merge 17 commits into from

2 participants

@jak4

Have a look.

Johannes Kaefer added some commits
Johannes Kaefer add AdParamService b650d5f
Johannes Kaefer when searching always use the IN parameter
always convert params[param_name] to Array
8ea0633
Johannes Kaefer fix self.find method (predicates and selector) 9085f08
Johannes Kaefer Merge branch 'fix_campaign_criteria' into adparams 7616eca
Johannes Kaefer fix AdsCommon::Errors::TypeMismatchError: AdsCommon::Errors::TypeMism…
…atchError: expected: 'Array', provided: 'Fixnum' for field 'values'
bb548a6
Johannes Kaefer fix AdsCommon::Errors::TypeMismatchError: AdsCommon::Errors::TypeMism…
…atchError: expected: 'Array', provided: 'Fixnum' for field 'values'
90d4a8b
Johannes Kaefer fix AdsCommon::Errors::TypeMismatchError: AdsCommon::Errors::TypeMism…
…atchError: expected: 'Array', provided: 'Fixnum' for field 'values'
041f57f
Johannes Kaefer try adparams service for first time 5d58bcd
Johannes Kaefer Merge branch 'configurable_yml_paths' into adparams 311cd8c
Johannes Kaefer add adparam to adapi.rb d9b1c19
Johannes Kaefer create method 0139cde
Johannes Kaefer operations has to be an array 153d7aa
Johannes Kaefer no error handling 3f20d65
Johannes Kaefer self.find returns now an array of keyword-objects 452cd90
Johannes Kaefer cleanup keywords
1) a Keyword-Object represents one Keyword returned via the AdGroupCriterionService
 1a) create now creates one keyword via the api
2) self.find will return an array with keyword-objects
ddfb64b
Johannes Kaefer shortend and match_type are troublesome e8ad8f8
Johannes Kaefer cleanup 846ac6e
@lstejskal
Owner

I rebased your updates and merged them with v201109 branch.

@lstejskal lstejskal closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 2, 2012
  1. add AdParamService

    Johannes Kaefer authored
  2. when searching always use the IN parameter

    Johannes Kaefer authored
    always convert params[param_name] to Array
  3. fix self.find method (predicates and selector)

    Johannes Kaefer authored
  4. Merge branch 'fix_campaign_criteria' into adparams

    Johannes Kaefer authored
Commits on Jan 3, 2012
  1. fix AdsCommon::Errors::TypeMismatchError: AdsCommon::Errors::TypeMism…

    Johannes Kaefer authored
    …atchError: expected: 'Array', provided: 'Fixnum' for field 'values'
  2. fix AdsCommon::Errors::TypeMismatchError: AdsCommon::Errors::TypeMism…

    Johannes Kaefer authored
    …atchError: expected: 'Array', provided: 'Fixnum' for field 'values'
  3. fix AdsCommon::Errors::TypeMismatchError: AdsCommon::Errors::TypeMism…

    Johannes Kaefer authored
    …atchError: expected: 'Array', provided: 'Fixnum' for field 'values'
  4. try adparams service for first time

    Johannes Kaefer authored
  5. Merge branch 'configurable_yml_paths' into adparams

    Johannes Kaefer authored
  6. add adparam to adapi.rb

    Johannes Kaefer authored
  7. create method

    Johannes Kaefer authored
  8. operations has to be an array

    Johannes Kaefer authored
Commits on Jan 4, 2012
  1. no error handling

    Johannes Kaefer authored
  2. self.find returns now an array of keyword-objects

    Johannes Kaefer authored
  3. cleanup keywords

    Johannes Kaefer authored
    1) a Keyword-Object represents one Keyword returned via the AdGroupCriterionService
     1a) create now creates one keyword via the api
    2) self.find will return an array with keyword-objects
  4. shortend and match_type are troublesome

    Johannes Kaefer authored
  5. cleanup

    Johannes Kaefer authored
This page is out of date. Refresh to see the latest.
View
1  lib/adapi.rb
@@ -20,6 +20,7 @@
require 'adapi/keyword'
require 'adapi/ad'
require 'adapi/ad/text_ad'
+require 'adapi/ad_param'
# monkeypatch HTTPI
require 'httpi_request_monkeypatch'
View
3  lib/adapi/ad/text_ad.rb
@@ -101,7 +101,8 @@ def self.find(amount = :all, params = {})
# supported condition parameters: ad_group_id and id
predicates = [ :ad_group_id, :id ].map do |param_name|
if params[param_name]
- {:field => param_name.to_s.camelcase, :operator => 'EQUALS', :values => params[param_name] }
+ value = Array.try_convert(params[param_name]) ? params_param_name : [params[param_name]]
+ {:field => param_name.to_s.camelcase, :operator => 'IN', :values => value }
end
end.compact
View
5 lib/adapi/ad_group.rb
@@ -93,10 +93,11 @@ def self.find(amount = :all, params = {})
first_only = (amount.to_sym == :first)
raise "Campaign ID is required" unless params[:campaign_id]
-
+
predicates = [ :campaign_id, :id ].map do |param_name|
if params[param_name]
- {:field => param_name.to_s.camelcase, :operator => 'EQUALS', :values => params[param_name] }
+ value = Array.try_convert(params[param_name]) ? params_param_name : [params[param_name]]
+ {:field => param_name.to_s.camelcase, :operator => 'IN', :values => value }
end
end.compact
View
89 lib/adapi/ad_param.rb
@@ -0,0 +1,89 @@
+# encoding: utf-8
+
+module Adapi
+ class AdParam < Api
+ attr_accessor :ad_group_id, :criterion_id, :insertion_text, :param_index
+
+ validates_presence_of :ad_group_id, :criterion_id
+
+ def attributes
+ super.merge(
+ 'ad_group_id' => ad_group_id, 'criterion_id' => criterion_id,
+ 'insertion_text' => insertion_text, 'param_index' => param_index
+ )
+ end
+
+ def initialize(params = {})
+ params[:service_name] = :AdParamService
+
+ %w{ ad_group_id criterion_id insertion_text param_index }.each do |param_name|
+ self.send "#{param_name}=", params[param_name.to_sym]
+ end
+
+ super(params)
+ end
+
+ def create
+ operation = {
+ :operator => 'SET',
+ :operand => serializable_hash
+ }
+
+ begin
+ response = @service.mutate([operation])
+
+ #rescue AdsCommon::Errors::HttpError => e
+ #self.errors.add(:base, e.message)
+
+ ## traps any exceptions raised by AdWords API
+ #rescue AdwordsApi::Errors::ApiException => e
+ # # return PolicyViolations so they can be sent again
+ # e.errors.each do |error|
+ # if (error[:api_error_type] == 'PolicyViolationError') && error[:is_exemptable]
+ # self.errors.add(error[:api_error_type], error[:key])
+ # else
+ # # otherwise, just report the errors
+ # self.errors.add( "[#{self.xsi_type.underscore}]", "#{error[:error_string]} @ #{error[:field_path]}")
+ # end
+ # end
+ end
+
+ response
+ end
+
+ def self.find(params = {})
+ params.symbolize_keys!
+
+ predicates = [ :ad_group_id, :criterion_id ].map do |param_name|
+ if params[param_name]
+ value = Array.try_convert(params[param_name]) ? params_param_name : [params[param_name]]
+ {:field => param_name.to_s.camelcase, :operator => 'IN', :values => value }
+ end
+ end.compact
+
+ selector = {
+ :fields => ['AdGroupId', 'CriterionId', 'InsertionText', 'ParamIndex'],
+ :predicates => predicates
+ }
+
+ response = AdParam.new.service.get(selector)
+
+ response = (response and response[:entries]) ? response[:entries] : []
+
+ response.map! do |ad_params_data|
+ AdParam.new(ad_params_data)
+ end
+
+ response
+ end
+
+ def serializable_hash
+ {
+ :ad_group_id => ad_group_id,
+ :criterion_id => criterion_id,
+ :param_index => param_index,
+ :insertion_text => insertion_text
+ }
+ end
+ end
+end
View
4 lib/adapi/campaign.rb
@@ -170,7 +170,9 @@ def self.find(amount = :all, params = {})
predicates = [ :id ].map do |param_name|
if params[param_name]
- {:field => param_name.to_s.camelcase, :operator => 'EQUALS', :values => params[param_name] }
+ # convert to array
+ value = Array.try_convert(params[param_name]) ? params_param_name : [params[param_name]]
+ {:field => param_name.to_s.camelcase, :operator => 'IN', :values => value }
end
end.compact
View
17 lib/adapi/campaign_criterion.rb
@@ -89,8 +89,21 @@ def self.find(params = {})
end
raise ArgumentError, "Campaing ID is required" unless params[:campaign_id]
-
- selector = { :campaign_ids => [ params[:campaign_id].to_i ] }
+
+ predicates = [ :campaign_id ].map do |param_name|
+ if params[param_name]
+ # convert to array
+ value = Array.try_convert(params[param_name]) ? params_param_name : [params[param_name]]
+ {:field => param_name.to_s.camelcase, :operator => 'IN', :values => value }
+ end
+ end.compact
+
+ # TODO: get more fields
+ selector = {
+ :fields => ['Id'],
+ :ordering => [{:field => 'Id', :sort_order => 'ASCENDING'}],
+ :predicates => predicates
+ }
response = CampaignCriterion.new.service.get(selector)
View
160 lib/adapi/keyword.rb
@@ -17,26 +17,52 @@
module Adapi
class Keyword < AdGroupCriterion
-
- attr_accessor :keywords
+ #:criterion=>{:id=>105790288, :type=>"KEYWORD", :criterion_type=>"Keyword", :text=>"systemtelefon", :match_type=>"PHRASE", :xsi_type=>"Keyword"}
+ attr_accessor :criterion_id, :criterion_type, :criterion_type, :criterion_text, :criterion_match_type, :criterion_xsi_type
+ #:ad_group_criterion_type=>"BiddableAdGroupCriterion",
+ attr_accessor :ad_group_criterion_type
+ #:stats=>{:network=>"SEARCH", :stats_type=>"Stats"},
+ attr_accessor :stats_network, :stats_type
+ #=> {:text=>{:ad_group_id=>1658215692, :criterion_use=>"BIDDABLE", :ad_group_criterion_type=>"BiddableAdGroupCriterion", :xsi_type=>"BiddableAdGroupCriterion"}, :match_type=>"BROAD", :negative=>false}
+ attr_accessor :criterion_use, :ad_group_criterion_type, :xsi_type, :negative #:match_type
def attributes
- super.merge('keywords' => keywords)
+ super.merge(serializable_hash)
end
- def initialize(params = {})
- params[:service_name] = :AdGroupCriterionService
-
- @xsi_type = 'AdGroupCriterion'
-
- %w{ keywords }.each do |param_name|
- self.send "#{param_name}=", params[param_name.to_sym]
- end
-
- self.keywords ||= []
- self.keywords.map! { |k| Keyword.keyword_attributes(k) }
+ def initialize( ext_options = {} )
+ options = default_options.merge(ext_options.delete_if{|k,v|v.nil?})
+
+ # I think this is just not necessary and maybe restricting later on
+ #%w{ keywords }.each do |param_name|
+ # self.send "#{param_name}=", params[param_name.to_sym]
+ #end
+
+ #self.match_type = options[:match_type],
+ self.negative = options[:negative],
+ self.ad_group_id = options[:ad_group_id],
+ self.criterion_use = options[:criterion_use],
+ self.ad_group_criterion_type = options[:ad_group_criterion_type],
+ self.xsi_type = options[:xsi_type],
+ self.id = options[:id],
+ self.criterion_type = options[:type],
+ self.criterion_text = options[:text],
+ self.criterion_match_type = options[:match_type],
+ self.criterion_xsi_type = options[:xsi_type],
+ self.stats_network = options[:network],
+ self.stats_type = options[:stats_type]
+
+ #self.keywords ||= []
+ #self.keywords.map! { |k| Keyword.keyword_attributes(k) }
+
+ super(options)
+ end
- super(params)
+ def default_options
+ {
+ :service_name => :AdGroupCriterionService,
+ :xsi_type => 'AdGroupCriterion'
+ }
end
# Converts keyword specification from shortened form to Google format
@@ -66,20 +92,20 @@ def self.keyword_attributes(keyword)
end
def create
- operations = @keywords.map do |keyword|
+ operations = [
{
:operator => 'ADD',
:operand => {
- :xsi_type => (keyword[:negative] ? 'NegativeAdGroupCriterion' : 'BiddableAdGroupCriterion'),
- :ad_group_id => @ad_group_id,
+ :xsi_type => (negative ? 'NegativeAdGroupCriterion' : 'BiddableAdGroupCriterion'),
+ :ad_group_id => ad_group_id,
:criterion => {
:xsi_type => 'Keyword',
- :text => keyword[:text],
- :match_type => keyword[:match_type]
+ :text => criterion_text,
+ :match_type => criterion_match_type
}
}
}
- end
+ ]
response = self.mutate(operations)
@@ -90,20 +116,35 @@ def create
true
end
- def self.find(amount = :all, params = {})
- params[:format] ||= :google # default, don't do anything with the data from google
-
- params.symbolize_keys!
- # this has no effect, it's here just to have the same interface everywhere
- first_only = (amount.to_sym == :first)
+ def serializable_hash
+ {
+ # :match_type => match_type,
+ :negative => negative,
+ :ad_group_id => ad_group_id,
+ :criterion_use => criterion_use,
+ :ad_group_criterion_type => ad_group_criterion_type,
+ :xsi_type => xsi_type,
+ :id => id,
+ :criterion_type => type,
+ :criterion_text => text,
+ :criterion_match_type => match_type,
+ :criterion_xsi_type => xsi_type,
+ :stats_network => network,
+ :stats_type => stats_type
+ }
+ end
+
+ def self.find(ext_options = {})
+ options = default_find_options.merge(ext_options.delete_if{|k,v|v.nil?})
# we need ad_group_id
- raise ArgumentError, "AdGroup ID is required" unless params[:ad_group_id]
+ raise ArgumentError, "AdGroup ID is required" unless options[:ad_group_id]
# supported condition parameters: ad_group_id and id
- predicates = [ :ad_group_id ].map do |param_name|
- if params[param_name]
- {:field => param_name.to_s.camelcase, :operator => 'EQUALS', :values => params[param_name] }
+ predicates = [ :ad_group_id, :criterion_use ].map do |param_name|
+ if ext_options[param_name]
+ value = Array.try_convert(ext_options[param_name]) ? params_param_name : [options[param_name]]
+ {:field => param_name.to_s.camelcase, :operator => 'IN', :values => value }
end
end.compact
@@ -118,22 +159,29 @@ def self.find(amount = :all, params = {})
response = (response and response[:entries]) ? response[:entries] : []
-# for now, always return keywords in :google format
-=begin
- response = case params[:format].to_sym
- when :short
- Keyword.shortened(response)
- when :params
- Keyword.parameterized(response)
- else
- response
+ #response = case options[:format].to_sym
+ # when :short
+ # Keyword.shortened(response)
+ # when :params
+ # Keyword.parameterized(response)
+ # else
+ # response
+ #end
+
+ keywords = []
+
+ response.each do |r|
+ keywords << create_from_api(r)
end
-=end
- Keyword.new(
- :ad_group_id => params[:ad_group_id],
- :keywords => response
- )
+ keywords
+ end
+
+ def self.default_find_options
+ {
+ :format => :google,
+ :amount => :all
+ }
end
# PS: create a better UI for this?
@@ -172,5 +220,27 @@ def self.parameterized(google_keywords = [])
end
end
+ def self.create_from_api( entry )
+ c = entry[:criterion]
+ s = entry[:stats]
+
+ Keyword.new(
+ #:match_type => entry[:match_type],
+ :negative => (entry[:xsi_type].eql?("NegativeAdGroupCriterion")),
+ :ad_group_id => entry[:ad_group_id],
+ :criterion_use => entry[:criterion_use],
+ :ad_group_criterion_type => entry[:ad_group_criterion_type],
+ :xsi_type => entry[:xsi_type],
+
+ :id => c[:id],
+ :criterion_type => c[:type],
+ :criterion_text => c[:text],
+ :criterion_match_type => c[:match_type],
+ :criterion_xsi_type => c[:xsi_type],
+
+ :stats_network => s[:network],
+ :stats_type => s[:stats_type]
+ )
+ end
end
end
Something went wrong with that request. Please try again.