The code samples below provide examples of common reporting functions using the AdWords API. Client Library.
Download a criteria performance report with AWQL
#!/usr/bin/env ruby # Encoding: utf-8 # # Copyright:: Copyright 2012, Google Inc. All Rights Reserved. # # License:: Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # # This example gets an Ad Hoc report using AdWords Query Language. # See AWQL guide for more details: # https://developers.google.com/adwords/api/docs/guides/awql require 'date' require 'adwords_api' def download_criteria_report_with_awql(file_name, report_format) # AdwordsApi::Api will read a config file from ENV['HOME']/adwords_api.yml # when called without parameters. adwords = AdwordsApi::Api.new # To enable logging of SOAP requests, set the log_level value to 'DEBUG' in # the configuration file or provide your own logger: # adwords.logger = Logger.new('adwords_xml.log') # Get report utilities for the version. report_utils = adwords.report_utils(API_VERSION) # Prepare a date range for the last week. start_date = DateTime.parse((Date.today - 7).to_s).strftime('%Y%m%d') end_date = DateTime.parse((Date.today - 1).to_s).strftime('%Y%m%d') # Define report definition. You can also pass your own XML text as a string. report_query_builder = adwords.report_query_builder do |b| b.select(*%w[CampaignId AdGroupId Id Criteria CriteriaType Impressions Clicks Cost]) b.from('CRITERIA_PERFORMANCE_REPORT') b.where('Status').in('ENABLED', 'PAUSED') # You could use the during_date_range method to specify ranges such as # 'LAST_7_DAYS', but you can't specify both. b.during(start_date, end_date) end report_query = report_query_builder.build.to_s # Optional: Set the configuration of the API instance to suppress header, # column name, or summary rows in the report output. You can also configure # this in your adwords_api.yml configuration file. adwords.skip_report_header = false adwords.skip_column_header = false adwords.skip_report_summary = false # Enable to allow rows with zero impressions to show. adwords.include_zero_impressions = true # Download report, using "download_report_as_file_with_awql" utility method. # To retrieve the report as return value, use "download_report_with_awql" # method. report_utils.download_report_as_file_with_awql(report_query, report_format, file_name) puts "Report was downloaded to '%s'." % file_name end if __FILE__ == $0 API_VERSION = :v201809 begin # File name to write report to. file_name = 'INSERT_OUTPUT_FILE_NAME_HERE' report_format = 'CSV' download_criteria_report_with_awql(file_name, report_format) # Authorization error. rescue AdsCommon::Errors::OAuth2VerificationRequired => e puts "Authorization credentials are not valid. Edit adwords_api.yml for " + "OAuth2 client ID and secret and run misc/setup_oauth2.rb example " + "to retrieve and store OAuth2 tokens." puts "See this wiki page for more details:\n\n " + 'https://github.com/googleads/google-api-ads-ruby/wiki/OAuth2' # HTTP errors. rescue AdsCommon::Errors::HttpError => e puts 'HTTP Error: %s' % e # API errors. rescue AdwordsApi::Errors::ReportError => e puts 'Reporting Error: %s' % e.message end end
Download a criteria performance report using selectors
#!/usr/bin/env ruby # Encoding: utf-8 # # Copyright:: Copyright 2011, Google Inc. All Rights Reserved. # # License:: Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # # This example gets and downloads an Ad Hoc report from a XML report definition. require 'adwords_api' def download_criteria_report_with_selector(file_name) # AdwordsApi::Api will read a config file from ENV['HOME']/adwords_api.yml # when called without parameters. adwords = AdwordsApi::Api.new # To enable logging of SOAP requests, set the log_level value to 'DEBUG' in # the configuration file or provide your own logger: # adwords.logger = Logger.new('adwords_xml.log') # Get report utilities for the version. report_utils = adwords.report_utils(API_VERSION) # Define report definition. You can also pass your own XML text as a string. report_definition = { :selector => { :fields => ['CampaignId', 'AdGroupId', 'Id', 'Criteria', 'CriteriaType', 'FinalUrls', 'Impressions', 'Clicks', 'Cost'], # Predicates are optional. :predicates => { :field => 'Status', :operator => 'IN', :values => ['ENABLED', 'PAUSED'] } }, :report_name => 'Last 7 days CRITERIA_PERFORMANCE_REPORT', :report_type => 'CRITERIA_PERFORMANCE_REPORT', :download_format => 'CSV', :date_range_type => 'LAST_7_DAYS', } # Optional: Set the configuration of the API instance to suppress header, # column name, or summary rows in the report output. You can also configure # this in your adwords_api.yml configuration file. adwords.skip_report_header = false adwords.skip_column_header = false adwords.skip_report_summary = false # Enable to allow rows with zero impressions to show. adwords.include_zero_impressions = false # Download report, using "download_report_as_file" utility method. # To retrieve the report as return value, use "download_report" method. report_utils.download_report_as_file(report_definition, file_name) puts "Report was downloaded to '%s'." % file_name end if __FILE__ == $0 API_VERSION = :v201809 begin # File name to write report to. file_name = 'INSERT_OUTPUT_FILE_NAME_HERE' download_criteria_report_with_selector(file_name) # Authorization error. rescue AdsCommon::Errors::OAuth2VerificationRequired => e puts "Authorization credentials are not valid. Edit adwords_api.yml for " + "OAuth2 client ID and secret and run misc/setup_oauth2.rb example " + "to retrieve and store OAuth2 tokens." puts "See this wiki page for more details:\n\n " + 'https://github.com/googleads/google-api-ads-ruby/wiki/OAuth2' # HTTP errors. rescue AdsCommon::Errors::HttpError => e puts "HTTP Error: %s" % e # API errors. rescue AdwordsApi::Errors::ReportError => e puts "Reporting Error: %s" % e.message end end
Get the report fields from a report
#!/usr/bin/env ruby # Encoding: utf-8 # # Copyright:: Copyright 2011, Google Inc. All Rights Reserved. # # License:: Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # # This example gets the list of possible report fields for a report type. require 'adwords_api' def get_report_fields(report_type) # AdwordsApi::Api will read a config file from ENV['HOME']/adwords_api.yml # when called without parameters. adwords = AdwordsApi::Api.new # To enable logging of SOAP requests, set the log_level value to 'DEBUG' in # the configuration file or provide your own logger: # adwords.logger = Logger.new('adwords_xml.log') report_def_srv = adwords.service(:ReportDefinitionService, API_VERSION) # Get report fields. fields = report_def_srv.get_report_fields(report_type) if fields puts "Report type '%s' contains the following fields:" % report_type fields.each do |field| puts ' - %s (%s)' % [field[:field_name], field[:field_type]] puts ' := [%s]' % field[:enum_values].join(', ') if field[:enum_values] end end end if __FILE__ == $0 API_VERSION = :v201809 begin report_type = 'INSERT_REPORT_TYPE_HERE' get_report_fields(report_type) # Authorization error. rescue AdsCommon::Errors::OAuth2VerificationRequired => e puts "Authorization credentials are not valid. Edit adwords_api.yml for " + "OAuth2 client ID and secret and run misc/setup_oauth2.rb example " + "to retrieve and store OAuth2 tokens." puts "See this wiki page for more details:\n\n " + 'https://github.com/googleads/google-api-ads-ruby/wiki/OAuth2' # HTTP errors. rescue AdsCommon::Errors::HttpError => e puts "HTTP Error: %s" % e # API errors. rescue AdwordsApi::Errors::ApiException => e puts "Message: %s" % e.message puts 'Errors:' e.errors.each_with_index do |error, index| puts "\tError [%d]:" % (index + 1) error.each do |field, value| puts "\t\t%s: %s" % [field, value] end end end end
Download a report for multiple accounts
#!/usr/bin/env ruby # Encoding: utf-8 # # Copyright:: Copyright 2011, Google Inc. All Rights Reserved. # # License:: Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # # This example gets and downloads an Ad Hoc report from a XML report definition # for all accounts in hierarchy in multiple parallel threads. This example # needs to be run against an AdWords manager account. require 'thread' require 'adwords_api' require 'adwords_api/utils' def parallel_report_download() # AdwordsApi::Api will read a config file from ENV['HOME']/adwords_api.yml # when called without parameters. adwords = AdwordsApi::Api.new # To enable logging of SOAP requests, set the log_level value to 'DEBUG' in # the configuration file or provide your own logger: # adwords.logger = Logger.new('adwords_xml.log') # Determine list of customer IDs to retrieve report for. For this example we # will use ManagedCustomerService to get all IDs in hierarchy. managed_customer_srv = adwords.service(:ManagedCustomerService, API_VERSION) # Get the account hierarchy for this account. selector = {:fields => ['CustomerId']} graph = managed_customer_srv.get(selector) # Using queue to balance load between threads. queue = Queue.new() if graph and graph[:entries] and !graph[:entries].empty? graph[:entries].each {|account| queue << account[:customer_id]} else raise StandardError, 'Can not retrieve any customer ID' end # Get report utilities for the version. report_utils = adwords.report_utils(API_VERSION) # Define report definition. You can also pass your own XML text as a string. report_definition = { :selector => { :fields => ['CampaignId', 'AdGroupId', 'Impressions', 'Clicks', 'Cost'], # Predicates are optional. :predicates => { :field => 'AdGroupStatus', :operator => 'IN', :values => ['ENABLED', 'PAUSED'] } }, :report_name => 'Custom ADGROUP_PERFORMANCE_REPORT', :report_type => 'ADGROUP_PERFORMANCE_REPORT', :download_format => 'CSV', :date_range_type => 'LAST_7_DAYS' } puts 'Retrieving %d reports with %d threads:' % [queue.size, THREADS] reports_succeeded = Queue.new() reports_failed = Queue.new() # Creating a mutex to control access to the queue. queue_mutex = Mutex.new # Start all the threads. threads = (1..THREADS).map do |thread_id| Thread.new(report_definition) do |local_def| cid = nil begin cid = queue_mutex.synchronize {(queue.empty?) ? nil : queue.pop(true)} if cid retry_count = 0 file_name = 'adgroup_%010d.csv' % cid puts "[%2d/%d] Loading report for customer ID %s into '%s'..." % [thread_id, retry_count, AdwordsApi::Utils.format_id(cid), file_name] begin report_utils.download_report_as_file(local_def, file_name, cid) reports_succeeded << {:cid => cid, :file_name => file_name} rescue AdwordsApi::Errors::ReportError => e if e.http_code == 500 && retry_count < MAX_RETRIES retry_count += 1 sleep(retry_count * BACKOFF_FACTOR) retry else puts(('Report failed for customer ID %s with code %d after %d ' + 'retries.') % [cid, e.http_code, retry_count + 1]) reports_failed << {:cid => cid, :http_code => e.http_code, :message => e.message} end end end end while (cid != nil) end end # Wait for all threads to finish. threads.each { |aThread| aThread.join } puts 'Download completed, results:' puts 'Successful reports:' while !reports_succeeded.empty? do result = reports_succeeded.pop() puts "\tClient ID %s => '%s'" % [AdwordsApi::Utils.format_id(result[:cid]), result[:file_name]] end puts 'Failed reports:' while !reports_failed.empty? do result = reports_failed.pop() puts "\tClient ID %s => Code: %d, Message: '%s'" % [AdwordsApi::Utils.format_id(result[:cid]), result[:http_code], result[:message]] end puts 'End of results.' end if __FILE__ == $0 API_VERSION = :v201809 # Number of parallel threads to spawn. THREADS = 10 # Maximum number of retries for 500 errors. MAX_RETRIES = 5 # Timeout between retries in seconds. BACKOFF_FACTOR = 5 begin parallel_report_download() # Authorization error. rescue AdsCommon::Errors::OAuth2VerificationRequired => e puts "Authorization credentials are not valid. Edit adwords_api.yml for " + "OAuth2 client ID and secret and run misc/setup_oauth2.rb example " + "to retrieve and store OAuth2 tokens." puts "See this wiki page for more details:\n\n " + 'https://github.com/googleads/google-api-ads-ruby/wiki/OAuth2' # HTTP errors. rescue AdsCommon::Errors::HttpError => e puts 'HTTP Error: %s' % e # API errors. rescue AdwordsApi::Errors::ReportError => e puts 'Reporting Error: %s' % e.message end end
Stream results from a report
#!/usr/bin/env ruby # Encoding: utf-8 # # Copyright:: Copyright 2015, Google Inc. All Rights Reserved. # # License:: Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # # This example streams the results of an Ad Hoc report to a file. require 'adwords_api' def stream_criteria_report_results() # AdwordsApi::Api will read a config file from ENV['HOME']/adwords_api.yml # when called without parameters. adwords = AdwordsApi::Api.new # To enable logging of SOAP requests, set the log_level value to 'DEBUG' in # the configuration file or provide your own logger: # adwords.logger = Logger.new('adwords_xml.log') # Get report utilities for the version. report_utils = adwords.report_utils(API_VERSION) # Define report query. report_query_builder = adwords.report_query_builder do |b| b.select('Id', 'AdNetworkType1', 'Impressions') b.from('CRITERIA_PERFORMANCE_REPORT') b.where('Status').in('ENABLED', 'PAUSED') b.during_date_range('LAST_7_DAYS') end report_query = report_query_builder.build.to_s # Optional: Set the configuration of the API instance to suppress header, # column name, or summary rows in the report output. You can also configure # this in your adwords_api.yml configuration file. adwords.skip_report_header = true adwords.skip_column_header = true adwords.skip_report_summary = true # Enable to allow rows with zero impressions to show. adwords.include_zero_impressions = false # Set the default value of the hash to 0 to allow easy totaling. ad_network_map = Hash.new(0) # We use get_stream_helper_with_awql.each_line here, which uses the # ReportStream utility to handle breaking the streamed results into lines # for easy processing. If you'd rather handle processing yourself, you can # use download_report_as_stream_with_awql, which just passes data to the # block as it's downloaded, without breaking it up into meaningful chunks. report_utils.get_stream_helper_with_awql( report_query, 'CSV').each_line do |line| process_line(line, ad_network_map) end puts 'Total impressions by ad network type 1:' ad_network_map.each do |ad_network_type, total_impressions| puts ' %s: %s' % [ad_network_type, total_impressions] end end def process_line(line, ad_network_map) id, ad_network_type_1, impressions = line.split(',') ad_network_map[ad_network_type_1] += impressions.to_i end if __FILE__ == $0 API_VERSION = :v201809 begin # File name to write report to. stream_criteria_report_results() # Authorization error. rescue AdsCommon::Errors::OAuth2VerificationRequired => e puts "Authorization credentials are not valid. Edit adwords_api.yml for " + "OAuth2 client ID and secret and run misc/setup_oauth2.rb example " + "to retrieve and store OAuth2 tokens." puts "See this wiki page for more details:\n\n " + 'https://github.com/googleads/google-api-ads-ruby/wiki/OAuth2' # HTTP errors. rescue AdsCommon::Errors::HttpError => e puts "HTTP Error: %s" % e # API errors. rescue AdwordsApi::Errors::ReportError => e puts "Reporting Error: %s" % e.message end end