adapi 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/.gitignore +3 -0
  2. data/GUIDELINES.markdown +61 -0
  3. data/README.markdown +79 -45
  4. data/Rakefile +31 -3
  5. data/adapi.gemspec +10 -3
  6. data/examples/add_ad_group.rb +1 -1
  7. data/examples/add_bare_ad_group.rb +1 -4
  8. data/examples/add_campaign.rb +1 -0
  9. data/examples/add_campaign_criteria.rb +27 -0
  10. data/examples/add_invalid_ad_group.rb +3 -1
  11. data/examples/add_invalid_text_ad.rb +1 -1
  12. data/examples/add_keywords.rb +1 -1
  13. data/examples/add_negative_campaign_criteria.rb +23 -0
  14. data/examples/add_text_ad.rb +1 -1
  15. data/examples/customize_configuration.rb +1 -2
  16. data/examples/delete_keyword.rb +1 -1
  17. data/examples/find_campaign.rb +5 -5
  18. data/examples/find_campaign_ad_groups.rb +1 -1
  19. data/examples/find_campaign_criteria.rb +103 -0
  20. data/examples/find_locations.rb +21 -0
  21. data/examples/rollback_campaign.rb +7 -6
  22. data/examples/update_campaign.rb +1 -1
  23. data/examples/update_campaign_status.rb +1 -1
  24. data/lib/adapi.rb +11 -9
  25. data/lib/adapi/ad/text_ad.rb +2 -1
  26. data/lib/adapi/ad_group.rb +13 -9
  27. data/lib/adapi/ad_param.rb +89 -0
  28. data/lib/adapi/api.rb +8 -0
  29. data/lib/adapi/campaign.rb +27 -18
  30. data/lib/adapi/campaign_criterion.rb +278 -0
  31. data/lib/adapi/campaign_target.rb +5 -123
  32. data/lib/adapi/config.rb +36 -31
  33. data/lib/adapi/constant_data.rb +13 -0
  34. data/lib/adapi/constant_data/language.rb +45 -0
  35. data/lib/adapi/keyword.rb +15 -5
  36. data/lib/adapi/location.rb +91 -0
  37. data/lib/adapi/version.rb +8 -1
  38. data/lib/httpi_request_monkeypatch.rb +4 -0
  39. data/test/config/adapi.yml.template +21 -0
  40. data/test/config/adwords_api.yml.template +10 -0
  41. data/test/integration/create_campaign_test.rb +54 -0
  42. data/test/test_helper.rb +2 -3
  43. data/test/unit/ad_group_test.rb +3 -4
  44. data/test/unit/ad_test.rb +1 -1
  45. data/test/unit/campaign_criterion_test.rb +23 -0
  46. data/test/unit/config_test.rb +52 -0
  47. metadata +48 -35
  48. data/examples/add_campaign_targets.rb +0 -26
  49. data/test/unit/campaign_target_test.rb +0 -51
data/.gitignore CHANGED
@@ -5,3 +5,6 @@ pkg/*
5
5
  doc/*
6
6
  coverage/*
7
7
  .yardoc/*
8
+ adapi.yml
9
+ .rvmrc
10
+ .idea/
@@ -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
- ### Authentication workflow ###
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
- You tell adapi which account to use by setting an alias:
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. You must either set an
129
- alias to `Adapi::Config` or have account with `:default` alias available.
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
- ### Configuration by adwords_api.yml ###
152
+ ### Authentication workflow ###
132
153
 
133
- If you already have `google-adwords-api` gem configured and use just one account,
134
- the same configuration will also work for adapi: `~/adwords_api.yml`
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
- ### Configuration directly in code ###
160
+ ## API Version Support ##
137
161
 
138
- Before logging into the Adwords API, you can set global settings through
139
- `Adapi::Config`:
162
+ Adapi 0.0.5 and higher supports only the latest version of Google AdWords API: *v201109*
140
163
 
141
- ```ruby
142
- # load the settings
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
- Adapi::Config.set(:sandbox)
160
- ```
167
+ ## Unsupported AdWords services ##
161
168
 
162
- ## API Version Support ##
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
- * adapi supports only the latest version of Google AdWords API: *v201109*
165
- * older versions will not be supported (well, maybe *v201101*)
166
- * *v201109* and newer versions will still be supported when new versions are released
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
- ### Tests ###
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
- task :default => :test
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/**/*_test.rb'
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
- s.add_dependency "google-ads-common", "~> 0.5.0"
22
- s.add_dependency "google-adwords-api", "~> 0.4.0"
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"
@@ -3,7 +3,7 @@
3
3
  require 'adapi'
4
4
 
5
5
  # create campaign
6
- require File.join(File.dirname(__FILE__), 'add_bare_campaign')
6
+ require_relative 'add_bare_campaign'
7
7
 
8
8
  # create ad group
9
9
 
@@ -3,7 +3,7 @@
3
3
  require 'adapi'
4
4
 
5
5
  # create campaign
6
- require File.join(File.dirname(__FILE__), 'add_bare_campaign')
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
@@ -19,6 +19,7 @@ campaign_data = {
19
19
  :target_content_contextual => false
20
20
  },
21
21
 
22
+ # PS: :targets key is obsolete, this should be named :criteria, but it still works
22
23
  :targets => {
23
24
  :language => [ 'en', 'cs' ],
24
25
  # TODO test together with city target
@@ -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
+
@@ -1,9 +1,11 @@
1
1
  # encoding: utf-8
2
2
 
3
+ # This example should throw an error on ad.url
4
+
3
5
  require 'adapi'
4
6
 
5
7
  # create campaign
6
- require File.join(File.dirname(__FILE__), 'add_bare_campaign')
8
+ require_relative 'add_bare_campaign'
7
9
 
8
10
  # create ad group
9
11
 
@@ -9,7 +9,7 @@ require 'adapi'
9
9
  #pp "Running in #{Adapi::Config.read[:service][:environment]}"
10
10
 
11
11
  # create ad group
12
- require File.join(File.dirname(__FILE__), 'add_bare_ad_group')
12
+ require_relative 'add_bare_ad_group'
13
13
 
14
14
  $ad = Adapi::Ad::TextAd.create(
15
15
  :ad_group_id => $ad_group[:id],
@@ -3,7 +3,7 @@
3
3
  require 'adapi'
4
4
 
5
5
  # create ad group
6
- require File.join(File.dirname(__FILE__), 'add_bare_ad_group')
6
+ require_relative 'add_bare_ad_group'
7
7
 
8
8
  $keywords = Adapi::Keyword.new(
9
9
  :ad_group_id => $ad_group[:id],
@@ -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
+