adapi 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/GUIDELINES.markdown +61 -0
- data/README.markdown +79 -45
- data/Rakefile +31 -3
- data/adapi.gemspec +10 -3
- data/examples/add_ad_group.rb +1 -1
- data/examples/add_bare_ad_group.rb +1 -4
- data/examples/add_campaign.rb +1 -0
- data/examples/add_campaign_criteria.rb +27 -0
- data/examples/add_invalid_ad_group.rb +3 -1
- data/examples/add_invalid_text_ad.rb +1 -1
- data/examples/add_keywords.rb +1 -1
- data/examples/add_negative_campaign_criteria.rb +23 -0
- data/examples/add_text_ad.rb +1 -1
- data/examples/customize_configuration.rb +1 -2
- data/examples/delete_keyword.rb +1 -1
- data/examples/find_campaign.rb +5 -5
- data/examples/find_campaign_ad_groups.rb +1 -1
- data/examples/find_campaign_criteria.rb +103 -0
- data/examples/find_locations.rb +21 -0
- data/examples/rollback_campaign.rb +7 -6
- data/examples/update_campaign.rb +1 -1
- data/examples/update_campaign_status.rb +1 -1
- data/lib/adapi.rb +11 -9
- data/lib/adapi/ad/text_ad.rb +2 -1
- data/lib/adapi/ad_group.rb +13 -9
- data/lib/adapi/ad_param.rb +89 -0
- data/lib/adapi/api.rb +8 -0
- data/lib/adapi/campaign.rb +27 -18
- data/lib/adapi/campaign_criterion.rb +278 -0
- data/lib/adapi/campaign_target.rb +5 -123
- data/lib/adapi/config.rb +36 -31
- data/lib/adapi/constant_data.rb +13 -0
- data/lib/adapi/constant_data/language.rb +45 -0
- data/lib/adapi/keyword.rb +15 -5
- data/lib/adapi/location.rb +91 -0
- data/lib/adapi/version.rb +8 -1
- data/lib/httpi_request_monkeypatch.rb +4 -0
- data/test/config/adapi.yml.template +21 -0
- data/test/config/adwords_api.yml.template +10 -0
- data/test/integration/create_campaign_test.rb +54 -0
- data/test/test_helper.rb +2 -3
- data/test/unit/ad_group_test.rb +3 -4
- data/test/unit/ad_test.rb +1 -1
- data/test/unit/campaign_criterion_test.rb +23 -0
- data/test/unit/config_test.rb +52 -0
- metadata +48 -35
- data/examples/add_campaign_targets.rb +0 -26
- data/test/unit/campaign_target_test.rb +0 -51
data/.gitignore
CHANGED
data/GUIDELINES.markdown
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
|
2
|
+
## Commit Guidelines ##
|
3
|
+
|
4
|
+
Thank you for your pull requests! Please make sure that commits comply with
|
5
|
+
following guidelines, so that commit messages will self-explanatory and revision
|
6
|
+
history easy to browse and searchable:
|
7
|
+
|
8
|
+
* commit messages should begin with either *verb* in the simple simple past
|
9
|
+
tense (try to use only the following verbs: *Added*, *Changed* or
|
10
|
+
*Removed*) or *special prefix* in square brackets:
|
11
|
+
|
12
|
+
* [FIX] - commit fixes a bug. Message should contain description of the bug.
|
13
|
+
Example: https://github.com/lstejskal/adapi/commit/71f881a85a16a174b2faf86c0ec72d5a490db438
|
14
|
+
|
15
|
+
* [HOTFIX] - commit fixes a bug, but the bugfix is brittle and should be
|
16
|
+
improved. Usually this marks a temporary hack which solves an urgent problem.
|
17
|
+
Example: https://github.com/lstejskal/adapi/commit/a28e7d1d8d1a26de7e3a380d7fc8153752250388
|
18
|
+
|
19
|
+
* [REFACTOR] - refactoring without any (or very little) changes in functionality.
|
20
|
+
Example: https://github.com/lstejskal/adapi/commit/4eef493857ec0dcb581e88f87c51668c81a97d5d
|
21
|
+
|
22
|
+
* [BUNDLER] something to do with gems
|
23
|
+
Example: https://github.com/lstejskal/adapi/commit/a2838281b725ed6d826495683c822fd81807c674
|
24
|
+
|
25
|
+
* You can also make create your own custom prefix, but please do it only sparingly.
|
26
|
+
|
27
|
+
* commit messages should be as short as possible and to the point. Ideally we
|
28
|
+
should be able to figure out what the commit is about just by reading the
|
29
|
+
commit message, without a glance into the code.
|
30
|
+
Example: "[FIX] nil.method error in Keyword#find method"
|
31
|
+
|
32
|
+
* commits should not be too long, only deal with one thing or a couple of related things
|
33
|
+
|
34
|
+
* avoid afterthought commits and last-minute fixes so popular in SVN. You're in the git now: ammend and rebase.
|
35
|
+
|
36
|
+
Example of unnecessary "afterthought" commits:
|
37
|
+
10:00 12345 Added BubbleGum class
|
38
|
+
10:05 12345 [FIX] removed extra comma in BubbleGum class
|
39
|
+
10:15 12345 [REFACTOR] BubbleGum#chew method
|
40
|
+
|
41
|
+
Last two fixes should be additionaly included to the first commit by `git ammend` command.
|
42
|
+
|
43
|
+
## Branch Structure ##
|
44
|
+
|
45
|
+
* *stable branch* - `master`, obviously. And also branch with the same name
|
46
|
+
as current version of gem. For example: if gem is version 0.0.4, stable branch
|
47
|
+
in either `master` and `0-0-4`. `master` branch might also contain latest
|
48
|
+
bugfixes from development branch.
|
49
|
+
|
50
|
+
* *development branch* - branch with higher number than current gem version;
|
51
|
+
there should be always only one such branch. For example, if gem is version
|
52
|
+
0.0.4, development branch is `0-0-5`. If you living on the edge is your
|
53
|
+
thing, use development branch. It's not stable, but it won't be intentionally
|
54
|
+
broken either. It contains latest updates and bugfixes. Bigger features have
|
55
|
+
their own branches.
|
56
|
+
|
57
|
+
* *feature branch* - named after feature that's being implemented in it. For
|
58
|
+
example: `v201109`, where the latest version of AdWords API is implemented.
|
59
|
+
Lots of action is happening there, expect things to be broken, use at your own
|
60
|
+
risk and make sure you know what you're doing (like, by reading the source
|
61
|
+
code first).
|
data/README.markdown
CHANGED
@@ -23,9 +23,7 @@ have all planned functionality.
|
|
23
23
|
|
24
24
|
## Installation ##
|
25
25
|
|
26
|
-
|
27
|
-
gem install adapi
|
28
|
-
```
|
26
|
+
`gem install adapi`
|
29
27
|
|
30
28
|
### from git repository ###
|
31
29
|
|
@@ -39,12 +37,41 @@ rake install
|
|
39
37
|
## Configuration ##
|
40
38
|
|
41
39
|
This section explains how to connect to specific AdWords account and client.
|
40
|
+
There are several options to choose from:
|
41
|
+
|
42
|
+
#### Configuration by adwords_api.yml ####
|
43
|
+
|
44
|
+
If you already have `google-adwords-api` gem configured and use just one account,
|
45
|
+
the same configuration will also work for adapi: `~/adwords_api.yml`
|
46
|
+
|
47
|
+
#### Single account set directly in code ####
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
Adapi::Config.load_settings(:in_hash => {
|
51
|
+
:sandbox => {
|
52
|
+
:authentication => {
|
53
|
+
:method => "ClientLogin"
|
54
|
+
:email => "sandbox_email@gmail.com",
|
55
|
+
:password => "sandbox_password",
|
56
|
+
:developer_token => "sandbox_token",
|
57
|
+
:client_customer_id => "555-666-7777",
|
58
|
+
:user_agent => "Adwords API Test"
|
59
|
+
},
|
60
|
+
:service => {
|
61
|
+
:environment => "SANDBOX"
|
62
|
+
}
|
63
|
+
}
|
64
|
+
})
|
65
|
+
|
66
|
+
Adapi::Config.set(:sandbox)
|
67
|
+
```
|
68
|
+
|
69
|
+
#### Multiple accounts set directly in code ####
|
42
70
|
|
43
71
|
You can set many AdWords accounts to connect to and switch between while running
|
44
72
|
the application. You can even update single values of the settings on-the-fly.
|
45
73
|
|
46
74
|
```ruby
|
47
|
-
# load the settings
|
48
75
|
Adapi::Config.load_settings(:in_hash => {
|
49
76
|
:coca_cola => {
|
50
77
|
:authentication => {
|
@@ -83,14 +110,7 @@ Adapi::Config.set(:coca_cola, :client_customer_id => '777-666-5555')
|
|
83
110
|
# do some stuff here...
|
84
111
|
```
|
85
112
|
|
86
|
-
|
87
|
-
|
88
|
-
* load configuration from `~/adapi.yml`
|
89
|
-
* load configuration from `~/adwords_api.yml` (default configuration for AdWords gems
|
90
|
-
from Google)
|
91
|
-
* set configuration directly to `Adapi::Config` (overrides previous settings)
|
92
|
-
|
93
|
-
### Configuration by `adapi.yml` ###
|
113
|
+
#### Configuration by `adapi.yml` ####
|
94
114
|
|
95
115
|
Stored in `~/adapi.yml`. Supports multiple accounts, which are identifed by
|
96
116
|
aliases. Example:
|
@@ -119,51 +139,52 @@ aliases. Example:
|
|
119
139
|
:environment: SANDBOX
|
120
140
|
```
|
121
141
|
|
122
|
-
|
142
|
+
To tell adapi which account to use:
|
123
143
|
|
124
144
|
```ruby
|
125
145
|
Adapi::Config.set(:sandbox)
|
126
146
|
```
|
127
147
|
|
128
|
-
`:default` account is, as name implies, used by default.
|
129
|
-
|
148
|
+
`:default` account is, as name implies, used by default. If you don't have
|
149
|
+
`:default` account available, you have to manually set account alias to
|
150
|
+
`Adapi::Config`.
|
130
151
|
|
131
|
-
###
|
152
|
+
### Authentication workflow ###
|
132
153
|
|
133
|
-
|
134
|
-
|
154
|
+
* try to load configuration from `~/adapi.yml`
|
155
|
+
* if `~/adapi.yml`doesn't exist, try to load configuration from
|
156
|
+
`~/adwords_api.yml` (used by adwords-api gem)
|
157
|
+
* if there are no configuration files available, set configuration directly to
|
158
|
+
`Adapi::Config` (overrides previous settings)
|
135
159
|
|
136
|
-
|
160
|
+
## API Version Support ##
|
137
161
|
|
138
|
-
|
139
|
-
`Adapi::Config`:
|
162
|
+
Adapi 0.0.5 and higher supports only the latest version of Google AdWords API: *v201109*
|
140
163
|
|
141
|
-
|
142
|
-
|
143
|
-
Adapi::Config.load_settings(:in_hash => {
|
144
|
-
:sandbox => {
|
145
|
-
:authentication => {
|
146
|
-
:method => "ClientLogin"
|
147
|
-
:email => "sandbox_email@gmail.com",
|
148
|
-
:password => "sandbox_password",
|
149
|
-
:developer_token => "sandbox_token",
|
150
|
-
:client_customer_id => "555-666-7777",
|
151
|
-
:user_agent => "Adwords API Test"
|
152
|
-
},
|
153
|
-
:service => {
|
154
|
-
:environment => "SANDBOX"
|
155
|
-
}
|
156
|
-
}
|
157
|
-
})
|
164
|
+
Older versions of adapi supporting older versions of AdWords API will still be
|
165
|
+
available (adapi 0.0.4 supports only v201101), marked by AdWords API version tag.
|
158
166
|
|
159
|
-
|
160
|
-
```
|
167
|
+
## Unsupported AdWords services ##
|
161
168
|
|
162
|
-
|
169
|
+
Following AdWords services are not supported by adapi at the moment. However,
|
170
|
+
they will be implemented (this also serves as TODO list):
|
171
|
+
|
172
|
+
* Campaign Data Management
|
173
|
+
* ConversionTrackerService
|
174
|
+
* UserListService
|
175
|
+
|
176
|
+
* Optimization
|
177
|
+
* BulkOpportunityService
|
178
|
+
* ReportDefinitionService
|
179
|
+
* TargetingIdeaService
|
180
|
+
* TrafficEstimatorService
|
163
181
|
|
164
|
-
*
|
165
|
-
*
|
166
|
-
|
182
|
+
* Account Management
|
183
|
+
* CustomerSyncService
|
184
|
+
|
185
|
+
* Utility
|
186
|
+
* MutateJobService
|
187
|
+
* BulkMutateJobService
|
167
188
|
|
168
189
|
## Examples ##
|
169
190
|
|
@@ -171,6 +192,19 @@ Example are available in [examples directory](./master/examples/). For now, they
|
|
171
192
|
are mostly just uninspired rewrites of examples from `google-adwords-api` gem,
|
172
193
|
but that's going to change when proper UI to AdWords models will be implemented.
|
173
194
|
|
195
|
+
## Logging ##
|
196
|
+
|
197
|
+
*STILL IN BETA* By default, nothing is logged. If you set `library/log_level` in
|
198
|
+
configuration, SOAP messages will be logged to `~/adapi.log` file according to
|
199
|
+
give log level.
|
200
|
+
|
201
|
+
Example of logger configuration:
|
202
|
+
|
203
|
+
```
|
204
|
+
:library:
|
205
|
+
:log_level: DEBUG
|
206
|
+
```
|
207
|
+
|
174
208
|
## Author ##
|
175
209
|
|
176
|
-
Lukas Stejskal
|
210
|
+
2011-2012 Lukas Stejskal
|
data/Rakefile
CHANGED
@@ -1,14 +1,42 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
2
|
require 'rake'
|
3
3
|
|
4
|
-
|
4
|
+
task :default do
|
5
|
+
# run examples using current gem environment
|
6
|
+
# example: rake example=find_campaigns
|
7
|
+
#
|
8
|
+
if ENV.keys.include?("example")
|
9
|
+
ENV["example"] += ".rb" unless ENV["example"] =~ /\.rb$/
|
10
|
+
exec "ruby -Ilib examples/%s" % ENV["example"]
|
11
|
+
|
12
|
+
# load example into irb using current gem environment
|
13
|
+
# example: rake irb=find_campaigns
|
14
|
+
#
|
15
|
+
elsif ENV.keys.include?("irb")
|
16
|
+
exec "irb -Ilib -Iexamples -r%s" % ENV["irb"].gsub(/\.rb$/, '')
|
17
|
+
|
18
|
+
# run default task: test
|
19
|
+
#
|
20
|
+
else
|
21
|
+
Rake::Task['test'].invoke
|
22
|
+
end
|
23
|
+
end
|
5
24
|
|
6
|
-
|
25
|
+
### Tests ###
|
7
26
|
|
27
|
+
# run all tests except integrations tests
|
28
|
+
#
|
8
29
|
require 'rake/testtask'
|
9
30
|
Rake::TestTask.new(:test) do |test|
|
10
31
|
test.libs << %w{ lib test }
|
11
|
-
test.pattern = 'test
|
32
|
+
test.pattern = 'test/unit/*_test.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'rake/testtask'
|
37
|
+
Rake::TestTask.new(:"test:integration") do |test|
|
38
|
+
test.libs << %w{ lib test }
|
39
|
+
test.pattern = 'test/integration/*_test.rb'
|
12
40
|
test.verbose = true
|
13
41
|
end
|
14
42
|
|
data/adapi.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.version = Adapi::VERSION
|
8
8
|
s.authors = ["Lukas Stejskal"]
|
9
9
|
s.email = ["lucastej@gmail.com"]
|
10
|
-
s.homepage = ""
|
10
|
+
s.homepage = "https://github.com/lstejskal/adapi"
|
11
11
|
s.summary = %q{User-friendly interface to Google Adwords API}
|
12
12
|
s.description = %q{This gem provides user-friendly interface to Google Adwords API.}
|
13
13
|
|
@@ -18,8 +18,15 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
# require specific version of ad-common and adwords-api gems,
|
22
|
+
# they're stil changing a lot and automatic updates through '~>'
|
23
|
+
# can easily break something
|
24
|
+
#
|
25
|
+
# PS: ads-common is "freezed" - required before adwords-api
|
26
|
+
#
|
27
|
+
s.add_dependency "google-ads-common", "0.6.2"
|
28
|
+
s.add_dependency "google-adwords-api", "0.5.0"
|
29
|
+
|
23
30
|
s.add_dependency "activemodel", "~> 3.1"
|
24
31
|
s.add_dependency "activesupport", "~> 3.1"
|
25
32
|
s.add_dependency "rake", "~> 0.9.2"
|
data/examples/add_ad_group.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'adapi'
|
4
4
|
|
5
5
|
# create campaign
|
6
|
-
|
6
|
+
require_relative 'add_bare_campaign'
|
7
7
|
|
8
8
|
# create ad group with basic data only
|
9
9
|
# this script is used as an include in other scripts
|
@@ -12,9 +12,7 @@ $ad_group_data = {
|
|
12
12
|
:campaign_id => $campaign[:id],
|
13
13
|
:name => "AdGroup #%d" % (Time.new.to_f * 1000).to_i,
|
14
14
|
:status => 'ENABLED',
|
15
|
-
# TODO refactor AdGroup.bids DSL
|
16
15
|
:bids => {
|
17
|
-
# this should be set automatically, it's dependent on Campaign.bids
|
18
16
|
:xsi_type => 'BudgetOptimizerAdGroupBids',
|
19
17
|
:proxy_keyword_max_cpc => 10
|
20
18
|
}
|
@@ -22,6 +20,5 @@ $ad_group_data = {
|
|
22
20
|
|
23
21
|
$ad_group = Adapi::AdGroup.create($ad_group_data)
|
24
22
|
|
25
|
-
|
26
23
|
p "Created ad_group ID #{$ad_group.id} for campaign ID #{$ad_group.campaign_id}"
|
27
24
|
p $ad_group.attributes
|
data/examples/add_campaign.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'adapi'
|
4
|
+
|
5
|
+
# create campaign
|
6
|
+
require_relative 'add_bare_campaign'
|
7
|
+
|
8
|
+
$campaign_criterion = Adapi::CampaignCriterion.new(
|
9
|
+
:campaign_id => $campaign[:id],
|
10
|
+
:criteria => {
|
11
|
+
:language => %w{ en cs },
|
12
|
+
|
13
|
+
:location => {
|
14
|
+
:id => 21137
|
15
|
+
# :name => { :city => 'Prague', :region => 'CZ-PR', :country => 'CZ' }
|
16
|
+
# :proximity => { :geo_point => '50.083333,14.366667', :radius => '50 km' }
|
17
|
+
},
|
18
|
+
|
19
|
+
# add custom platform criteria
|
20
|
+
:platform => [ { :id => 30001} ]
|
21
|
+
}
|
22
|
+
)
|
23
|
+
|
24
|
+
$campaign_criterion.create
|
25
|
+
|
26
|
+
p $campaign_criterion.attributes
|
27
|
+
|
@@ -9,7 +9,7 @@ require 'adapi'
|
|
9
9
|
#pp "Running in #{Adapi::Config.read[:service][:environment]}"
|
10
10
|
|
11
11
|
# create ad group
|
12
|
-
|
12
|
+
require_relative 'add_bare_ad_group'
|
13
13
|
|
14
14
|
$ad = Adapi::Ad::TextAd.create(
|
15
15
|
:ad_group_id => $ad_group[:id],
|
data/examples/add_keywords.rb
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'adapi'
|
4
|
+
|
5
|
+
# create campaign
|
6
|
+
require_relative 'add_bare_campaign'
|
7
|
+
|
8
|
+
$campaign_criterion = Adapi::CampaignCriterion.new(
|
9
|
+
:campaign_id => $campaign[:id],
|
10
|
+
:negative => true,
|
11
|
+
:criteria => {
|
12
|
+
:language => %w{ de },
|
13
|
+
|
14
|
+
:location => {
|
15
|
+
:name => { :city => 'Oslo' }
|
16
|
+
}
|
17
|
+
}
|
18
|
+
)
|
19
|
+
|
20
|
+
$campaign_criterion.create
|
21
|
+
|
22
|
+
p $campaign_criterion.attributes
|
23
|
+
|