Basic Operations Samples

The code samples below provide examples of basic operations using the AdWords API. Client Library.

Add ad groups to a campaign

#!/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 illustrates how to create ad groups. To get a list of existing
# campaigns run get_campaigns.rb.

require 'adwords_api'

def add_ad_groups(campaign_id)
  # 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')

  ad_group_srv = adwords.service(:AdGroupService, API_VERSION)

  ad_groups = [
    {
      :name => "Earth to Mars Cruises #%d" % (Time.new.to_f * 1000).to_i,
      :status => 'ENABLED',
      :campaign_id => campaign_id,
      :bidding_strategy_configuration => {
        :bids => [
          {
            # The 'xsi_type' field allows you to specify the xsi:type of the
            # object being created. It's only necessary when you must provide
            # an explicit type that the client library can't infer.
            :xsi_type => 'CpcBid',
            :bid => {:micro_amount => 10000000}
          }
        ]
      },
      :ad_group_ad_rotation_mode => {
        :ad_rotation_mode => 'OPTIMIZE'
      },
      :settings => [
        # Targeting restriction settings. Depending on the :criterion_type_group
        # value, most TargetingSettingDetail only affect Display campaigns.
        # However, the USER_INTEREST_AND_LIST value works for RLSA campaigns -
        # Search campaigns targeting using a remarketing list.
        {
          :xsi_type => 'TargetingSetting',
          :details => [
            # Restricting to serve ads that match your ad group placements.
            # This is equivalent to choosing "Target and bid" in the UI.
            {
              :xsi_type => 'TargetingSettingDetail',
              :criterion_type_group => 'PLACEMENT',
              :target_all => false
            },
            # Using your ad group verticals only for bidding. This is equivalent
            # to choosing "Bid only" in the UI.
            {
              :xsi_type => 'TargetingSettingDetail',
              :criterion_type_group => 'VERTICAL',
              :target_all => true
            }
          ]
        }
      ]
    },
    {
      :name => 'Earth to Pluto Cruises #%d' % (Time.new.to_f * 1000).to_i,
      :status => 'ENABLED',
      :campaign_id => campaign_id,
      :bidding_strategy_configuration => {
        :bids => [
          {
            # The 'xsi_type' field allows you to specify the xsi:type of the
            # object being created. It's only necessary when you must provide
            # an explicit type that the client library can't infer.
            :xsi_type => 'CpcBid',
            :bid => {:micro_amount => 10000000}
          }
        ]
      }
    }
  ]

  # Prepare operations for adding ad groups.
  operations = ad_groups.map do |ad_group|
    {:operator => 'ADD', :operand => ad_group}
  end

  # Add ad groups.
  response = ad_group_srv.mutate(operations)
  if response and response[:value]
    response[:value].each do |ad_group|
      puts "Ad group ID %d was successfully added." % ad_group[:id]
    end
  else
    raise StandardError, 'No ad group was added'
  end
end

if __FILE__ == $0
  API_VERSION = :v201809

  begin
    # Campaign ID to add ad group to.
    campaign_id = 'INSERT_CAMPAIGN_ID_HERE'.to_i
    add_ad_groups(campaign_id)

  # 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

Add campaigns

#!/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 illustrates how to create campaigns.

require 'adwords_api'
require 'date'

def add_campaigns()
  # 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')

  # Create a budget, which can be shared by multiple campaigns.
  budget_srv = adwords.service(:BudgetService, API_VERSION)
  budget = {
    :name => 'Interplanetary budget #%d' % (Time.new.to_f * 1000).to_i,
    :amount => {:micro_amount => 50000000},
    :delivery_method => 'STANDARD'
  }
  budget_operation = {:operator => 'ADD', :operand => budget}

  # Add budget.
  return_budget = budget_srv.mutate([budget_operation])
  budget_id = return_budget[:value].first[:budget_id]

  campaign_srv = adwords.service(:CampaignService, API_VERSION)

  # Create campaigns.
  campaigns = [
    {
      :name => "Interplanetary Cruise #%d" % (Time.new.to_f * 1000).to_i,
      # Recommendation: Set the campaign to PAUSED when creating it to stop the
      # ads from immediately serving. Set to ENABLED once you've added
      # targeting and the ads are ready to serve.
      :status => 'PAUSED',
      :bidding_strategy_configuration => {
        :bidding_strategy_type => 'MANUAL_CPC'
      },
      # Budget (required) - note only the budget ID is required.
      :budget => {:budget_id => budget_id},
      :advertising_channel_type => 'SEARCH',
      # Optional fields:
      :start_date =>
          DateTime.parse((Date.today + 1).to_s).strftime('%Y%m%d'),
      :network_setting => {
        :target_google_search => true,
        :target_search_network => true,
        :target_content_network => true
      },
      :settings => [
        {
          :xsi_type => 'GeoTargetTypeSetting',
          :positive_geo_target_type => 'DONT_CARE',
          :negative_geo_target_type => 'DONT_CARE'
        }
      ],
      :frequency_cap => {
        :impressions => '5',
        :time_unit => 'DAY',
        :level => 'ADGROUP'
      }
    },
    {
      :name => "Interplanetary Cruise banner #%d" % (Time.new.to_f * 1000).to_i,
      :status => 'PAUSED',
      :bidding_strategy_configuration => {
        :bidding_strategy_type => 'MANUAL_CPC'
      },
      :budget => {:budget_id => budget_id},
      :advertising_channel_type => 'DISPLAY'
    }
  ]

  # Prepare for adding campaign.
  operations = campaigns.map do |campaign|
    {:operator => 'ADD', :operand => campaign}
  end

  # Add campaign.
  response = campaign_srv.mutate(operations)
  if response and response[:value]
    response[:value].each do |campaign|
      puts "Campaign with name '%s' and ID %d was added." %
          [campaign[:name], campaign[:id]]
    end
  else
    raise new StandardError, 'No campaigns were added.'
  end
end

if __FILE__ == $0
  API_VERSION = :v201809

  begin
    add_campaigns()

  # 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

Add expanded text ads to an ad group

#!/usr/bin/env ruby
# Encoding: utf-8
#
# Copyright:: Copyright 2016, 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 adds expanded text ads to a given ad group.
# To get ad groups, run get_ad_groups.rb.

require 'adwords_api'
require 'date'

def add_expanded_text_ads(ad_group_id)
  # 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')

  ad_group_ad_srv = adwords.service(:AdGroupAdService, API_VERSION)

  # Create text ads.
  # The 'xsi_type' field allows you to specify the xsi:type of the object
  # being created. It's only necessary when you must provide an explicit
  # type that the client library can't infer.
  operations = 5.times.map do |i|
    expanded_text_ad = {
      :xsi_type => 'ExpandedTextAd',
      :headline_part1 => 'Cruise to Mars #%d' % (Time.new.to_f * 1000).to_i,
      :headline_part2 => 'Best Space Cruise Line',
      :headline_part3 => 'For Your Loved Ones',
      :description => 'Buy your tickets now!',
      :description2 => 'Discount ends soon',
      :final_urls => ['http://www.example.com/%d' % i],
      :path1 => 'all-inclusive',
      :path2 => 'deals'
    }

    ad_group_ad = {
      :ad_group_id => ad_group_id,
      :ad => expanded_text_ad,
      # Additional properties (non-required).
      :status => 'PAUSED'
    }

    operation = {
      :operator => 'ADD',
      :operand => ad_group_ad
    }
  end

  # Add ads.
  response = ad_group_ad_srv.mutate(operations)
  if response and response[:value]
    response[:value].each do |ad_group_ad|
      headline_part3 = ad_group_ad[:ad][:headline_part3]
      headline_part3_string = ''
      unless headline_part3.nil?
        headline_part3_string = ' | %s' % headline_part3
      end
      puts ('New expanded text ad with id "%d" and headline "%s | %s%s" was ' +
          'added.') % [
              ad_group_ad[:ad][:id],
              ad_group_ad[:ad][:headline_part1],
              ad_group_ad[:ad][:headline_part2],
              headline_part3_string
          ]
    end
  else
    raise StandardError, 'No ads were added.'
  end
end

if __FILE__ == $0
  API_VERSION = :v201809

  begin
    # Ad group ID to add text ads to.
    ad_group_id = 'INSERT_AD_GROUP_ID_HERE'.to_i
    add_expanded_text_ads(ad_group_id)

  # 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

Add keywords to an ad group

#!/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 illustrates how to add multiple keywords to a given ad group. To
# create an ad group, run add_ad_group.rb.

require 'adwords_api'

def add_keywords(ad_group_id)
  # 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')

  ad_group_criterion_srv =
      adwords.service(:AdGroupCriterionService, API_VERSION)

  # Create keywords.
  # The 'xsi_type' field allows you to specify the xsi:type of the object
  # being created. It's only necessary when you must provide an explicit
  # type that the client library can't infer.
  keywords = [
    {:xsi_type => 'BiddableAdGroupCriterion',
     :ad_group_id => ad_group_id,
     :criterion => {
       :xsi_type => 'Keyword',
       :text => 'mars cruise',
       :match_type => 'BROAD'
     },
     # Optional fields:
     :user_status => 'PAUSED',
     :final_urls => {
       :urls => ['http://example.com/mars']
     }
    },
    {:xsi_type => 'BiddableAdGroupCriterion',
     :ad_group_id => ad_group_id,
     :criterion => {
       :xsi_type => 'Keyword',
       :text => 'space hotel',
       :match_type => 'BROAD'}}
  ]

  # Create 'ADD' operations.
  operations = keywords.map do |keyword|
    {:operator => 'ADD', :operand => keyword}
  end

  # Add keywords.
  response = ad_group_criterion_srv.mutate(operations)
  if response and response[:value]
    ad_group_criteria = response[:value]
    puts "Added %d keywords to ad group ID %d:" %
        [ad_group_criteria.length, ad_group_id]
    ad_group_criteria.each do |ad_group_criterion|
      puts "\tKeyword ID is %d and type is '%s'" %
          [ad_group_criterion[:criterion][:id],
           ad_group_criterion[:criterion][:type]]
    end
  else
    raise StandardError, 'No keywords were added.'
  end
end

if __FILE__ == $0
  API_VERSION = :v201809

  begin
    # Ad group ID to add keywords to.
    ad_group_id = 'INSERT_AD_GROUP_ID_HERE'.to_i
    add_keywords(ad_group_id)

  # 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

Add a responsive search ad to an ad group

#!/usr/bin/env ruby
# Encoding: utf-8
#
# Copyright 2018 Google LLC
#
# 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 adds a responsive search ad to a given ad group.
# To get ad groups, run get_ad_groups.rb.

require 'adwords_api'
require 'date'

def add_responsive_search_ad(ad_group_id)
  # 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')

  ad_group_ad_srv = adwords.service(:AdGroupAdService, API_VERSION)

  # The 'xsi_type' field allows you to specify the xsi:type of the object
  # being created. It's only necessary when you must provide an explicit
  # type that the client library can't infer.
  responsive_search_ad = {
    :xsi_type => 'ResponsiveSearchAd',
    :headlines => [
      {
        :asset => {
          :xsi_type => 'TextAsset',
          :asset_text => 'Cruise to Mars #%d' % (Time.new.to_f * 1000).to_i
        },
        # Set a pinning to always choose this asset for HEADLINE_1. Pinning is
        # optional; if no pinning is set, then headlines and descriptions will
        # be rotated and the ones that perform best will be used more often.
        :pinned_field => 'HEADLINE_1'
      },
      {
        :asset => {
          :xsi_type => 'TextAsset',
          :asset_text => 'Best Space Cruise Line'
        }
      },
      {
        :asset => {
          :xsi_type => 'TextAsset',
          :asset_text => 'Experience the Stars'
        }
      }
    ],
    :descriptions => [
      {
        :asset => {
          :xsi_type => 'TextAsset',
          :asset_text => 'Buy your tickets now'
        }
      },
      {
        :asset => {
          :xsi_type => 'TextAsset',
          :asset_text => 'Visit the Red Planet'
        }
      }
    ],
    :final_urls => ['http://www.example.com/cruise'],
    :path1 => 'all-inclusive',
    :path2 => 'deals'
  }

  ad_group_ad = {
    :ad_group_id => ad_group_id,
    :ad => responsive_search_ad,
    # Additional properties (non-required).
    :status => 'PAUSED'
  }

  operation = {
    :operator => 'ADD',
    :operand => ad_group_ad
  }

  # Add ad.
  response = ad_group_ad_srv.mutate([operation])
  if response and response[:value]
    response[:value].each do |ad_group_ad|
      ad = ad_group_ad[:ad]
      puts 'New responsive search ad with ID %d was added.' % ad[:id]
      puts '  Headlines:'
      ad[:headlines].each do |headline|
        pinning = headline[:pinned_field]
        puts '    %s' % headline[:asset][:asset_text]
        puts '      (pinned to %s)' % pinning unless pinning.nil?
      end
      puts '  Descriptions:'
      ad[:descriptions].each do |description|
        pinning = description[:pinned_field]
        puts '    %s' % description[:asset][:asset_text]
        puts '      (pinned to %s)' % pinning unless pinning.nil?
      end
    end
  else
    raise StandardError, 'No ads were added.'
  end
end

if __FILE__ == $0
  API_VERSION = :v201809

  begin
    # Ad group ID to add responsive search ads to.
    ad_group_id = 'INSERT_AD_GROUP_ID_HERE'.to_i
    add_responsive_search_ad(ad_group_id)

  # 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

Get the ad groups of a campaign

#!/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 illustrates how to retrieve all the ad groups for a campaign. To
# create an ad group, run add_ad_group.rb.

require 'adwords_api'

def get_ad_groups(campaign_id)
  # 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')

  ad_group_srv = adwords.service(:AdGroupService, API_VERSION)

  # Get all the ad groups for this campaign.
  selector = {
    :fields => ['Id', 'Name'],
    :ordering => [{:field => 'Name', :sort_order => 'ASCENDING'}],
    :predicates => [
      {:field => 'CampaignId', :operator => 'IN', :values => [campaign_id]}
    ],
    :paging => {
      :start_index => 0,
      :number_results => PAGE_SIZE
    }
  }

  # Set initial values.
  offset, page = 0, {}

  begin
    page = ad_group_srv.get(selector)
    if page[:entries]
      page[:entries].each do |ad_group|
        puts "Ad group name is '%s' and ID is %d" %
            [ad_group[:name], ad_group[:id]]
      end
      # Increment values to request the next page.
      offset += PAGE_SIZE
      selector[:paging][:start_index] = offset
    end
  end while page[:total_num_entries] > offset

  if page.include?(:total_num_entries)
    puts "\tCampaign ID %d has %d ad group(s)." %
        [campaign_id, page[:total_num_entries]]
  end
end

if __FILE__ == $0
  API_VERSION = :v201809
  PAGE_SIZE = 500

  begin
    # Campaign ID to get ad groups for.
    campaign_id = 'INSERT_CAMPAIGN_ID_HERE'.to_i
    get_ad_groups(campaign_id)

  # 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

Get all campaigns

#!/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 illustrates how to retrieve all the campaigns for an account.

require 'adwords_api'

def get_campaigns()
  # 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')

  campaign_srv = adwords.service(:CampaignService, API_VERSION)

  # Get all the campaigns for this account.
  selector = {
    :fields => ['Id', 'Name', 'Status'],
    :ordering => [
      {:field => 'Name', :sort_order => 'ASCENDING'}
    ],
    :paging => {
      :start_index => 0,
      :number_results => PAGE_SIZE
    }
  }

  # Set initial values.
  offset, page = 0, {}

  begin
    page = campaign_srv.get(selector)
    if page[:entries]
      page[:entries].each do |campaign|
        puts "Campaign ID %d, name '%s' and status '%s'" %
            [campaign[:id], campaign[:name], campaign[:status]]
      end
      # Increment values to request the next page.
      offset += PAGE_SIZE
      selector[:paging][:start_index] = offset
    end
  end while page[:total_num_entries] > offset

  if page.include?(:total_num_entries)
    puts "\tTotal number of campaigns found: %d." % [page[:total_num_entries]]
  end
end

if __FILE__ == $0
  API_VERSION = :v201809
  PAGE_SIZE = 500

  begin
    get_campaigns()

  # 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

Get all campaigns using 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 illustrates how to retrieve all the campaigns for an account with
# AWQL.

require 'adwords_api'

def get_campaigns_with_awql()
  # 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')

  campaign_srv = adwords.service(:CampaignService, API_VERSION)

  # Get all the campaigns for this account.
  query_builder = adwords.service_query_builder do |b|
    b.select('Id', 'Name', 'Status')
    b.order_by_asc('Name')
    b.limit(0, PAGE_SIZE)
  end
  query = query_builder.build

  page = nil

  loop do
    page_query = query.to_s
    page = campaign_srv.query(page_query)
    if page[:entries]
      page[:entries].each do |campaign|
        puts "Campaign ID %d, name '%s' and status '%s'" %
            [campaign[:id], campaign[:name], campaign[:status]]
      end
    end
    break unless query.has_next(page)
    query.next_page
  end

  if page.include?(:total_num_entries)
    puts "\tTotal number of campaigns found: %d." % page[:total_num_entries]
  end
end

if __FILE__ == $0
  API_VERSION = :v201809
  PAGE_SIZE = 500

  begin
    get_campaigns_with_awql()

  # 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

Get expanded text ads in an ad group

#!/usr/bin/env ruby
# Encoding: utf-8
#
# Copyright:: Copyright 2016, 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 non-removed expanded text ads in an ad group. To add
# expanded text ads, run add_expanded_text_ads.rb.
# To get ad groups, run get_ad_groups.rb.

require 'adwords_api'

def get_expanded_text_ads(ad_group_id)
  # 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')

  ad_group_ad_srv = adwords.service(:AdGroupAdService, API_VERSION)

  # Get all the ads for this ad group.
  selector = {
    :fields => ['Id', 'Status', 'HeadlinePart1', 'HeadlinePart2',
        'Description'],
    :ordering => [{:field => 'Id', :sort_order => 'ASCENDING'}],
    # By default, disabled ads aren't returned by the selector. To return them,
    # include the DISABLED status in a predicate.
    :predicates => [
      {
        :field => 'AdGroupId',
        :operator => 'IN',
        :values => [ad_group_id]
      },
      {
        :field => 'Status',
        :operator => 'IN',
        :values => ['ENABLED', 'PAUSED']
      },
      {
        :field => 'AdType',
        :operator => 'EQUALS',
        :values => ['EXPANDED_TEXT_AD']
      }
    ],
    :paging => {
      :start_index => 0,
      :number_results => PAGE_SIZE
    }
  }

  # Set initial values.
  offset, page = 0, {}

  begin
    page = ad_group_ad_srv.get(selector)
    if page[:entries]
      page[:entries].each do |ad_group_ad|
        puts ('Expanded text ad with ID "%d", status "%s", and headline ' +
            '"%s - %s" was found.') % [ad_group_ad[:ad][:id],
            ad_group_ad[:status], ad_group_ad[:ad][:headline_part1],
            ad_group_ad[:ad][:headline_part2]]
      end
      # Increment values to request the next page.
      offset += PAGE_SIZE
      selector[:paging][:start_index] = offset
    end
  end while page[:total_num_entries] > offset

  if page.include?(:total_num_entries)
    puts "\tAd group ID %d has %d expanded text ad(s)." %
        [ad_group_id, page[:total_num_entries]]
  end
end

if __FILE__ == $0
  API_VERSION = :v201809
  PAGE_SIZE = 500

  begin
    # Ad group ID to get text ads for.
    ad_group_id = 'INSERT_AD_GROUP_ID_HERE'.to_i
    get_expanded_text_ads(ad_group_id)

  # 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

Get keywords in an ad group

#!/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 illustrates how to retrieve all keywords for an ad group. To add
# keywords to an existing ad group, run add_keywords.rb.

require 'adwords_api'

def get_keywords(ad_group_id)
  # 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')

  ad_group_criterion_srv =
      adwords.service(:AdGroupCriterionService, API_VERSION)

  # Get all keywords for this ad group.
  selector = {
    :fields => ['Id', 'CriteriaType', 'KeywordMatchType', 'KeywordText'],
    :ordering => [
      {:field => 'Id', :sort_order => 'ASCENDING'}
    ],
    :predicates => [
      {:field => 'AdGroupId', :operator => 'EQUALS', :values => [ad_group_id]},
      {:field => 'CriteriaType', :operator => 'EQUALS', :values => ['KEYWORD']}
    ],
    :paging => {
      :start_index => 0,
      :number_results => PAGE_SIZE
    }
  }

  # Set initial values.
  offset, page = 0, {}

  begin
    page = ad_group_criterion_srv.get(selector)
    if page[:entries]
      page[:entries].each do |keyword|
        puts "Keyword ID %d, type '%s', text '%s', and match type '%s'" %
            [keyword[:criterion][:id],
             keyword[:criterion][:type],
             keyword[:criterion][:text],
             keyword[:criterion][:match_type]]
      end
      # Increment values to request the next page.
      offset += PAGE_SIZE
      selector[:paging][:start_index] = offset
    end
  end while page[:total_num_entries] > offset

  if page.include?(:total_num_entries)
    puts "\tAd group ID %d has %d keyword(s)." %
        [ad_group_id, page[:total_num_entries]]
  end
end

if __FILE__ == $0
  API_VERSION = :v201809
  PAGE_SIZE = 500

  begin
    # Ad group ID to get keywords for.
    ad_group_id = 'INSERT_AD_GROUP_ID_HERE'.to_i
    get_keywords(ad_group_id)

  # 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

Get expanded text ads in an ad group

#!/usr/bin/env ruby
# Encoding: utf-8
#
# Copyright:: Copyright 2016, 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 non-removed expanded text ads in an ad group. To add
# expanded text ads, run add_expanded_text_ads.rb.
# To get ad groups, run get_ad_groups.rb.

require 'adwords_api'

def get_expanded_text_ads(ad_group_id)
  # 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')

  ad_group_ad_srv = adwords.service(:AdGroupAdService, API_VERSION)

  # Get all the ads for this ad group.
  selector = {
    :fields => ['Id', 'Status', 'HeadlinePart1', 'HeadlinePart2',
        'Description'],
    :ordering => [{:field => 'Id', :sort_order => 'ASCENDING'}],
    # By default, disabled ads aren't returned by the selector. To return them,
    # include the DISABLED status in a predicate.
    :predicates => [
      {
        :field => 'AdGroupId',
        :operator => 'IN',
        :values => [ad_group_id]
      },
      {
        :field => 'Status',
        :operator => 'IN',
        :values => ['ENABLED', 'PAUSED']
      },
      {
        :field => 'AdType',
        :operator => 'EQUALS',
        :values => ['EXPANDED_TEXT_AD']
      }
    ],
    :paging => {
      :start_index => 0,
      :number_results => PAGE_SIZE
    }
  }

  # Set initial values.
  offset, page = 0, {}

  begin
    page = ad_group_ad_srv.get(selector)
    if page[:entries]
      page[:entries].each do |ad_group_ad|
        puts ('Expanded text ad with ID "%d", status "%s", and headline ' +
            '"%s - %s" was found.') % [ad_group_ad[:ad][:id],
            ad_group_ad[:status], ad_group_ad[:ad][:headline_part1],
            ad_group_ad[:ad][:headline_part2]]
      end
      # Increment values to request the next page.
      offset += PAGE_SIZE
      selector[:paging][:start_index] = offset
    end
  end while page[:total_num_entries] > offset

  if page.include?(:total_num_entries)
    puts "\tAd group ID %d has %d expanded text ad(s)." %
        [ad_group_id, page[:total_num_entries]]
  end
end

if __FILE__ == $0
  API_VERSION = :v201809
  PAGE_SIZE = 500

  begin
    # Ad group ID to get text ads for.
    ad_group_id = 'INSERT_AD_GROUP_ID_HERE'.to_i
    get_expanded_text_ads(ad_group_id)

  # 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

Pause an ad

#!/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 illustrates how to update an ad, setting its status to 'PAUSED'.

require 'adwords_api'

def pause_ad(ad_group_id, ad_id)
  # 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')

  ad_group_ad_srv = adwords.service(:AdGroupAdService, API_VERSION)

  # Prepare operation for updating ad.
  operation = {
    :operator => 'SET',
    :operand => {
      :ad_group_id => ad_group_id,
      :status => 'PAUSED',
      :ad => {:id => ad_id}
    }
  }

  # Update ad.
  response = ad_group_ad_srv.mutate([operation])
  if response and response[:value]
    ad = response[:value].first
    puts "Ad ID %d was successfully updated, status set to '%s'." %
        [ad[:ad][:id], ad[:status]]
  else
    puts 'No ads were updated.'
  end
end

if __FILE__ == $0
  API_VERSION = :v201809

  begin
    # IDs of ad to pause and its ad group.
    ad_group_id = 'INSERT_AD_GROUP_ID_HERE'.to_i
    ad_id = 'INSERT_AD_ID_HERE'.to_i
    pause_ad(ad_group_id, ad_id)

  # 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

Remove an ad

#!/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 removes an ad using the 'REMOVE' operator. To get ads, run
# get_expanded_text_ads.rb.

require 'adwords_api'

def remove_ad(ad_group_id, ad_id)
  # 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')

  ad_group_ad_srv = adwords.service(:AdGroupAdService, API_VERSION)

  # Prepare for deleting ad.
  operation = {
    :operator => 'REMOVE',
    :operand => {
      :ad_group_id => ad_group_id,
      :ad => {
        :xsi_type => 'Ad',
        :id => ad_id
      }
    }
  }

  # Remove ad.
  response = ad_group_ad_srv.mutate([operation])
  if response and response[:value]
    ad = response[:value].first
    puts "Ad ID %d was successfully removed." % ad[:ad][:id]
  else
    puts 'No ads were removed.'
  end
end

if __FILE__ == $0
  API_VERSION = :v201809

  begin
    # IDs of an ad to remove and its ad group.
    ad_group_id = 'INSERT_AD_GROUP_ID_HERE'.to_i
    ad_id = 'INSERT_AD_ID_HERE'.to_i
    remove_ad(ad_group_id, ad_id)

  # 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

Remove an ad group

#!/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 removes an ad group by setting the status to 'REMOVED'. To get ad
# groups, run get_ad_groups.rb.

require 'adwords_api'

def remove_ad_group(ad_group_id)
  # 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')

  ad_group_srv = adwords.service(:AdGroupService, API_VERSION)

  # Prepare for deleting ad group.
  operation = {
    :operator => 'SET',
    :operand => {
      :id => ad_group_id,
      :status => 'REMOVED'
    }
  }

  # Remove ad group.
  response = ad_group_srv.mutate([operation])
  if response and response[:value]
    ad_group = response[:value].first
    puts "Ad group ID %d was successfully removed." % [ad_group[:id]]
  else
    puts 'No ad group was updated.'
  end
end

if __FILE__ == $0
  API_VERSION = :v201809

  begin
    # ID of an ad group to remove.
    ad_group_id = 'INSERT_AD_GROUP_ID_HERE'.to_i
    remove_ad_group(ad_group_id)

  # 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

Remove a campaign

#!/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 removes a campaign by setting the status to 'REMOVED'. To get
# campaigns, run get_campaigns.rb.

require 'adwords_api'

def remove_campaign(campaign_id)
  # 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')

  campaign_srv = adwords.service(:CampaignService, API_VERSION)

   # Prepare for deleting campaign.
  operation = {
    :operator => 'SET',
    :operand => {
      :id => campaign_id,
     :status => 'REMOVED'
    }
  }

  # Remove campaign.
  response = campaign_srv.mutate([operation])

  if response and response[:value]
    campaign = response[:value].first
    puts "Campaign ID %d was removed." %
        [campaign[:id]]
  else
    puts 'No campaign was updated.'
  end
end

if __FILE__ == $0
  API_VERSION = :v201809

  begin
    # ID of a campaign to remove.
    campaign_id = 'INSERT_CAMPAIGN_ID_HERE'.to_i
    remove_campaign(campaign_id)

  # 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

Remove a keyword

#!/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 removes a keyword using the 'REMOVE' operator. To get list of
# keywords, run get_keywords.rb.

require 'adwords_api'

def remove_keyword(ad_group_id, criterion_id)
  # 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')

  ad_group_criterion_srv =
      adwords.service(:AdGroupCriterionService, API_VERSION)

  # Prepare for deleting keyword.
  operation = {
    :operator => 'REMOVE',
    :operand => {
      # The 'xsi_type' field allows you to specify the xsi:type of the object
      # being created. It's only necessary when you must provide an explicit
      # type that the client library can't infer.
      :xsi_type => 'BiddableAdGroupCriterion',
      :ad_group_id => ad_group_id,
      :criterion => {
        :id => criterion_id
      }
    }
  }

  # Remove keyword.
  response = ad_group_criterion_srv.mutate([operation])
  ad_group_criterion = response[:value].first
  if ad_group_criterion
    puts "Keyword ID %d was successfully removed." %
        ad_group_criterion[:criterion][:id]
  else
    puts 'No keywords were removed.'
  end
end

if __FILE__ == $0
  API_VERSION = :v201809

  begin
    # IDs of criterion to remove and its ad group.
    ad_group_id = 'INSERT_AD_GROUP_ID_HERE'.to_i
    criterion_id = 'INSERT_CRITERION_ID_HERE'.to_i
    remove_keyword(ad_group_id, criterion_id)

  # 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

Update an ad group

#!/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 illustrates how to update an ad group, setting its status to
# 'PAUSED'. To create an ad group, run add_ad_group.rb.

require 'adwords_api'

def update_ad_group(ad_group_id, cpc_bid_micro_amount)
  # 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')

  ad_group_srv = adwords.service(:AdGroupService, API_VERSION)

  # Create an ad group with the specified ID.
  ad_group = {
    :status => 'PAUSED',
    :id => ad_group_id
  }

  # Update the CPC bid if specified.
  unless cpc_bid_micro_amount.nil?
    ad_group[:bidding_strategy_configuration] = {
      :bids => [{
        :xsi_type => 'CpcBid',
        :bid => {
          :micro_amount => cpc_bid_micro_amount
        }
      }]
    }
  end

  operation = {
    :operator => 'SET',
    :operand => ad_group
  }

  # Update ad group.
  response = ad_group_srv.mutate([operation])
  if response and response[:value]
    ad_group = response[:value].first
    bidding_strategy_configuration = ad_group[:bidding_strategy_configuration]
    cpc_bid_micros = nil
    unless bidding_strategy_configuration.nil?
      unless bidding_strategy_configuration[:bids].nil?
        bidding_strategy_configuration[:bids].each do |bid|
          if bid[:xsi_type] == 'CpcBid'
            cpc_bid_micros = bid[:bid][:micro_amount]
          end
        end
      end
    end
    puts ('Ad group id %d and name "%s" updated to have status "%s" and CPC ' +
        'bid %d.') % [ad_group[:id], ad_group[:name], ad_group[:status],
        cpc_bid_micros]
  else
    puts 'No ad groups were updated.'
  end
end

if __FILE__ == $0
  API_VERSION = :v201809

  begin
    # ID of an ad group to update.
    ad_group_id = 'INSERT_AD_GROUP_ID_HERE'.to_i
    # Set this to nil if you do not want to update the CPC bid.
    cpc_bid_micro_amount = 'INSERT_CPC_BID_MICRO_AMOUNT_HERE'.to_i

    update_ad_group(ad_group_id, cpc_bid_micro_amount)

  # 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

Update a campaign

#!/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 illustrates how to update a campaign, setting its status to
# 'PAUSED'. To create a campaign, run add_campaigns.rb.

require 'adwords_api'

def update_campaign(campaign_id)
  # 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')

  campaign_srv = adwords.service(:CampaignService, API_VERSION)

  # Prepare for updating campaign.
  operation = {
    :operator => 'SET',
    :operand => {
      :id => campaign_id,
      :status => 'PAUSED'
    }
  }

  # Update campaign.
  response = campaign_srv.mutate([operation])
  if response and response[:value]
    campaign = response[:value].first
    puts "Campaign ID %d was successfully updated, status was set to '%s'." %
        [campaign[:id], campaign[:status]]
  else
    puts 'No campaigns were updated.'
  end
end

if __FILE__ == $0
  API_VERSION = :v201809

  begin
    # ID of a campaign to update.
    campaign_id = 'INSERT_CAMPAIGN_ID_HERE'.to_i
    update_campaign(campaign_id)

  # 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

Update an expanded text ad

#!/usr/bin/env ruby
# Encoding: utf-8
#
# Copyright 2018 Google LLC
#
# 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 updates an expanded text ad. To get expanded text ads, run
# get_expanded_text_ads.rb.

require 'adwords_api'

def update_expanded_text_ad(ad_id)
  # 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')

  ad_srv = adwords.service(:AdService, API_VERSION)

  # Updates an expanded text ad using the provided ad ID.
  trip_number = (Time.new.to_f * 1000).to_i
  # Creates an expanded text ad using the provided ad ID and updates some
  # properties of the expanded text ad.
  expanded_text_ad = {
    :id => ad_id,
    :xsi_type => 'ExpandedTextAd',
    :headline_part1 => 'Cruise to Mars #%d' % trip_number,
    :headline_part2 => 'Best Space Cruise Line',
    :description => 'Buy your tickets now!',
    :final_urls => ['http://www.example.com/%d' % trip_number],
    :final_mobile_urls => ['http://www.example.com/mobile/%d' % trip_number]
  }

  # Creates ad group ad operation.
  operation = {
    :operator => 'SET',
    :operand => expanded_text_ad
  }

  # Updates the ad on the server.
  response = ad_srv.mutate([operation])

  # Prints out some information.
  if response and response[:value]
    updated_ad = response[:value].first
    puts 'Expanded text ad with ID %d was successfully updated' %
        updated_ad[:id]
    puts ('Headline part 1 is "%s". Headline part 2 is "%s".' +
        ' Description is "%s".') %
        [updated_ad[:headline_part1],
        updated_ad[:headline_part2],
        updated_ad[:description]]
    puts 'Final URL is "%s". Final mobile URL is "%s".' %
        [updated_ad[:final_urls][0], updated_ad[:final_mobile_urls][0]]
  else
    raise StandardError, 'No ads were updated.'
  end
end

if __FILE__ == $0
  API_VERSION = :v201809

  begin
    # Ad ID to update.
    ad_id = 'INSERT_AD_ID_HERE'.to_i
    update_expanded_text_ad(ad_id)

  # 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

Update a keyword

#!/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 updates the bid of a keyword. To create a keyword, run
# add_keywords.rb.

require 'adwords_api'

def update_keyword(ad_group_id, criterion_id)
  # 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')

  ad_group_criterion_srv =
      adwords.service(:AdGroupCriterionService, API_VERSION)

  # Prepare for updating a keyword.
  operation = {
    :operator => 'SET',
    :operand => {
      # The 'xsi_type' field allows you to specify the xsi:type of the object
      # being created. It's only necessary when you must provide an explicit
      # type that the client library can't infer.
      :xsi_type => 'BiddableAdGroupCriterion',
      :ad_group_id => ad_group_id,
      :criterion => {
        :id => criterion_id
      },
      :bidding_strategy_configuration => {
        :bids => [
          {
            :xsi_type => 'CpcBid',
            :bid => {:micro_amount => 1000000}
          }
        ]
      }
    }
  }

  # Update criterion.
  response = ad_group_criterion_srv.mutate([operation])
  if response and response[:value]
    ad_group_criterion = response[:value].first
    puts "Keyword ID %d was successfully updated, current bids are:" %
        ad_group_criterion[:criterion][:id]
    ad_group_criterion[:bidding_strategy_configuration][:bids].each do |bid|
      puts "\tType: '%s', value: %d" %
          [bid[:bids_type], bid[:bid][:micro_amount]]
    end
  else
    puts 'No keywords were updated.'
  end
end

if __FILE__ == $0
  API_VERSION = :v201809

  begin
    # IDs of a criterion to update and its ad group.
    ad_group_id = 'INSERT_AD_GROUP_ID_HERE'.to_i
    criterion_id = 'INSERT_CRITERION_ID_HERE'.to_i
    update_keyword(ad_group_id, criterion_id)

  # 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

Send feedback about...

AdWords API
AdWords API
Need help? Visit our support page.