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.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.rdoc +127 -0
- data/Rakefile +12 -0
- data/adapi.gemspec +28 -0
- data/examples/add_ad.rb +17 -0
- data/examples/add_ad_group.rb +46 -0
- data/examples/add_ad_group_criteria.rb +20 -0
- data/examples/add_bare_ad_group.rb +26 -0
- data/examples/add_bare_campaign.rb +27 -0
- data/examples/add_campaign.rb +68 -0
- data/examples/add_campaign_targets.rb +16 -0
- data/examples/custom_settings.yml +22 -0
- data/examples/customize_configuration.rb +17 -0
- data/examples/log_to_specific_account.rb +20 -0
- data/examples/update_campaign.rb +23 -0
- data/examples/update_campaign_name.rb +14 -0
- data/examples/update_campaign_status.rb +15 -0
- data/lib/adapi.rb +18 -0
- data/lib/adapi/ad.rb +64 -0
- data/lib/adapi/ad_group.rb +70 -0
- data/lib/adapi/ad_group_criterion.rb +68 -0
- data/lib/adapi/api.rb +20 -0
- data/lib/adapi/campaign.rb +142 -0
- data/lib/adapi/campaign_target.rb +90 -0
- data/lib/adapi/config.rb +54 -0
- data/lib/adapi/version.rb +3 -0
- data/lib/collection.rb +429 -0
- data/test/factories/.gitignore +0 -0
- data/test/test_helper.rb +20 -0
- data/test/unit/.gitignore +0 -0
- data/test/unit/campaign_target_test.rb +21 -0
- metadata +187 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
== MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2011, Lukas Stejskal.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
== Adapi
|
2
|
+
|
3
|
+
Adapi (shortened "AdWords API") is a library for easy and painless work with
|
4
|
+
Google Adwords API. Its users shouldn't bother with SOAP and tangle of XML- and
|
5
|
+
API-specific objects (remember adwords4r gem?), inputs and outputs are plain
|
6
|
+
Ruby arrays and hashes.
|
7
|
+
|
8
|
+
Adapi is built on new Google Adwords API gems: google-ads-common and
|
9
|
+
google-adwords-api. Arrays and hashes instead of objects come from there, but
|
10
|
+
adapi takes it several steps further. AdWords services are represented by models
|
11
|
+
with relations, so among other things it's possible to create whole campaign in
|
12
|
+
single method call: Adapi::Campaign.create(campaign_data). Various convenience
|
13
|
+
methods are added to the models, for example: campaign.pause! (pauses
|
14
|
+
campaign). Adapi enables multiple AdWords accounts to be used at the same time.
|
15
|
+
|
16
|
+
Adapi is STILL IN DEVELOPMENT, not nearly done yet! Version 0.1.0 should have
|
17
|
+
all planned functionality.
|
18
|
+
|
19
|
+
== Installation
|
20
|
+
|
21
|
+
gem install adapi
|
22
|
+
|
23
|
+
=== from git repository
|
24
|
+
|
25
|
+
bundle install
|
26
|
+
rake install
|
27
|
+
|
28
|
+
== Configuration of AdWords Account(s)
|
29
|
+
|
30
|
+
This section explains how to connect to specific account and client.
|
31
|
+
|
32
|
+
In general, you can set many AdWords accounts to connect to (similarly as you
|
33
|
+
can set up several databases in Rails, for example).
|
34
|
+
|
35
|
+
=== Authentication workflow
|
36
|
+
|
37
|
+
* load configuration from ~/adapi.yml
|
38
|
+
* load configuration from ~/adwords_api.yml (default configuration for AdWords gems
|
39
|
+
from Google)
|
40
|
+
* set configuration directly to Adapi::Config (overrides previous settings)
|
41
|
+
|
42
|
+
=== Configuration by adapi.yml
|
43
|
+
|
44
|
+
Stored in ~/adapi.yml. Supports multiple accounts, which are identifed by
|
45
|
+
aliases. Example:
|
46
|
+
|
47
|
+
:default:
|
48
|
+
:authentication:
|
49
|
+
:method: ClientLogin
|
50
|
+
:email: default_email@gmail.com
|
51
|
+
:password: default_password
|
52
|
+
:developer_token: default_token
|
53
|
+
:client_email: default_client_email@gmail.com
|
54
|
+
:user_agent: My Adwords API Client
|
55
|
+
:service:
|
56
|
+
:environment: PRODUCTION
|
57
|
+
|
58
|
+
:sandbox:
|
59
|
+
:authentication:
|
60
|
+
:method: ClientLogin
|
61
|
+
:email: sandbox_email@gmail.com
|
62
|
+
:password: sandbox_password
|
63
|
+
:developer_token: sandbox_token
|
64
|
+
:client_email: sandbox_client_email@gmail.com
|
65
|
+
:user_agent: Adwords API Test
|
66
|
+
:service:
|
67
|
+
:environment: SANDBOX
|
68
|
+
|
69
|
+
You tell adapi which account to use by setting an alias:
|
70
|
+
|
71
|
+
Adapi::Config.set(:sandbox)
|
72
|
+
|
73
|
+
:default account is, as name implies, used by default. You must either set an
|
74
|
+
alias to Adapi::Config or have account with :default alias available.
|
75
|
+
|
76
|
+
=== Configuration by adwords_api.yml
|
77
|
+
|
78
|
+
If you already have google-adwords-api gem configured and use just one account,
|
79
|
+
the same configuration will also work for adapi: ~/adwords_api.yml
|
80
|
+
|
81
|
+
=== Configuration directly in code
|
82
|
+
|
83
|
+
Before logging into the Adwords API, you can set global settings through
|
84
|
+
Adapi::Config:
|
85
|
+
|
86
|
+
Adapi::Config.set({
|
87
|
+
:authentication:
|
88
|
+
:method: ClientLogin
|
89
|
+
:email: sandbox_email@gmail.com
|
90
|
+
:password: sandbox_password
|
91
|
+
:developer_token: sandbox_token
|
92
|
+
:client_email: sandbox_client_email@gmail.com
|
93
|
+
:user_agent: Adwords API Test
|
94
|
+
:service:
|
95
|
+
:environment: SANDBOX
|
96
|
+
})
|
97
|
+
|
98
|
+
This will override any previous configuration and set the account as :default.
|
99
|
+
You can specify more accounts this way, with aliases, in the same way as in
|
100
|
+
~/adapi.yml.
|
101
|
+
|
102
|
+
== API
|
103
|
+
|
104
|
+
There are two ways of working with API. Both examples show adding an ad to
|
105
|
+
specific campaign's ad group:
|
106
|
+
|
107
|
+
=== Model-centric
|
108
|
+
|
109
|
+
Adapi::Campaign.create(campaign_data)
|
110
|
+
|
111
|
+
=== TODO Collection-centric
|
112
|
+
|
113
|
+
account = Adapi::Account.new(:account_alias)
|
114
|
+
|
115
|
+
campaign = account.campaigns.create(campaign_data)
|
116
|
+
|
117
|
+
account.campaigns[ campaign[:id] ].ad_groups << ad_group_data
|
118
|
+
|
119
|
+
== Examples
|
120
|
+
|
121
|
+
Example are available in /examples directory. For now, they are mostly just dumb
|
122
|
+
rewrites of examples from google-adwords-api gem, but that's going to change
|
123
|
+
when proper UI to AdWords models will be implemented.
|
124
|
+
|
125
|
+
== Author
|
126
|
+
|
127
|
+
Lukas Stejskal
|
data/Rakefile
ADDED
data/adapi.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "adapi/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "adapi"
|
7
|
+
s.version = Adapi::VERSION
|
8
|
+
s.authors = ["Lukas Stejskal"]
|
9
|
+
s.email = ["lucastej@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{User-friendly interface to Google Adwords API}
|
12
|
+
s.description = %q{This gem provides user-friendly interface to Google Adwords API.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "adapi"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_dependency "google-ads-common", "~> 0.5.1"
|
22
|
+
s.add_dependency "google-adwords-api", "~> 0.4.1"
|
23
|
+
|
24
|
+
s.add_development_dependency "turn"
|
25
|
+
s.add_development_dependency "shoulda"
|
26
|
+
s.add_development_dependency "fakeweb"
|
27
|
+
s.add_development_dependency "factory_girl"
|
28
|
+
end
|
data/examples/add_ad.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
require 'adapi'
|
3
|
+
|
4
|
+
# create ad group
|
5
|
+
require 'add_bare_ad_group'
|
6
|
+
|
7
|
+
ad_data = {
|
8
|
+
:ad_group_id => $ad_group[:id],
|
9
|
+
:xsi_type => 'TextAd',
|
10
|
+
:headline => "Code like Neo",
|
11
|
+
:description1 => 'Need mad coding skills?',
|
12
|
+
:description2 => 'Check out my new blog!',
|
13
|
+
:url => 'http://www.demcodez.com',
|
14
|
+
:display_url => 'http://www.demcodez.com'
|
15
|
+
}
|
16
|
+
|
17
|
+
p Adapi::Ad.create(:data => ad_data)
|
@@ -0,0 +1,46 @@
|
|
1
|
+
|
2
|
+
require 'adapi'
|
3
|
+
|
4
|
+
# create campaign
|
5
|
+
require 'add_bare_campaign'
|
6
|
+
|
7
|
+
# create ad group
|
8
|
+
|
9
|
+
ad_group_data = {
|
10
|
+
:name => "AdGroup #%d" % (Time.new.to_f * 1000).to_i,
|
11
|
+
:status => 'ENABLED',
|
12
|
+
:campaign_id => $campaign[:id],
|
13
|
+
:bids => {
|
14
|
+
:xsi_type => 'ManualCPCAdGroupBids',
|
15
|
+
:keyword_max_cpc => {
|
16
|
+
:amount => {
|
17
|
+
:micro_amount => 10000000
|
18
|
+
}
|
19
|
+
}
|
20
|
+
},
|
21
|
+
|
22
|
+
:criteria => [
|
23
|
+
{ # keyword_criterion
|
24
|
+
:xsi_type => 'BiddableAdGroupCriterion',
|
25
|
+
:criterion => { :xsi_type => 'Keyword', :text => 'codez', :match_type => 'BROAD' }
|
26
|
+
},
|
27
|
+
{ # placement_criterion
|
28
|
+
:xsi_type => 'BiddableAdGroupCriterion',
|
29
|
+
:criterion => { :xsi_type => 'Placement', :url => 'http://www.blogger.com' }
|
30
|
+
}
|
31
|
+
],
|
32
|
+
|
33
|
+
:ads => [
|
34
|
+
{
|
35
|
+
:xsi_type => 'TextAd',
|
36
|
+
:headline => "Code like Neo",
|
37
|
+
:description1 => 'Need mad coding skills?',
|
38
|
+
:description2 => 'Check out my new blog!',
|
39
|
+
:url => 'http://www.demcodez.com',
|
40
|
+
:display_url => 'http://www.demcodez.com'
|
41
|
+
}
|
42
|
+
]
|
43
|
+
|
44
|
+
}
|
45
|
+
|
46
|
+
p Adapi::AdGroup.create(:data => ad_group_data)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
require 'adapi'
|
3
|
+
|
4
|
+
# create ad group
|
5
|
+
require 'add_bare_ad_group'
|
6
|
+
|
7
|
+
keyword_criterion = {
|
8
|
+
:xsi_type => 'BiddableAdGroupCriterion',
|
9
|
+
:criterion => { :xsi_type => 'Keyword', :text => 'codez', :match_type => 'BROAD' }
|
10
|
+
}
|
11
|
+
|
12
|
+
placement_criterion = {
|
13
|
+
:xsi_type => 'BiddableAdGroupCriterion',
|
14
|
+
:criterion => { :xsi_type => 'Placement', :url => 'http://www.blogger.com' }
|
15
|
+
}
|
16
|
+
|
17
|
+
p Adapi::AdGroupCriterion.create(
|
18
|
+
:ad_group_id => $ad_group[:id],
|
19
|
+
:criteria => [keyword_criterion, placement_criterion]
|
20
|
+
)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
require 'adapi'
|
3
|
+
|
4
|
+
# create campaign
|
5
|
+
require 'add_bare_campaign'
|
6
|
+
|
7
|
+
# create ad group with basic data only
|
8
|
+
# this script is used as an include in other scripts
|
9
|
+
|
10
|
+
$ad_group_data = {
|
11
|
+
:name => "AdGroup #%d" % (Time.new.to_f * 1000).to_i,
|
12
|
+
:status => 'ENABLED',
|
13
|
+
:campaign_id => $campaign[:id],
|
14
|
+
:bids => {
|
15
|
+
:xsi_type => 'ManualCPCAdGroupBids',
|
16
|
+
:keyword_max_cpc => {
|
17
|
+
:amount => {
|
18
|
+
:micro_amount => 10000000
|
19
|
+
}
|
20
|
+
}
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
$ad_group = Adapi::AdGroup.create(:data => $ad_group_data)
|
25
|
+
|
26
|
+
p $ad_group
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
require 'adapi'
|
3
|
+
|
4
|
+
# add campaign with basic data only
|
5
|
+
# this script is used as an include in other scripts
|
6
|
+
|
7
|
+
$campaign_data = {
|
8
|
+
:name => "Campaign #%d" % (Time.new.to_f * 1000).to_i,
|
9
|
+
:status => 'PAUSED',
|
10
|
+
:bidding_strategy => { :xsi_type => 'ManualCPC' },
|
11
|
+
:budget => {
|
12
|
+
:period => 'DAILY',
|
13
|
+
:amount => { :micro_amount => 50000000 },
|
14
|
+
:delivery_method => 'STANDARD'
|
15
|
+
},
|
16
|
+
|
17
|
+
:network_setting => {
|
18
|
+
:target_google_search => true,
|
19
|
+
:target_search_network => true,
|
20
|
+
:target_content_network => false,
|
21
|
+
:target_content_contextual => false
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
$campaign = Adapi::Campaign.create($campaign_data)
|
26
|
+
|
27
|
+
p $campaign
|
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
require 'adapi'
|
3
|
+
|
4
|
+
# create campaign by single command, with campaing targets, with ad_groups
|
5
|
+
# including keywords and ads
|
6
|
+
|
7
|
+
campaign_data = {
|
8
|
+
:name => "Campaign #%d" % (Time.new.to_f * 1000).to_i,
|
9
|
+
:status => 'PAUSED',
|
10
|
+
:bidding_strategy => { :xsi_type => 'ManualCPC' },
|
11
|
+
:budget => {
|
12
|
+
:period => 'DAILY',
|
13
|
+
:amount => { :micro_amount => 50000000 },
|
14
|
+
:delivery_method => 'STANDARD'
|
15
|
+
},
|
16
|
+
|
17
|
+
:network_setting => {
|
18
|
+
:target_google_search => true,
|
19
|
+
:target_search_network => true,
|
20
|
+
:target_content_network => false,
|
21
|
+
:target_content_contextual => false
|
22
|
+
},
|
23
|
+
|
24
|
+
:targets => {
|
25
|
+
:language => [ 'en', 'cs' ],
|
26
|
+
:geo => { :country => 'CZ' }
|
27
|
+
},
|
28
|
+
|
29
|
+
:ad_groups => [
|
30
|
+
{
|
31
|
+
:name => "AdGroup #%d" % (Time.new.to_f * 1000).to_i,
|
32
|
+
:status => 'ENABLED',
|
33
|
+
:bids => {
|
34
|
+
:xsi_type => 'ManualCPCAdGroupBids',
|
35
|
+
:keyword_max_cpc => {
|
36
|
+
:amount => {
|
37
|
+
:micro_amount => 10000000
|
38
|
+
}
|
39
|
+
}
|
40
|
+
},
|
41
|
+
|
42
|
+
:criteria => [
|
43
|
+
{ # keyword_criterion
|
44
|
+
:xsi_type => 'BiddableAdGroupCriterion',
|
45
|
+
:criterion => { :xsi_type => 'Keyword', :text => 'codez', :match_type => 'BROAD' }
|
46
|
+
},
|
47
|
+
{ # placement_criterion
|
48
|
+
:xsi_type => 'BiddableAdGroupCriterion',
|
49
|
+
:criterion => { :xsi_type => 'Placement', :url => 'http://www.blogger.com' }
|
50
|
+
}
|
51
|
+
],
|
52
|
+
|
53
|
+
:ads => [
|
54
|
+
{
|
55
|
+
:xsi_type => 'TextAd',
|
56
|
+
:headline => "Code like Neo",
|
57
|
+
:description1 => 'Need mad coding skills?',
|
58
|
+
:description2 => 'Check out my new blog!',
|
59
|
+
:url => 'http://www.demcodez.com',
|
60
|
+
:display_url => 'http://www.demcodez.com'
|
61
|
+
}
|
62
|
+
]
|
63
|
+
}
|
64
|
+
]
|
65
|
+
|
66
|
+
}
|
67
|
+
|
68
|
+
p Adapi::Campaign.create(campaign_data)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
require 'adapi'
|
3
|
+
|
4
|
+
# create campaign
|
5
|
+
require 'add_bare_campaign'
|
6
|
+
|
7
|
+
# create campaign targets
|
8
|
+
campaign_target_data = {
|
9
|
+
:campaign_id => $campaign[:id],
|
10
|
+
:targets => {
|
11
|
+
:language => [ 'en', 'cs' ],
|
12
|
+
:geo => { :country => 'CZ' }
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
p Adapi::CampaignTarget.create(campaign_target_data)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
:default:
|
3
|
+
:authentication:
|
4
|
+
:method: ClientLogin
|
5
|
+
:email: default_email@gmail.com
|
6
|
+
:password: default_password
|
7
|
+
:developer_token: default_token
|
8
|
+
:client_email: default_client_email@gmail.com
|
9
|
+
:user_agent: My Adwords API Client
|
10
|
+
:service:
|
11
|
+
:environment: PRODUCTION
|
12
|
+
|
13
|
+
:sandbox:
|
14
|
+
:authentication:
|
15
|
+
:method: ClientLogin
|
16
|
+
:email: sandbox_email@gmail.com
|
17
|
+
:password: sandbox_password
|
18
|
+
:developer_token: sandbox_token
|
19
|
+
:client_email: sandbox_client_email@gmail.com
|
20
|
+
:user_agent: Adwords API Test
|
21
|
+
:service:
|
22
|
+
:environment: SANDBOX
|