The code samples below provide examples of common extension functions using the AdWords API. Client Library.
Associate a Business Profile feed to that of a customer
#!/usr/bin/env ruby # Encoding: utf-8 # # Copyright:: Copyright 2014, 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 a feed that syncs feed items from a Google My Business (GMB) # account and associates the feed with a customer. require 'adwords_api' require 'date' def add_gmb_location_extensions(gmb_email_address, gmb_access_token, business_account_identifier) # 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') feed_srv = adwords.service(:FeedService, API_VERSION) customer_feed_srv = adwords.service(:CustomerFeedService, API_VERSION) if gmb_access_token.nil? gmb_access_token = adwords.get_auth_handler.get_token( adwords.credential_handler.credentials)[:access_token] end # Create a feed that will sync to the Google My Business account specified # by gmb_email_address. Do not add FeedAttributes to this object, as AdWords # will add them automatically because this will be a system generated feed. gmb_feed = { :name => "GMB feed #%d" % (Time.new.to_f * 1000).to_i, :system_feed_generation_data => { :xsi_type => 'PlacesLocationFeedData', :o_auth_info => { :http_method => 'GET', :http_request_url => 'https://www.googleapis.com/auth/adwords', :http_authorization_header => "Bearer %s" % gmb_access_token }, :email_address => gmb_email_address }, # Since this feed's feed items will be managed by AdWords, you must set # its origin to ADWORDS. :origin => 'ADWORDS' } # Optional: specify labels to filter Google My Business listings. If # specified, only listings that have any of the labels set are synchronized # into FeedItems. gmb_feed[:system_feed_generation_data][:label_filters] = ['Stores in New York City'] # Only include the business_account_identifier if it's specified. # A nil value will cause an invalid request. unless business_account_identifier.nil? gmb_feed[:system_feed_generation_data][:business_account_identifier] = business_account_identifier end gmb_operation = { :operator => 'ADD', :operand => gmb_feed } result = feed_srv.mutate([gmb_operation]) added_feed = result[:value].first puts "Added GMB feed with ID %d" % added_feed[:id] # Add a CustomerFeed that associates the feed with this customer for the # LOCATION placeholder type. customer_feed = { :feed_id => added_feed[:id], :placeholder_types => [PLACEHOLDER_TYPE_LOCATION], :matching_function => { :operator => 'IDENTITY', :lhs_operand => [{ :xsi_type => 'ConstantOperand', :type => 'BOOLEAN', :boolean_value => true }] } } customer_feed_operation = { :xsi_type => 'CustomerFeedOperation', :operator => 'ADD', :operand => customer_feed } added_customer_feed = nil number_of_attempts = 0 while i < MAX_CUSTOMER_FEED_ADD_ATTEMPTS && !added_customer_feed number_of_attempts += 1 begin result = customer_feed_srv.mutate([customer_feed_operation]) added_customer_feed = result[:value].first puts "Attempt #%d to add the CustomerFeed was successful" % number_of_attempts rescue sleep_seconds = 5 * (2 ** number_of_attempts) puts ("Attempt #%d to add the CustomerFeed was not succeessful. " + "Waiting %d seconds before trying again.") % [number_of_attempts, sleep_seconds] sleep(sleep_seconds) end end unless added_customer_feed raise StandardError, ("Could not create the CustomerFeed after %d " + "attempts. Please retry the CustomerFeed ADD operation later.") % MAX_CUSTOMER_FEED_ADD_ATTEMPTS end puts "Added CustomerFeed for feed ID %d and placeholder type %d" % [added_customer_feed[:id], added_customer_feed[:placeholder_types].first] # OPTIONAL: Create a CampaignFeed to specify which FeedItems to use at the # Campaign level. This will be similar to the CampaignFeed in the # add_site_links example, except you can filter based on the business name # and category of each FeedItem by using a FeedAttributeOperand in your # matching function. # OPTIONAL: Create an AdGroupFeed for even more fine grained control over # which feed items are used at the AdGroup level. end if __FILE__ == $0 API_VERSION = :v201809 PLACEHOLDER_TYPE_LOCATION = 7 MAX_CUSTOMER_FEED_ADD_ATTEMPTS = 10 begin # The email address of either an owner or a manager of the GMB account. gmb_email_address = 'INSERT_GMB_EMAIL_ADDRESS_HERE' # If the gmbEmailAddress above is the same as you used to generate your # AdWords API refresh token, leave the value below as nil. # Otherwise, to obtain an access token for your GMB account, generate a # refresh token as you did for AdWords, but make sure you are logged in as # the same user as gmb_email_address above when you follow the link, then # capture the generated access token gmb_access_token = nil # If the gmb_email_address above is for a GMB manager instead of # the GMB account owner, then set business_account_identifier to the # +Page ID of a location for which the manager has access. See the # location extensions guide at # https://developers.google.com/adwords/api/docs/guides/feed-services-locations # for details. business_account_identifier = nil add_gmb_location_extensions(gmb_email_address, gmb_access_token, business_account_identifier) # 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
Associate a price extension to an account
#!/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 a price extension and associates it with an account. # Campaign targeting is also set using the specified campaign ID. To get # campaigns, run basic_operations/get_campaigns.rb. require 'adwords_api' def add_prices(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') customer_extension_setting_srv = adwords.service(:CustomerExtensionSettingService, API_VERSION) price_feed_item = { :xsi_type => 'PriceFeedItem', :price_extension_type => 'SERVICES', # Price qualifier is optional. :price_qualifier => 'FROM', :tracking_url_template => 'http://tracker.example.com/?u={lpurl}', :language => 'en', :campaign_targeting => { :targeting_campaign_id => campaign_id }, :scheduling => { :feed_item_schedules => [ { :day_of_week => 'SUNDAY', :start_hour => 10, :start_minute => 'ZERO', :end_hour => 18, :end_minute => 'ZERO' }, { :day_of_week => 'SATURDAY', :start_hour => 10, :start_minute => 'ZERO', :end_hour => 22, :end_minute => 'ZERO' } ] }, # To create a price extension, at least three table rows are needed. :table_rows => [ create_price_table_row( 'Scrubs', 'Body Scrub, Salt Scrub', 'http://www.example.com/scrubs', 'http://m.example.com/scrubs', 60000000, 'USD', 'PER_HOUR' ), create_price_table_row( 'Hair Cuts', 'Once a month', 'http://www.example.com/haircuts', 'http://m.example.com/haircuts', 75000000, 'USD', 'PER_MONTH' ), create_price_table_row( 'Skin Care Package', 'Four times a month', 'http://www.example.com/skincarepackage', nil, 250000000, 'USD', 'PER_MONTH' ) ] } customer_extension_setting = { :extension_type => 'PRICE', :extension_setting => { :extensions => [price_feed_item] } } operation = { :operator => 'ADD', :operand => customer_extension_setting } result = customer_extension_setting_srv.mutate([operation]) new_extension_setting = result[:value].first puts "Extension setting with type '%s' was added to your account.\n" % new_extension_setting[:extension_type] end def create_price_table_row(header, description, final_url, final_mobile_url, price_in_micros, currency_code, price_unit) ret_val = { :header => header, :description => description, :final_urls => { :urls => [final_url] }, :price => { :money => { :micro_amount => price_in_micros }, :currency_code => currency_code }, :price_unit => price_unit } # Optional: Set the mobile final URLs. unless final_mobile_url.nil? or final_mobile_url.empty? ret_val[:final_mobile_urls] = {:urls => [final_mobile_url]} end end if __FILE__ == $0 API_VERSION = :v201809 begin # Campaign ID to add site link to. campaign_id = 'INSERT_CAMPAIGN_ID_HERE'.to_i add_prices(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 sitelinks to a campaign
#!/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 adds a sitelinks feed and associates it with a campaign. require 'adwords_api' require 'date' def add_site_links(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') customer_srv = adwords.service(:CustomerService, API_VERSION) # Find the matching customer and its time zone. The get_customers method will # return a single customer corresponding to the configured client_customer_id. customer = customer_srv.get_customers().first customer_time_zone = customer[:date_time_zone] puts 'Found customer ID %d with time zone "%s"' % [customer[:customer_id], customer_time_zone] if customer_time_zone.nil? raise StandardError, 'Customer not found for customer ID: ' + customer_id end campaign_extension_setting_srv = adwords.service(:CampaignExtensionSettingService, API_VERSION) sitelink_1 = { :xsi_type => "SitelinkFeedItem", :sitelink_text => "Store Hours", :sitelink_final_urls => { :urls => ["http://www.example.com/storehours"] } } sitelink_2 = { :xsi_type => "SitelinkFeedItem", :sitelink_text => "Thanksgiving Specials", :sitelink_final_urls => { :urls => ["http://www.example.com/thanksgiving"] }, :start_time => DateTime.new(Date.today.year, 11, 20, 0, 0, 0). strftime("%Y%m%d %H%M%S ") + customer_time_zone, :end_time => DateTime.new(Date.today.year, 11, 27, 23, 59, 59). strftime("%Y%m%d %H%M%S ") + customer_time_zone, # Target this sitelink for United States only. See # https://developers.google.com/adwords/api/docs/appendix/geotargeting # for valid geolocation codes. :geo_targeting => { :id => 2840 }, # Restrict targeting only to people physically within the United States. # Otherwise, this could also show to people interested in the United States # but not physically located there. :geo_targeting_restriction => { :geo_restriction => 'LOCATION_OF_PRESENCE' } } sitelink_3 = { :xsi_type => "SitelinkFeedItem", :sitelink_text => "Wifi available", :sitelink_final_urls => { :urls => ["http://www.example.com/mobile/wifi"] }, :device_preference => {:device_preference => 30001}, # Target this sitelink only when the ad is triggered by the keyword # "free wifi". :keyword_targeting => { :text => "free wifi", :match_type => 'BROAD' } } sitelink_4 = { :xsi_type => "SitelinkFeedItem", :sitelink_text => "Happy hours", :sitelink_final_urls => { :urls => ["http://www.example.com/happyhours"] }, :scheduling => { :feed_item_schedules => [ { :day_of_week => 'MONDAY', :start_hour => 18, :start_minute => 'ZERO', :end_hour => 21, :end_minute => 'ZERO' }, { :day_of_week => 'TUESDAY', :start_hour => 18, :start_minute => 'ZERO', :end_hour => 21, :end_minute => 'ZERO' }, { :day_of_week => 'WEDNESDAY', :start_hour => 18, :start_minute => 'ZERO', :end_hour => 21, :end_minute => 'ZERO' }, { :day_of_week => 'THURSDAY', :start_hour => 18, :start_minute => 'ZERO', :end_hour => 21, :end_minute => 'ZERO' }, { :day_of_week => 'FRIDAY', :start_hour => 18, :start_minute => 'ZERO', :end_hour => 21, :end_minute => 'ZERO' } ] } } campaign_extension_setting = { :campaign_id => campaign_id, :extension_type => 'SITELINK', :extension_setting => { :extensions => [sitelink_1, sitelink_2, sitelink_3, sitelink_4] } } operation = { :operand => campaign_extension_setting, :operator => 'ADD' } response = campaign_extension_setting_srv.mutate([operation]) if response and response[:value] new_extension_setting = response[:value].first puts "Extension setting with type = %s was added to campaign ID %d" % [ new_extension_setting[:extension_type], new_extension_setting[:campaign_id] ] elsif puts "No extension settings were created." end end if __FILE__ == $0 API_VERSION = :v201809 begin # Campaign ID to add site link to. campaign_id = 'INSERT_CAMPAIGN_ID_HERE'.to_i add_site_links(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 sitelinks to a campaign using feeds
#!/usr/bin/env ruby # Encoding: utf-8 # # Copyright:: Copyright 2013, 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 a sitelinks feed and associates it with a campaign. require 'adwords_api' def add_site_links(campaign_id, 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') feed_srv = adwords.service(:FeedService, API_VERSION) feed_item_srv = adwords.service(:FeedItemService, API_VERSION) feed_item_target_srv = adwords.service(:FeedItemTargetService, API_VERSION) feed_mapping_srv = adwords.service(:FeedMappingService, API_VERSION) campaign_feed_srv = adwords.service(:CampaignFeedService, API_VERSION) sitelinks_data = {} # Create site links feed first. site_links_feed = { :name => 'Feed For Site Links', :attributes => [ {:type => 'STRING', :name => 'Link Text'}, {:type => 'URL_LIST', :name => 'Final URLs'}, {:type => 'STRING', :name => 'Line 2 Description'}, {:type => 'STRING', :name => 'Line 3 Description'} ] } response = feed_srv.mutate([ {:operator => 'ADD', :operand => site_links_feed} ]) unless response.nil? || response[:value].nil? feed = response[:value].first # Attribute of type STRING. link_text_feed_attribute_id = feed[:attributes][0][:id] # Attribute of type URL_LIST. final_url_feed_attribute_id = feed[:attributes][1][:id] # Attribute of type STRING. line_2_feed_attribute_id = feed[:attributes][2][:id] # Attribute of type STRING. line_3_feed_attribute_id = feed[:attributes][3][:id] puts "Feed with name '%s' and ID %d was added with" % [feed[:name], feed[:id]] puts ("\tText attribute ID %d and Final URLs attribute ID %d " + "and Line 2 attribute ID %d and Line 3 attribute ID %d.") % [ link_text_feed_attribute_id, final_url_feed_attribute_id, line_2_feed_attribute_id, line_3_feed_attribute_id ] sitelinks_data[:feed_id] = feed[:id] sitelinks_data[:link_text_feed_id] = link_text_feed_attribute_id sitelinks_data[:final_url_feed_id] = final_url_feed_attribute_id sitelinks_data[:line_2_feed_id] = line_2_feed_attribute_id sitelinks_data[:line_3_feed_id] = line_3_feed_attribute_id else raise new StandardError, 'No feeds were added.' end # Create site links feed items. items_data = [ { :text => 'Home', :final_urls => ['http://www.example.com'], :line_2 => 'Home line 2', :line_3 => 'Home line 3' }, { :text => 'Stores', :final_urls => ['http://www.example.com/stores'], :line_2 => 'Stores line 2', :line_3 => 'Stores line 3' }, { :text => 'On Sale', :final_urls => ['http://www.example.com/sale'], :line_2 => 'On Sale line 2', :line_3 => 'On Sale line 3' }, { :text => 'Support', :final_urls => ['http://www.example.com/support'], :line_2 => 'Support line 2', :line_3 => 'Support line 3' }, { :text => 'Products', :final_urls => ['http://www.example.com/products'], :line_2 => 'Products line 2', :line_3 => 'Products line 3' }, { :text => 'About Us', :final_urls => ['http://www.example.com/about'], :line_2 => 'About line 2', :line_3 => 'About line 3' } ] feed_items = items_data.map do |item| { :feed_id => sitelinks_data[:feed_id], :attribute_values => [ { :feed_attribute_id => sitelinks_data[:link_text_feed_id], :string_value => item[:text] }, { :feed_attribute_id => sitelinks_data[:final_url_feed_id], :string_values => item[:final_urls] }, { :feed_attribute_id => sitelinks_data[:line_2_feed_id], :string_value => item[:line_2] }, { :feed_attribute_id => sitelinks_data[:line_3_feed_id], :string_value => item[:line_3] } ] } end # The "About us" site link is using geographical targeting to use # LOCATION_OF_PRESENCE. feed_items.last[:geo_targeting_restriction] = { :geo_restriction => 'LOCATION_OF_PRESENCE' } feed_items_operations = feed_items.map do |item| {:operator => 'ADD', :operand => item} end response = feed_item_srv.mutate(feed_items_operations) unless response.nil? || response[:value].nil? sitelinks_data[:feed_item_ids] = [] response[:value].each do |feed_item| puts 'Feed item with ID %d was added.' % feed_item[:feed_item_id] sitelinks_data[:feed_item_ids] << feed_item[:feed_item_id] end else raise new StandardError, 'No feed items were added.' end # Target the "About Us" sitelink to geographically target California. # See https://developers.google.com/adwords/api/docs/appendix/geotargeting # for location criteria for supported locations. criterion_target = { :xsi_type => 'FeedItemCriterionTarget', :feed_id => feed_items[5][:feed_id], :feed_item_id => sitelinks_data[:feed_item_ids][5], :criterion => { :xsi_type => 'Location', :id => 21137 # California } } retval = feed_item_target_srv.mutate([{ :operator => 'ADD', :operand => criterion_target }]) new_location_target = retval[:value].first puts ('Feed item target for feed ID %d and feed item ID %d was created to' + 'restrict serving to location ID %d.') % [new_location_target[:feed_id], new_location_target[:feed_item_id], new_location_target[:criterion][:id]] # Create site links feed mapping. feed_mapping = { :placeholder_type => PLACEHOLDER_SITELINKS, :feed_id => sitelinks_data[:feed_id], :attribute_field_mappings => [ { :feed_attribute_id => sitelinks_data[:link_text_feed_id], :field_id => PLACEHOLDER_FIELD_SITELINK_LINK_TEXT }, { :feed_attribute_id => sitelinks_data[:final_url_feed_id], :field_id => PLACEHOLDER_FIELD_SITELINK_FINAL_URLS }, { :feed_attribute_id => sitelinks_data[:line_2_feed_id], :field_id => PLACEHOLDER_FIELD_SITELINK_LINE_2_TEXT }, { :feed_attribute_id => sitelinks_data[:line_3_feed_id], :field_id => PLACEHOLDER_FIELD_SITELINK_LINE_3_TEXT } ] } response = feed_mapping_srv.mutate([ {:operator => 'ADD', :operand => feed_mapping} ]) unless response.nil? || response[:value].nil? feed_mapping = response[:value].first puts ('Feed mapping with ID %d and placeholder type %d was saved for feed' + ' with ID %d.') % [ feed_mapping[:feed_mapping_id], feed_mapping[:placeholder_type], feed_mapping[:feed_id] ] else raise new StandardError, 'No feed mappings were added.' end # Construct a matching function that associates the sitelink feeditems to the # campaign, and set the device preference to Mobile. See the matching function # guide at: # https://developers.google.com/adwords/api/docs/guides/feed-matching-functions # for more details. matching_function_string = "AND(IN(FEED_ITEM_ID, {%s}), EQUALS(CONTEXT.DEVICE, 'Mobile'))" % sitelinks_data[:feed_item_ids].join(',') # Create site links campaign feed. campaign_feed = { :feed_id => sitelinks_data[:feed_id], :campaign_id => campaign_id, :matching_function => {:function_string => matching_function_string}, # Specifying placeholder types on the CampaignFeed allows the same feed # to be used for different placeholders in different Campaigns. :placeholder_types => [PLACEHOLDER_SITELINKS] } response = campaign_feed_srv.mutate([ {:operator => 'ADD', :operand => campaign_feed} ]) unless response.nil? || response[:value].nil? campaign_feed = response[:value].first puts 'Campaign with ID %d was associated with feed with ID %d.' % [campaign_feed[:campaign_id], campaign_feed[:feed_id]] else raise new StandardError, 'No campaign feeds were added.' end # Optional: Restrict the first feed item to only serve with ads for the # specified ad group ID. if !ad_group_id.nil? && ad_group_id != 0 feed_item_target = { :xsi_type => 'FeedItemAdGroupTarget', :feed_id => sitelinks_data[:feed_id], :feed_item_id => sitelinks_data[:feed_item_ids].first, :ad_group_id => ad_group_id } operation = { :operator => 'ADD', :operand => feed_item_target } response = feed_item_target_srv.mutate([operation]) unless response.nil? || response[:value].nil? feed_item_target = response[:value].first puts ('Feed item target for feed ID %d and feed item ID %d' + ' was created to restrict serving to ad group ID %d') % [feed_item_target[:feed_id], feed_item_target[:feed_item_id], feed_item_target[:ad_group_id]] end end end if __FILE__ == $0 API_VERSION = :v201809 # See the Placeholder reference page for a list of all the placeholder types # and fields, see: # https://developers.google.com/adwords/api/docs/appendix/placeholders PLACEHOLDER_SITELINKS = 1 PLACEHOLDER_FIELD_SITELINK_LINK_TEXT = 1 PLACEHOLDER_FIELD_SITELINK_FINAL_URLS = 5 PLACEHOLDER_FIELD_SITELINK_LINE_2_TEXT = 3 PLACEHOLDER_FIELD_SITELINK_LINE_3_TEXT = 4 begin # Campaign ID to add site link to. campaign_id = 'INSERT_CAMPAIGN_ID_HERE'.to_i # Optional: Ad group to restrict targeting to. ad_group_id = 'INSERT_AD_GROUP_ID_HERE'.to_i add_site_links(campaign_id, 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