adapi 0.0.1

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.
@@ -0,0 +1,17 @@
1
+ require 'adapi'
2
+
3
+ # this example shows how to load custom settings
4
+
5
+ Adapi::Config.load_settings(
6
+ :path => File.expand_path(File.dirname(__FILE__)),
7
+ :filename => 'custom_settings.yml'
8
+ )
9
+
10
+ # :default account is set automatically
11
+ p "Default settings:"
12
+ p Adapi::Config.read[:authentication][:email]
13
+
14
+ Adapi::Config.set(:sandbox)
15
+ p "Set :sandbox account:"
16
+ p Adapi::Config.read[:authentication][:email]
17
+
@@ -0,0 +1,20 @@
1
+
2
+ require 'adapi'
3
+
4
+ # use specific config data
5
+ Adapi::Config.set({
6
+ :authentication => {
7
+ :method => 'ClientLogin',
8
+ :email => 'sandbox_email@gmail.com',
9
+ :password => 'sandbox_password',
10
+ :developer_token => 'sandbox_developer_token',
11
+ :client_email => 'sandbox_client_email@gmail.com',
12
+ :user_agent => 'Adwords API Test'
13
+ },
14
+ :service => {
15
+ :environment => 'SANDBOX'
16
+ }
17
+ })
18
+
19
+ # create campaign
20
+ require 'add_bare_campaign'
@@ -0,0 +1,23 @@
1
+
2
+ require 'adapi'
3
+
4
+ # create campaign
5
+ require 'add_bare_campaign'
6
+
7
+ p 'original status: %s' % $campaign[:status]
8
+
9
+ campaign_updates = {
10
+ :id => $campaign[:id],
11
+ :status => 'ACTIVE'
12
+ }
13
+
14
+ $campaign = Adapi::Campaign.update(:data => campaign_updates)
15
+
16
+ p 'updated status: %s' % $campaign[:status]
17
+
18
+ $campaign = Adapi::Campaign.update(
19
+ :id => $campaign[:id],
20
+ :data => {:status => 'DELETED'}
21
+ )
22
+
23
+ p 'updated status (again): %s' % $campaign[:status]
@@ -0,0 +1,14 @@
1
+
2
+ require 'adapi'
3
+
4
+ # create campaign
5
+ require 'add_bare_campaign'
6
+
7
+ p 'original name: %s' % $campaign[:name]
8
+
9
+ $campaign = Adapi::Campaign.rename(
10
+ :id => $campaign[:id],
11
+ :name => "Renamed Campaign #%d" % (Time.new.to_f * 1000).to_i
12
+ )
13
+
14
+ p 'updated name: %s' % $campaign[:name]
@@ -0,0 +1,15 @@
1
+
2
+ require 'adapi'
3
+
4
+ # create campaign
5
+ require 'add_bare_campaign'
6
+
7
+ p 'original status: %s' % $campaign[:status]
8
+
9
+ $campaign = Adapi::Campaign.activate(:id => $campaign[:id])
10
+
11
+ p 'updated status: %s' % $campaign[:status]
12
+
13
+ $campaign = Adapi::Campaign.delete(:id => $campaign[:id])
14
+
15
+ p 'updated status (again): %s' % $campaign[:status]
data/lib/adapi.rb ADDED
@@ -0,0 +1,18 @@
1
+
2
+ require 'rubygems'
3
+ require 'adwords_api'
4
+ require 'collection'
5
+ require 'yaml'
6
+
7
+ require 'adapi/config'
8
+ require 'adapi/api'
9
+ require 'adapi/campaign'
10
+ require 'adapi/campaign_target'
11
+ require 'adapi/ad_group'
12
+ require 'adapi/ad_group_criterion'
13
+ require 'adapi/ad'
14
+ require 'adapi/version'
15
+
16
+ module Adapi
17
+ API_VERSION = :v201101
18
+ end
data/lib/adapi/ad.rb ADDED
@@ -0,0 +1,64 @@
1
+ module Adapi
2
+
3
+ # TODO add synonym for actual service name: AdGroupAd
4
+ #
5
+ class Ad < Api
6
+
7
+ def initialize(params = {})
8
+ params[:service_name] = :AdGroupAdService
9
+ super(params)
10
+ end
11
+
12
+ def self.create(params = {})
13
+ ad_service = Ad.new
14
+
15
+ ad_group_id = params[:data].delete(:ad_group_id)
16
+
17
+ operation = { :operator => 'ADD',
18
+ :operand => { :ad_group_id => ad_group_id, :ad => params[:data] }
19
+ }
20
+
21
+ response = ad_service.service.mutate([operation])
22
+
23
+ ad_group = response[:value].first
24
+
25
+ ad = nil
26
+ if response and response[:value]
27
+ ad = response[:value].first
28
+ puts " Ad ID is #{ad[:ad][:id]}, type is '#{ad[:ad][:xsi_type]}' and status is '#{ad[:status]}'."
29
+ end
30
+
31
+ ad
32
+ end
33
+
34
+ def self.find(params = {})
35
+ ad_service = Ad.new
36
+
37
+ raise "No AdGroup ID" unless params[:ad_group_id]
38
+ ad_group_id = params[:ad_group_id].to_i
39
+
40
+ selector = {
41
+ :fields => ['Id', 'Headline'],
42
+ :ordering => [{:field => 'Id', :sort_order => 'ASCENDING'}],
43
+ :predicates => [
44
+ {:field => 'AdGroupId', :operator => 'EQUALS', :values => ad_group_id }
45
+ # { :field => 'Status', :operator => 'IN', :values => ['ENABLED', 'PAUSED', 'DISABLED'] }
46
+ ]
47
+ }
48
+
49
+ response = ad_service.service.get(selector)
50
+
51
+ if response and response[:entries]
52
+ ads = response[:entries]
53
+ puts "Ad group ##{ad_group_id} has #{ads.length} ad(s)."
54
+ ads.each do |ad|
55
+ puts " Ad id is #{ad[:ad][:id]}, type is #{ad[:ad][:xsi_type]} and " +
56
+ "status is \"#{ad[:status]}\"."
57
+ end
58
+ else
59
+ puts "No ads found for ad group ##{ad_group_id}."
60
+ end
61
+ end
62
+
63
+ end
64
+ end
@@ -0,0 +1,70 @@
1
+ module Adapi
2
+ class AdGroup < Api
3
+
4
+ def initialize(params = {})
5
+ params[:service_name] = :AdGroupService
6
+ super(params)
7
+ end
8
+
9
+ def self.create(params = {})
10
+ ad_group_service = AdGroup.new
11
+
12
+ criteria = params[:data].delete(:criteria)
13
+ ads = params[:data].delete(:ads) || []
14
+
15
+ # prepare for adding campaign
16
+ operation = { :operator => 'ADD', :operand => params[:data] }
17
+
18
+ response = ad_group_service.service.mutate([operation])
19
+
20
+ ad_group = response[:value].first
21
+
22
+ if criteria
23
+ Adapi::AdGroupCriterion.create(
24
+ :ad_group_id => ad_group[:id],
25
+ :criteria => criteria
26
+ )
27
+ end
28
+
29
+ ads.each do |ad_data|
30
+ Adapi::Ad.create(
31
+ :data => ad_data.merge(:ad_group_id => ad_group[:id])
32
+ )
33
+ end
34
+
35
+ # puts "Ad group ID %d was successfully added." % ad_group[:id]
36
+ ad_group
37
+ end
38
+
39
+ # should be sorted out later, but leave it be for now
40
+ #
41
+ def self.find(params = {})
42
+ ad_group_service = AdGroup.new
43
+
44
+ raise "No Campaign ID" unless params[:campaign_id]
45
+ campaign_id = params[:campaign_id]
46
+
47
+ selector = {
48
+ :fields => ['Id', 'Name'],
49
+ # :ordering => [{:field => 'Name', :sort_order => 'ASCENDING'}],
50
+ :predicates => [{
51
+ :field => 'CampaignId', :operator => 'EQUALS', :values => campaign_id
52
+ }]
53
+ }
54
+
55
+ response = ad_group_service.service.get(selector)
56
+
57
+ if response and response[:entries]
58
+ ad_groups = response[:entries]
59
+ puts "Campaign ##{campaign_id} has #{ad_groups.length} ad group(s)."
60
+ ad_groups.each do |ad_group|
61
+ puts " Ad group name is \"#{ad_group[:name]}\" and id is #{ad_group[:id]}."
62
+ end
63
+ else
64
+ puts "No ad groups found for campaign ##{campaign_id}."
65
+ end
66
+
67
+ end
68
+
69
+ end
70
+ end
@@ -0,0 +1,68 @@
1
+ module Adapi
2
+ class AdGroupCriterion < Api
3
+
4
+ def initialize(params = {})
5
+ params[:service_name] = :AdGroupCriterionService
6
+ super(params)
7
+ end
8
+
9
+ def self.create(params = {})
10
+ ad_group_criterion_service = AdGroupCriterion.new
11
+
12
+ raise "No criteria available" unless params[:criteria].is_a?(Array)
13
+
14
+ # if ad_group_id is supplied as separate parameter, include it into
15
+ # criteria
16
+ if params[:ad_group_id]
17
+ params[:criteria].map! { |c| c.merge(:ad_group_id => params[:ad_group_id].to_i) }
18
+ end
19
+
20
+ operation = params[:criteria].map do |criterion|
21
+ { :operator => 'ADD', :operand => criterion }
22
+ end
23
+
24
+ response = ad_group_criterion_service.service.mutate(operation)
25
+
26
+ ad_group_criteria = nil
27
+ if response and response[:value]
28
+ ad_group_criteria = response[:value]
29
+ puts "Added #{ad_group_criteria.length} criteria " # "to ad group #{ad_group_id}."
30
+ ad_group_criteria.each do |ad_group_criterion|
31
+ puts " Criterion id is #{ad_group_criterion[:criterion][:id]} and " +
32
+ "type is #{ad_group_criterion[:criterion][:"@xsi:type"]}."
33
+ end
34
+ else
35
+ puts "No criteria were added."
36
+ end
37
+
38
+ ad_group_criteria
39
+ end
40
+
41
+ def find(params = {})
42
+ raise "No Campaign ID" unless params[:campaign_id]
43
+ campaign_id = params[:campaign_id]
44
+
45
+ selector = {
46
+ :fields => ['Id', 'Name'],
47
+ # :ordering => [{:field => 'Name', :sort_order => 'ASCENDING'}],
48
+ :predicates => [{
49
+ :field => 'CampaignId', :operator => 'EQUALS', :values => campaign_id
50
+ }]
51
+ }
52
+
53
+ response = @service.get(selector)
54
+
55
+ if response and response[:entries]
56
+ ad_groups = response[:entries]
57
+ puts "Campaign ##{campaign_id} has #{ad_groups.length} ad group(s)."
58
+ ad_groups.each do |ad_group|
59
+ puts " Ad group name is \"#{ad_group[:name]}\" and id is #{ad_group[:id]}."
60
+ end
61
+ else
62
+ puts "No ad groups found for campaign ##{campaign_id}."
63
+ end
64
+
65
+ end
66
+
67
+ end
68
+ end
data/lib/adapi/api.rb ADDED
@@ -0,0 +1,20 @@
1
+ module Adapi
2
+ class Api
3
+
4
+ attr_accessor :adwords, :service, :version, :params
5
+
6
+ def initialize(params = {})
7
+ raise "Missing Service Name" unless params[:service_name]
8
+
9
+ puts "\n\nEXISTING INSTANCE USED\n\n" if params[:adwords_api_instance]
10
+
11
+ # if params[:api_login] in nil, default login data are used
12
+ # from ~/adwords_api.yml
13
+ @adwords = params[:adwords_api_instance] || AdwordsApi::Api.new(Adapi::Config.read)
14
+ @version = API_VERSION
15
+ @service = @adwords.service(params[:service_name].to_sym, @version)
16
+ @params = params
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,142 @@
1
+ module Adapi
2
+ class Campaign < Api
3
+
4
+ def initialize(params = {})
5
+ params[:service_name] = :CampaignService
6
+ super(params)
7
+ end
8
+
9
+ # campaign data can be passed either as single hash:
10
+ # Campaign.create(:name => 'Campaign 123', :status => 'ENABLED')
11
+ # or as hash in a :data key:
12
+ # Campaign.create(:data => { :name => 'Campaign 123', :status => 'ENABLED' })
13
+ #
14
+ def self.create(params = {})
15
+ campaign_service = Campaign.new
16
+
17
+ # give users options to shorten input params
18
+ params = { :data => params } unless params.has_key?(:data)
19
+
20
+ # prepare for adding campaign
21
+ ad_groups = params[:data].delete(:ad_groups).to_a
22
+ targets = params[:data].delete(:targets)
23
+
24
+ operation = { :operator => 'ADD', :operand => params[:data] }
25
+
26
+ response = campaign_service.service.mutate([operation])
27
+
28
+ campaign = nil
29
+ if response and response[:value]
30
+ campaign = response[:value].first
31
+ puts "Campaign with name '%s' and ID %d was added." % [campaign[:name], campaign[:id]]
32
+ else
33
+ return nil
34
+ end
35
+
36
+ # create targets if they are available
37
+ if targets
38
+ Adapi::CampaignTarget.create(
39
+ :campaign_id => campaign[:id],
40
+ :targets => targets,
41
+ :api_adwords_instance => campaign_service.adwords
42
+ )
43
+ end
44
+
45
+ # if campaign has ad_groups, create them as well
46
+ ad_groups.each do |ad_group_data|
47
+ Adapi::AdGroup.create(
48
+ :data => ad_group_data.merge(:campaign_id => campaign[:id]),
49
+ :api_adwords_instance => campaign_service.adwords
50
+ )
51
+ end
52
+
53
+ campaign
54
+ end
55
+
56
+ # general method for changing campaign data
57
+ # TODO enable updating of all campaign parts at once, same as for Campaign#create method
58
+ #
59
+ def self.update(params = {})
60
+ campaign_service = Campaign.new
61
+
62
+ # give users options to shorten input params
63
+ params = { :data => params } unless params.has_key?(:data)
64
+
65
+ campaign_id = params[:id] || params[:data][:id] || nil
66
+ return nil unless campaign_id
67
+
68
+ operation = { :operator => 'SET',
69
+ :operand => params[:data].merge(:id => campaign_id.to_i)
70
+ }
71
+
72
+ response = campaign_service.service.mutate([operation])
73
+
74
+ if response and response[:value]
75
+ campaign = response[:value].first
76
+ puts 'Campaign id %d successfully updated.' % campaign[:id]
77
+ else
78
+ puts 'No campaigns were updated.'
79
+ end
80
+
81
+ return campaign
82
+ end
83
+
84
+ def self.set_status(params = {})
85
+ params[:id] ||= (params[:data] || params[:data][:id]) || nil
86
+ return nil unless params[:id]
87
+ return nil unless %w{ ACTIVE PAUSED DELETED }.include?(params[:status])
88
+
89
+ self.update(:id => params[:id], :status => params[:status])
90
+ end
91
+
92
+ def self.activate(params = {})
93
+ self.set_status params.merge(:status => 'ACTIVE')
94
+ end
95
+
96
+ def self.pause(params = {})
97
+ self.set_status params.merge(:status => 'PAUSED')
98
+ end
99
+
100
+ def self.delete(params = {})
101
+ self.set_status params.merge(:status => 'DELETED')
102
+ end
103
+
104
+ def self.rename(params = {})
105
+ params[:id] ||= (params[:data] || params[:data][:id]) || nil
106
+ return nil unless (params[:id] && params[:name])
107
+
108
+ self.update(:id => params[:id], :name => params[:name])
109
+ end
110
+
111
+ def self.find(params = {})
112
+ campaign_service = Campaign.new
113
+
114
+ selector = {
115
+ :fields => ['Id', 'Name', 'Status']
116
+ # :predicates => [{ :field => 'Id', :operator => 'EQUALS', :values => '334315' }]
117
+ # :ordering => [{:field => 'Name', :sort_order => 'ASCENDING'}]
118
+ }
119
+
120
+ # set filtering conditions: find by id, status etc.
121
+ if params[:conditions]
122
+ selector[:predicates] = params[:conditions].map do |c|
123
+ { :field => c[0].to_s.capitalize, :operator => 'EQUALS', :values => c[1] }
124
+ end
125
+ end
126
+
127
+ response = campaign_service.service.get(selector)
128
+
129
+ return (response and response[:entries]) ? response[:entries].to_a : []
130
+
131
+ if response
132
+ response[:entries].to_a.each do |campaign|
133
+ puts "Campaign name is \"#{campaign[:name]}\", id is #{campaign[:id]} " +
134
+ "and status is \"#{campaign[:status]}\"."
135
+ end
136
+ else
137
+ puts "No campaigns were found."
138
+ end
139
+ end
140
+
141
+ end
142
+ end