Skip to content

Commit

Permalink
Adding support for v9. (#358)
Browse files Browse the repository at this point in the history
Change-Id: I231a9d5f30a210b3e94e4988512f4c48d46d8363
  • Loading branch information
mcloonan authored Nov 11, 2021
1 parent d9661bd commit 605e5b5
Show file tree
Hide file tree
Showing 1,535 changed files with 143,883 additions and 536 deletions.
3 changes: 3 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
15.0.0:
- Compatibility with v9.0 of the API: https://developers.google.com/google-ads/api/docs/release-notes

14.0.0:
- Compatibility with v8.1 of the API: https://developers.google.com/google-ads/api/docs/release-notes
- Removed support for v6.
Expand Down
3 changes: 3 additions & 0 deletions codegen/templates/services.rb.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'google/ads/google_ads/service_wrapper'
require 'google/ads/google_ads/version'
module Google
module Ads
module GoogleAds
Expand Down Expand Up @@ -36,6 +37,8 @@ module Google
config.interceptors = @interceptors
config.metadata = @metadata
config.endpoint = @endpoint
config.lib_name = Google::Ads::GoogleAds::CLIENT_LIB_NAME
config.lib_version = Google::Ads::GoogleAds::CLIENT_LIB_VERSION
end,
rpc_inputs: {
<% service.rpc_names.each do |rpc_name| %>
Expand Down
5 changes: 3 additions & 2 deletions examples/advanced_operations/add_app_campaign.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,9 @@ def create_campaign(client, customer_id, budget_resource_name)
# manual_cpc, commission, maximize_conversions, etc.
# See https://developers.google.com/google-ads/api/reference/rpc
# under current version / resources / Campaign
c.target_cpa = Google::Ads::GoogleAds::V8::Common::TargetCpa.new
c.target_cpa.target_cpa_micros = 1_000_000
c.target_cpa = client.resource.target_cpa do |tcpa|
tcpa.target_cpa_micros = 1_000_000
end
# Sets the App Campaign Settings.
c.app_campaign_setting = client.resource.app_campaign_setting do |acs|
acs.app_id = 'com.google.android.apps.adwords'
Expand Down
5 changes: 3 additions & 2 deletions examples/advanced_operations/add_local_campaign.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@ def create_campaign(client, customer_id, budget_resource_name)
# the API. It is calculated by dividing "total value" by "total spend".
# For more information on maximize conversion value, see the support article:
# http://support.google.com/google-ads/answer/7684216.
c.maximize_conversion_value = Google::Ads::GoogleAds::V8::Common::MaximizeConversionValue.new
c.maximize_conversion_value.target_roas = 3.5
c.maximize_conversion_value = client.resource.maximize_conversion_value do |mcv|
mcv.target_roas = 3.5
end
# Configures the Local campaign setting.
c.local_campaign_setting = client.resource.local_campaign_setting do |lcs|
# Use the locations associated with the customer's linked
Expand Down
163 changes: 139 additions & 24 deletions examples/advanced_operations/add_smart_campaign.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,63 @@
def add_smart_campaign(
customer_id,
keyword_text,
freeform_keyword_text,
business_location_id,
business_name)
# GoogleAdsClient will read a config file from
# ENV['HOME']/google_ads_config.rb when called without parameters
client = Google::Ads::GoogleAds::GoogleAdsClient.new

keyword_theme_constants = get_keyword_theme_constants(client, keyword_text)

keyword_theme_infos = map_keyword_theme_constants_to_infos(
client, keyword_theme_constants)

# [START add_smart_campaign_12]
# The SmartCampaignSuggestionInfo object acts as the basis for many of the
# entities necessary to create a Smart campaign. It will be reused a number
# of times to retrieve suggestions for keyword themes, budget amount,
# ad creatives, and campaign criteria.
suggestion_info = get_smart_campaign_suggestion_info(
client,
business_location_id,
business_name,
keyword_theme_infos,
)

# After creating a SmartCampaignSuggestionInfo object we first use it to
# generate a list of keyword themes using the SuggestKeywordThemes method
# on the SmartCampaignSuggestService. It is strongly recommended that you
# use this strategy for generating keyword themes.
keyword_theme_constants = get_keyword_theme_suggestions(
client,
customer_id,
suggestion_info,
)

# If a keyword text is given retrieve keyword theme constant suggestions
# from the KeywordThemeConstantService and append them to the existing list.
if keyword_text
keyword_theme_constants += get_keyword_text_auto_completions(
client,
keyword_text,
)
end

# Map the KeywordThemeConstants retrieved by the previous two steps to
# KeywordThemeInfo instances.
keyword_theme_infos = map_keyword_theme_constants_to_infos(
client,
keyword_theme_constants,
)

# If a free-form keyword text is given we create a KeywordThemeInfo instance
# from it and add it to the existing list.
if freeform_keyword_text
keyword_theme_infos << get_freeform_keyword_theme_info(
client,
freeform_keyword_text,
)
end

# Now add the generated keyword themes to the suggestion info instance.
suggestion_info.keyword_themes += keyword_theme_infos
# [END add_smart_campaign_12]

suggested_budget_amount = get_budget_suggestion(
client,
customer_id,
Expand Down Expand Up @@ -109,9 +151,20 @@ def add_smart_campaign(
# [END add_smart_campaign_7]
end

def get_keyword_theme_suggestions(client, customer_id, suggestion_info)
response = client.service.smart_campaign_suggest.suggest_keyword_themes(
customer_id: customer_id,
suggestion_info: suggestion_info,
)

puts "Retrieved #{response.keyword_themes.size} keyword theme constant" \
" suggestions from SuggestKeywordThemes service."
return response.keyword_themes
end

# [START add_smart_campaign]
# Retrieves keyword_theme_constants for the given criteria.
def get_keyword_theme_constants(client, keyword_text)
def get_keyword_text_auto_completions(client, keyword_text)
response = client.service.keyword_theme_constant.suggest_keyword_theme_constants(
query_text: keyword_text,
country_code: COUNTRY_CODE,
Expand All @@ -125,6 +178,14 @@ def get_keyword_theme_constants(client, keyword_text)
end
# [END add_smart_campaign]

# [START add_smart_campaign_13]
def get_freeform_keyword_theme_info(client, freeform_keyword_text)
client.resource.keyword_theme_info do |kti|
kti.free_form_keyword_name = freeform_keyword_text
end
end
# [END add_smart_campaign_13]

# Maps a list of keyword_theme_constants to keyword_theme_infos.
def map_keyword_theme_constants_to_infos(client, keyword_theme_constants)
infos = []
Expand All @@ -149,8 +210,7 @@ def map_keyword_theme_constants_to_infos(client, keyword_theme_constants)
def get_smart_campaign_suggestion_info(
client,
business_location_id,
business_name,
keyword_theme_infos)
business_name)

# Since these suggestions are for a new campaign, we're going to
# use the suggestion_info field instead.
Expand Down Expand Up @@ -186,12 +246,10 @@ def get_smart_campaign_suggestion_info(
li.geo_target_constant = client.path.geo_target_constant(GEO_TARGET_CONSTANT)
end
end
# Adds the keyword_theme_info objects to the suggestion_info object.
si.keyword_themes += keyword_theme_infos
# Set either of the business_location_id or business_name, depending on
# whichever is provided.
if business_location_id
si.business_location_id = business_location_id.to_i
si.business_location_id = convert_business_location_id(business_location_id.to_i)
else
si.business_context = client.resource.business_context do |bc|
bc.business_name = business_name
Expand All @@ -218,6 +276,29 @@ def get_smart_campaign_suggestion_info(
end
# [END add_smart_campaign_9]

# The business location ID is an unsigned 64-bit integer. However, the API
# expects a signed 64-bit integer. This means that for business location IDs
# that are too large, we have to do some extra steps to convert it to a form
# the API can understand.
# Specifically, we perform the two's complement. Since Ruby supports arbitrary
# precision numbers, we have to calculate it manually.
LONG_MAX = 2 ** 63
ULONG_MAX = LONG_MAX * 2
def convert_business_location_id(business_location_id)
if business_location_id > ULONG_MAX
raise "Business location id #{business_location_id} is too large. Maximium " \
"value is #{ULONG_MAX}."
end
# Action only needs to be taken if the most significant bit is set.
if business_location_id > LONG_MAX
# Perform the two's complement.
-1 * (ULONG_MAX - business_location_id)
else
# For all other cases, the normal representation is fine.
business_location_id
end
end

# [START add_smart_campaign_1]
# Retrieves a suggested budget amount for a new budget.
#
Expand Down Expand Up @@ -271,6 +352,9 @@ def get_ad_suggestions(client, customer_id, suggestion_info)
# review them and filter out any empty values.
ad_suggestions = response.ad_info

# If there are no suggestions, the response will be blank.
return nil if ad_suggestions.nil?

puts 'The following headlines were suggested:'
ad_suggestions.headlines.each do |headline|
puts "\t#{headline.text || '<None>'}"
Expand Down Expand Up @@ -369,7 +453,7 @@ def create_smart_campaign_setting_operation(
# It's required that either a business location ID or a business name is
# added to the smart_campaign_setting.
if business_location_id
scs.business_location_id = business_location_id.to_i
scs.business_location_id = convert_business_location_id(business_location_id.to_i)
else
scs.business_name = business_name
end
Expand Down Expand Up @@ -449,11 +533,28 @@ def create_ad_group_ad_operation(client, customer_id, ad_suggestions)
# method. It's recommended that users review and approve or update these
# creatives before they're set on the ad. It's possible that some or all of
# these assets may contain empty texts, which should not be set on the ad
# and instead should be replaced with meaninful texts from the user. Below
# and instead should be replaced with meaningful texts from the user. Below
# we just accept the creatives that were suggested while filtering out empty
# assets, but individual workflows will vary here.
sca.headlines += ad_suggestions.headlines.filter(&:text)
sca.descriptions += ad_suggestions.descriptions.filter(&:text)
# assets. If no headlines or descriptions were suggested, then we manually
# add some, otherwise this operation will generate an INVALID_ARGUMENT
# error. Individual workflows will likely vary here.
sca.headlines += ad_suggestions.headlines.filter(&:text) if ad_suggestions
if sca.headlines.size < REQUIRED_NUM_HEADLINES
(REQUIRED_NUM_HEADLINES - sca.headlines.size).times do |i|
sca.headlines << client.resource.ad_text_asset do |asset|
asset.text = "placeholder headline #{i}"
end
end
end

sca.descriptions += ad_suggestions.descriptions.filter(&:text) if ad_suggestions
if sca.descriptions.size < REQUIRED_NUM_DESCRIPTIONS
(REQUIRED_NUM_DESCRIPTIONS - sca.descriptions.size).times do |i|
sca.descriptions << client.resource.ad_text_asset do |asset|
asset.text = "placeholder description #{i}"
end
end
end
end
end
end
Expand Down Expand Up @@ -492,7 +593,6 @@ def print_response_details(response)
end

if __FILE__ == $0
DEFAULT_KEYWORD = "travel"
# Geo target constant for New York City.
GEO_TARGET_CONSTANT = "1023191"
# Country code is a two-letter ISO-3166 code, for a list of all codes see:
Expand All @@ -506,6 +606,10 @@ def print_response_details(response)
BUDGET_TEMPORARY_ID = "-1"
SMART_CAMPAIGN_TEMPORARY_ID = "-2"
AD_GROUP_TEMPORARY_ID = "-3"
# These define the minimum number of headlines and descriptions that are
# required to create an AdGroupAd in a Smart campaign.
REQUIRED_NUM_HEADLINES = 3
REQUIRED_NUM_DESCRIPTIONS = 2

options = {}

Expand All @@ -518,8 +622,6 @@ def print_response_details(response)
#
# Running the example with -h will print the command line usage.
options[:customer_id] = 'INSERT_CUSTOMER_ID_HERE'
options[:keyword_text] = DEFAULT_KEYWORD


OptionParser.new do |opts|
opts.banner = sprintf('Usage: %s [options]', File.basename(__FILE__))
Expand All @@ -532,12 +634,24 @@ def print_response_details(response)
end

opts.on('-k', '--keyword-text KEYWORD-TEXT', String,
'A keyword text used to generate a set of keyword themes, which ' \
' are used to improve the budget suggestion and performance of the' \
' Smart campaign') do |v|
'A keyword text used to retrieve keyword theme constant ' \
'suggestions from the KeywordThemeConstantService. These keyword ' \
'theme suggestions are generated using auto-completion data for ' \
'the given text and may help improve the performance of ' \
'the Smart campaign.') do |v|
options[:keyword_text] = v
end

opts.on('-f', '--freeform-keyword-text FREEFORM-KEYWORD-TEXT', String,
'A keyword text used to create a freeform keyword theme, which is ' \
'entirely user-specified and not derived from any suggestion ' \
'service. Using free-form keyword themes is typically not ' \
'recommended because they are less effective than suggested ' \
'keyword themes, however they are useful in situations where a ' \
'very specific term needs to be targeted.') do |v|
options[:freeform_keyword_text] = v
end

opts.on('-b', '--business-location-id BUSINESS-LOCATION-ID', String,
'The ID of a Google My Business (GMB) location. This is required' \
' if a business name is not provided. It can be retrieved using the' \
Expand All @@ -564,7 +678,8 @@ def print_response_details(response)
begin
add_smart_campaign(
options.fetch(:customer_id).tr("-", ""),
options.fetch(:keyword_text),
options[:keyword_text],
options[:freeform_keyword_text],
options[:business_location_id],
options[:business_name],
)
Expand Down
5 changes: 3 additions & 2 deletions examples/advanced_operations/add_smart_display_ad.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ def create_smart_display_campaign(client, customer_id, budget)
# 'DISPLAY_SMART_CAMPAIGN'.
c.advertising_channel_sub_type = :DISPLAY_SMART_CAMPAIGN
# Smart Display campaign requires the TargetCpa bidding strategy.
c.target_cpa = Google::Ads::GoogleAds::V8::Common::TargetCpa.new
c.target_cpa.target_cpa_micros = 5_000_000
c.target_cpa = client.resource.target_cpa do |tcpa|
tcpa.target_cpa_micros = 5_000_000
end
c.campaign_budget = budget
# Optional: Sets the start and end dates for the campaign, beginning one day
# from now and ending a month from now.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def create_bidding_strategy(client, manager_customer_id)
# [START set_currency_code]
operation = client.operation.create_resource.bidding_strategy do |b|
b.name = "Maximize Clicks ##{(Time.new.to_f * 1000).to_i}"
b.target_spend = Google::Ads::GoogleAds::V8::Common::TargetSpend.new
b.target_spend = client.resource.target_spend
# Sets the currency of the new bidding strategy. If not provided, the
# bidding strategy uses the manager account's default currency.
b.currency_code = "USD"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ def use_portfolio_bidding_strategy(customer_id)
# Create a portfolio bidding strategy.
bidding_strategy = client.resource.bidding_strategy do |bs|
bs.name = "Enhanced CPC ##{(Time.new.to_f * 1000).to_i}"
bs.target_spend = Google::Ads::GoogleAds::V8::Common::TargetSpend.new
bs.target_spend.cpc_bid_ceiling_micros = 2_000_000
bs.target_spend = client.resource.target_spend do |ts|
ts.cpc_bid_ceiling_micros = 2_000_000
end
end

operation = client.operation.create_resource.bidding_strategy(bidding_strategy)
Expand Down
Loading

0 comments on commit 605e5b5

Please sign in to comment.