Adapi (ADwords API) is a Ruby library for easy and painless work with Google Adwords API. Its users shouldn't bother with SOAP and tangle of XML- and API-specific objects, inputs and outputs are plain Ruby arrays and hashes.
Adapi is built on google-adwords-api
gem. Arrays and hashes instead of objects
come from there, but adapi takes it several steps further:
-
AdWords services are represented by ActiveModel-compatible models with relations. Among other things it's possible to create whole campaign in single method call:
Adapi::Campaign.create(campaign_data)
. -
Various convenience methods are added to the models, for example:
campaign.pause!
(pauses campaign). -
Adapi enables you to easily work with multiple AdWords accounts at the same time.
Adapi is still in development and not nearly done yet! Version 1.0.0 should have all planned functionality.
Adapi supports the latest version of AdWords API: v201209.
gem install adapi
git clone [email protected]:lstejskal/adapi.git
cd adapi
bundle install
rake install
This section explains how to connect to specific AdWords account and client. The configuration
structure is quite similar to the configuration of google-adwords-api
gem.
There are several options to choose from:
Adapi::Config.load_settings( in_hash: {
production: {
authentication: {
method: "OAuth2",
oauth2_client_id: "abc",
oauth2_client_secret: "def",
oauth2_token: {
access_token: "123",
refresh_token: "456",
issued_at: "2013-03-03 13:33:39.734203841 +01:00",
expires_in: 3600,
id_token: nil
},
developer_token: "789",
user_agent: "My Adwords API Client",
client_customer_id: "555-666-7777"
},
service: {
environment: "PRODUCTION"
}
}
})
Adapi::Config.set(:production)
You can set many AdWords accounts to connect to and switch between while running the application. You can even update single values of the settings on-the-fly.
Adapi::Config.load_settings( in_hash: {
coca_cola: config_hash_for_coca_cola,
pepsi: config_hash_for_pepsi
})
# set to pepsi and specific client
Adapi::Config.set(:pepsi, :client_customer_id => '555-666-7777')
# do some stuff here...
# set to coca-cola and another client
Adapi::Config.set(:coca_cola, :client_customer_id => '777-666-5555')
# do some stuff here...
Stored in ~/adapi.yml
. Supports multiple accounts, which are identifed by
aliases. Example:
:default:
:authentication:
:method: OAuth2
:oauth2_client_id: "abc"
:oauth2_client_secret: "def"
:oauth2_token:
:access_token: "123"
:refresh_token: "456"
:issued_at: 2013-03-03 13:33:39.734203841 +01:00
:expires_in: 3600
:id_token:
:developer_token: "789"
:user_agent: My Adwords API Client
:client_customer_id: 555-666-7777
:service:
:environment: PRODUCTION
:library:
:log_level: WARN
:log_path: /tmp/adapi.log
:log_pretty_format: true
To tell adapi which account to use:
Adapi::Config.set(:production)
:default
account is, as name implies, used by default. If you don't have
:default
account available, you have to manually set account alias to
Adapi::Config
.
-
get
oauth2_client_id
andoauth2_client_secret
: [https://code.google.com/p/google-api-ads-ruby/wiki/OAuth2][https://code.google.com/p/google-api-ads-ruby/wiki/OAuth2] -
put them into adapi configuration file
-
run following script:
require 'adapi'
require 'yaml'
adapi_object = Adapi::Location.new() # load any adapi object
adwords_api = adapi_object.adwords # get adwords object
# got to url and paste verification code to the script
oauth2_token = adwords.authorize() do |auth_url|
puts "Go to URL:\n\t%s" % auth_url
print 'log in and type the verification code: '
gets.chomp
end
puts oauth2_token.to_yaml
- put
oauth2_token
hash adapi configuration file
Code taken from this google-adwords-api example: [https://code.google.com/p/google-api-ads-ruby/source/browse/adwords_api/examples/v201209/misc/use_oauth2.rb][https://code.google.com/p/google-api-ads-ruby/source/browse/adwords_api/examples/v201209/misc/use_oauth2.rb]
Adapi supports the latest version of AdWords API: v201209.
For support of earlier versions of AdWords API, downgrade to earlier versions of adapi: 0.1.5 for v201206, 0.0.9 for v201109_1, 0.07 for v201109. (You shoudn't need it though, older versions of AdWords API are eventually shut down.) Latest revision for specific AdWords API version is also marked by a tag.
Adapi tries to not to bother users with AdWords API low-level specifics as much as possible, if you're upgrading to newer version of AdWords API, please be cautious, check the release notes and update your code accordingly. Adapi won't accept obsolete attributes etc.
Following AdWords services are not supported by adapi at the moment, and exist only on my TODO list:
-
Campaign Data Management
- ConversionTrackerService
- UserListService
-
Optimization
- BulkOpportunityService
- ReportDefinitionService
- TargetingIdeaService
- TrafficEstimatorService
-
Account Management
- CustomerSyncService
-
Utility
- MutateJobService
- BulkMutateJobService
Examples are available in examples directory. For now, they
are mostly just uninspired rewrites of examples from google-adwords-api
gem,
but that's going to change when proper UI to AdWords models will be implemented.
Here are some examples to get you started with adapi. (All this is also available in examples directory.)
Creates a campaign with ad_groups and ad_texts from hash - by single method call.
campaign = Adapi::Campaign.create(
:name => "Campaign #%d" % (Time.new.to_f * 1000).to_i,
:status => 'PAUSED',
:bidding_strategy => {
:xsi_type => 'BudgetOptimizer',
:bid_ceiling => 100
},
:budget => {
:amount => 50,
:delivery_method => 'STANDARD'
},
:criteria => {
:language => [ :en, :cs ],
:location => {
# PS: province and country codes are now obsolete in AdWords API,
# but they still work in adapi
:name => { :city => 'Prague', :region => 'CZ-PR', :country => 'CZ' }
}
},
:ad_groups => [
{
:name => "AdGroup #%d" % (Time.new.to_f * 1000).to_i,
:status => 'ENABLED',
:keywords => [ 'dem codez', '"top coder"', "[-code]" ],
:ads => [
{
:headline => "Code like Neo",
:description1 => 'Need mad coding skills?',
:description2 => 'Check out my new blog!',
:url => 'http://www.demcodez.com',
:display_url => 'http://www.demcodez.com'
}
]
}
]
)
Creates a campaign with ad_groups and ad_texts step by step.
campaign = Adapi::Campaign.create(
:name => "Campaign #%d" % (Time.new.to_f * 1000).to_i,
:status => 'PAUSED',
:bidding_strategy => { :xsi_type => 'BudgetOptimizer', :bid_ceiling => 100 },
:budget => { :amount => 50, :delivery_method => 'STANDARD' }
)
Adapi::CampaignCriterion.create(
:campaign_id => campaign.id,
:criteria => {
:language => %w{ en cs },
:location => {
:name => { :city => 'Prague', :region => 'CZ-PR', :country => 'CZ' }
}
}
)
ad_group = Adapi::AdGroup.create(
:campaign_id => campaign.id,
:name => "AdGroup #%d" % (Time.new.to_f * 1000).to_i,
:status => 'ENABLED'
)
Adapi::Keyword.create(
:ad_group_id => ad_group.id,
:keywords => [ 'dem codez', '"top coder"', '[-code]' ]
)
Adapi::Ad::TextAd.create(
:ad_group_id => ad_group.id,
:headline => "Code like Neo",
:description1 => 'Need mad coding skills?',
:description2 => 'Check out my new blog!',
:url => 'http://www.demcodez.com',
:display_url => 'http://www.demcodez.com'
)
# find complete campaign
new_campaign = Adapi::Campaign.find_complete(campaign.id)
# display campaign as hash
puts new_campaign.to_hash.inspect
Campaign criteria (formerly targets) have been rewritten from the scratch for v201109. The goal is to provide a simple DSL for criteria so user doesn't have to deal with somewhat convoluted AdWords API syntax made for machines, not humans. So far, this has been done only for language and location criterion. You can use any other criteria, you just have to enter them in AdWords format.
Adapi::CampaignCriterion.create(
:campaign_id => campaign.id,
:criteria => {
:language => %w{ en cs },
}
)
:language
parameter accepts string or symbols for single language target or
array of strings/symbols for several language targets.
Adapi::CampaignCriterion.create(
:campaign_id => campaign.id,
:criteria => {
:location => {
:name => { :city => 'Prague', :region => 'CZ-PR', :country => 'CZ' }
}
)
This criterion has been heavily customized in adapi to comply with legacy
interfaces (pre-v201109). In other words, you don't have to enter locations as
ids (although you can). :location
accepts following parameters:
:id
- this is standard location interface of AdWordsv201109_1
:location => location_id
:location => { :id => location_id }
:location => { :id => [ location_id ] }
:proximity
:geo_point
: "longitude,lattitude":radius
: "radius_in_units radius_units"
:location => { :proximity => { :geo_point => '50.083333,14.366667', :radius => '50 km' } }
:name
- hash with parameters specifying location name::city
:region
(also:province
) - as name ("New York"
) or code ("US-NY"
):country
- as name ("Czech Republic"
) or code ("CZ"
)
:location => { :name => { :country => 'Czech Republic' } }
:location => { :name => { :city => 'Prague' } }
:location => { :name => { :city => 'Prague', :region => 'CZ-PR', :country => 'CZ' } }
Unfortunately, at the moment you can't target more locations in one CampaignCriterion request. This is going to be fixed in the next version, but for now please use following workaround - call CampaignCriterion several times:
Adapi::CampaignCriterion.create(
:campaign_id => campaign.id,
:criteria => {
:location => {
:name => { :city => 'Prague', :region => 'CZ-PR', :country => 'CZ' }
}
)
Adapi::CampaignCriterion.create(
:campaign_id => campaign.id,
:criteria => {
:location => {
:name => { :city => 'Brno', :region => 'CZ-JM', :country => 'CZ' }
}
}
)
Convenient shortcuts for other criteria besides language and location are not yet implemented. However, you can use any other criteria, you just have to enter them as ids.
Adapi::CampaignCriterion.create(
:campaign_id => campaign.id,
:criteria => {
:platform => [ { :id => 30001} ]
}
)
By default, communication with AdWords API is not logged. In order to log
messages of certain log level or above, set library/log_level
in configuration
(INFO or DEBUG setting is recommended for local development).
Default log path is "~/adapi.log". You can set custom log path in:
library/log_path
.
By default, SOAP messages are logged in ugly format - everything fits on single
line. It's fast, but quite difficult to read. To log SOAP requests and responses
in pretty format, set library/log_pretty_format
in configuration to true
.
Example of logger configuration:
:library:
:log_level: DEBUG
:log_path: /home/username/log/adapi.log
:log_pretty_format: true
2011-2013 Lukas Stejskal, Ataxo Interactive, a.s.