#!/usr/bin/perl -w
#
# Copyright 2021, Google LLC
#
# 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
#
#
# 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 shows how to create a Smart campaign.
#
# More details on Smart campaigns can be found here:
use strict;
use utf8;
use FindBin qw($Bin);
use lib "$Bin/../../lib";
use
Google::Ads::GoogleAds::V10::Services::CampaignBudgetService::CampaignBudgetOperation;
use
Google::Ads::GoogleAds::V10::Services::CampaignCriterionService::CampaignCriterionOperation;
use
Google::Ads::GoogleAds::V10::Services::KeywordThemeConstantService::SuggestKeywordThemeConstantsRequest;
use
Google::Ads::GoogleAds::V10::Services::SmartCampaignSettingService::SmartCampaignSettingOperation;
use
Google::Ads::GoogleAds::V10::Services::SmartCampaignSuggestService::BusinessContext;
use
Google::Ads::GoogleAds::V10::Services::SmartCampaignSuggestService::LocationList;
use
Google::Ads::GoogleAds::V10::Services::SmartCampaignSuggestService::SmartCampaignSuggestionInfo;
use
Google::Ads::GoogleAds::V10::Services::SmartCampaignSuggestService::SuggestKeywordThemesRequest;
use
Google::Ads::GoogleAds::V10::Services::SmartCampaignSuggestService::SuggestSmartCampaignAdRequest;
use
Google::Ads::GoogleAds::V10::Services::SmartCampaignSuggestService::SuggestSmartCampaignBudgetOptionsRequest;
use Getopt::Long qw(:config auto_help);
use Cwd qw(abs_path);
use Data::Uniqid qw(uniqid);
# Geo target constant for New York City.
use constant GEO_TARGET_CONSTANT => 1023191;
# Country code is a two-letter ISO-3166 code, for a list of all codes see:
use constant COUNTRY_CODE => "US";
# For a list of all language codes, see:
use constant LANGUAGE_CODE => "en";
use constant LANDING_PAGE_URL => "http://www.example.com";
use constant PHONE_NUMBER => "555-555-5555";
use constant BUDGET_TEMPORARY_ID => -1;
use constant SMART_CAMPAIGN_TEMPORARY_ID => -2;
use constant 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.
use constant REQUIRED_NUM_HEADLINES => 3;
use constant REQUIRED_NUM_DESCRIPTIONS => 2;
use constant _64_BIT_RANGE_CEILING => 2**64;
use constant _SIGNED_64_BIT_RANGE_CEILING => 2**63;
# The following parameter(s) should be provided to run the example. You can
# either specify these by changing the INSERT_XXX_ID_HERE values below, or on
# the command line.
#
# Parameters passed on the command line will override any parameters set in
# code.
#
# Running the example with -h will print the command line usage.
my $customer_id = "INSERT_CUSTOMER_ID_HERE";
my $keyword_text = undef;
my $freeform_keyword_text = undef;
my $business_location_id = undef;
my $business_name = undef;
sub add_smart_campaign {
my ($api_client, $customer_id, $keyword_text, $freeform_keyword_text,
$business_location_id, $business_name)
= @_;
# [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.
my $suggestion_info =
_get_smart_campaign_suggestion_info($business_location_id, $business_name);
# 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.
my $keyword_theme_constants =
_get_keyword_theme_suggestions($api_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 (defined $keyword_text) {
push @$keyword_theme_constants,
@{_get_keyword_text_auto_completions($api_client, $keyword_text)};
}
# Map the KeywordThemeConstants retrieved by the previous two steps to
# KeywordThemeInfo instances.
my $keyword_theme_infos =
_map_keyword_theme_constants_to_infos($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 (defined $freeform_keyword_text) {
push @$keyword_theme_infos,
_get_freeform_keyword_theme_info($freeform_keyword_text);
}
# Now add the generated keyword themes to the suggestion info instance.
$suggestion_info->{keywordThemes} = $keyword_theme_infos;
# [END add_smart_campaign_12]
# Retrieve a budget amount suggestion.
my $suggested_budget_amount =
_get_budget_suggestion($api_client, $customer_id, $suggestion_info);
# Retrieve Smart campaign ad creative suggestions.
my $ad_suggestions =
_get_ad_suggestions($api_client, $customer_id, $suggestion_info);
# [START add_smart_campaign_7]
# The below methods create and return MutateOperations that we later provide to the
# GoogleAdsService.Mutate method in order to create the entities in a single
# request. Since the entities for a Smart campaign are closely tied to one-another
# it's considered a best practice to create them in a single Mutate request; the
# entities will either all complete successfully or fail entirely, leaving no
# orphaned entities. See:
my $campaign_budget_operation =
_create_campaign_budget_operation($customer_id, $suggested_budget_amount);
my $smart_campaign_operation = _create_smart_campaign_operation($customer_id);
my $smart_campaign_setting_operation =
_create_smart_campaign_setting_operation($customer_id,
$business_location_id, $business_name);
my $campaign_criterion_operations =
_create_campaign_criterion_operations($customer_id, $keyword_theme_infos,
$suggestion_info);
my $ad_group_operation = _create_ad_group_operation($customer_id);
my $ad_group_ad_operation =
_create_ad_group_ad_operation($customer_id, $ad_suggestions);
# It's important to create these entities in this order because they depend on
# each other. For example, the SmartCampaignSetting and ad group depend on the
# campaign and the ad group ad depends on the ad group.
my $mutate_operations = [
$campaign_budget_operation, $smart_campaign_operation,
$smart_campaign_setting_operation,
# Expand the list of campaign criterion operations into the list of
# other mutate operations.
@$campaign_criterion_operations,
$ad_group_operation, $ad_group_ad_operation
];
# Send the operations in a single mutate request.
my $mutate_google_ads_response = $api_client->GoogleAdsService()->mutate({
customerId => $customer_id,
mutateOperations => $mutate_operations
});
_print_response_details($mutate_google_ads_response);
# [END add_smart_campaign_7]
return 1;
}
# [START add_smart_campaign_11]
# Retrieves KeywordThemeConstants using the given suggestion info.
# Here we use the SuggestKeywordThemes method, which uses all of the business
# details included in the given SmartCampaignSuggestionInfo instance to generate
# keyword theme suggestions. This is the recommended way to generate keyword themes
# because it uses detailed information about your business, its location, and
# website content to generate keyword themes.
sub _get_keyword_theme_suggestions {
my ($api_client, $customer_id, $suggestion_info) = @_;
my $response =
$api_client->SmartCampaignSuggestService()->suggest_keyword_themes(
Google::Ads::GoogleAds::V10::Services::SmartCampaignSuggestService::SuggestKeywordThemesRequest
->new({
customerId => $customer_id,
suggestionInfo => $suggestion_info
}));
printf "Retrieved %d keyword theme constant suggestions " .
"from the SuggestKeywordThemes method.\n",
scalar @{$response->{keywordThemes}};
return $response->{keywordThemes};
}
# [END add_smart_campaign_11]
# [START add_smart_campaign]
# Retrieves KeywordThemeConstants for the given keyword text.
# These KeywordThemeConstants are derived from autocomplete data for the given
# keyword text.
sub _get_keyword_text_auto_completions {
my ($api_client, $keyword_text) = @_;
my $response = $api_client->KeywordThemeConstantService()->suggest(
Google::Ads::GoogleAds::V10::Services::KeywordThemeConstantService::SuggestKeywordThemeConstantsRequest
->new({
queryText => $keyword_text,
countryCode => COUNTRY_CODE,
languageCode => LANGUAGE_CODE
}));
printf "Retrieved %d keyword theme constants using the keyword '%s'.\n",
scalar @{$response->{keywordThemeConstants}}, $keyword_text;
return $response->{keywordThemeConstants};
}
# [END add_smart_campaign]
# [START add_smart_campaign_13]
# Creates a KeywordInfo instance using the given free-form keyword text.
sub _get_freeform_keyword_theme_info {
my ($freeform_keyword_text) = @_;
return Google::Ads::GoogleAds::V10::Common::KeywordThemeInfo->new({
freeFormKeywordTheme => $freeform_keyword_text
});
}
# [END add_smart_campaign_13]
# Maps a list of KeywordThemeConstants to KeywordThemeInfos.
sub _map_keyword_theme_constants_to_infos {
my ($keyword_theme_constants) = @_;
my $keyword_theme_infos = [];
foreach my $keyword_theme_constant (@$keyword_theme_constants) {
push @$keyword_theme_infos,
Google::Ads::GoogleAds::V10::Common::KeywordThemeInfo->new({
keywordThemeConstant => $keyword_theme_constant->{resourceName}});
}
return $keyword_theme_infos;
}
# [START add_smart_campaign_9]
# Builds a SmartCampaignSuggestionInfo object with business details.
# The details are used by the SmartCampaignSuggestService to suggest a budget
# amount as well as creatives for the ad.
# Note that when retrieving ad creative suggestions you must set the
# "final_url", "language_code" and "keyword_themes" fields on the
# SmartCampaignSuggestionInfo instance.
sub _get_smart_campaign_suggestion_info {
my ($business_location_id, $business_name) = @_;
my $suggestion_info =
Google::Ads::GoogleAds::V10::Services::SmartCampaignSuggestService::SmartCampaignSuggestionInfo
->new({
# Add the URL of the campaign's landing page.
finalUrl => LANDING_PAGE_URL,
# Add the language code for the campaign.
languageCode => LANGUAGE_CODE,
# Construct location information using the given geo target constant.
# It's also possible to provide a geographic proximity using the
# "proximity" field on suggestion_info, for example:
#
# proximity => Google::Ads::GoogleAds::V10::Common::ProximityInfo->new({
# address => Google::Ads::GoogleAds::V10::Common::AddressInfo->new({
# postalCode => "INSERT_POSTAL_CODE",
# provinceCode => "INSERT_PROVINCE_CODE",
# countryCode => "INSERT_COUNTRY_CODE",
# provinceName => "INSERT_PROVINCE_NAME",
# streetAddress => "INSERT_STREET_ADDRESS",
# streetAddress2 => "INSERT_STREET_ADDRESS_2",
# cityName => "INSERT_CITY_NAME"
# }
# ),
# radius => "INSERT_RADIUS",
# radiusUnits => MILES
# }
# ),
#
# For more information on proximities see:
locationList =>
Google::Ads::GoogleAds::V10::Services::SmartCampaignSuggestService::LocationList
->new(
)});
# Add the LocationInfo object to the list of locations on the SuggestionInfo
# object. You have the option of providing multiple locations when using
# location-based suggestions.
push
@{$suggestion_info->{locationList}{locations}},
Google::Ads::GoogleAds::V10::Common::LocationInfo->new({
# Set the location to the resource name of the given geo target constant.
geoTargetConstant =>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::geo_target_constant(
GEO_TARGET_CONSTANT)});
# Set one of the business_location_id or business_name, whichever is provided.
if (defined $business_location_id) {
$suggestion_info->{businessLocationId} =
_convert_business_location_id($business_location_id);
} else {
$suggestion_info->{businessContext} =
Google::Ads::GoogleAds::V10::Services::SmartCampaignSuggestService::BusinessContext
->new({
businessName => $business_name
});
}
# Add a schedule detailing which days of the week the business is open. This
# example schedule describes a business that is open on Mondays from 9:00 AM
# to 5:00 PM.
push
@{$suggestion_info->{adSchedules}},
Google::Ads::GoogleAds::V10::Common::AdScheduleInfo->new({
# Set the day of this schedule as Monday.
dayOfWeek => MONDAY,
# Set the start hour to 9 AM.
startHour => 9,
# Set the end hour to 5 PM.
endHour => 17,
# Set the start and end minutes to zero.
startMinute => ZERO,
endMinute => ZERO
});
return $suggestion_info;
}
# [END add_smart_campaign_9]
# [START add_smart_campaign_1]
# Retrieves a suggested budget amount for a new budget.
# Using the SmartCampaignSuggestService to determine a daily budget for new and
# existing Smart campaigns is highly recommended because it helps the campaigns
# achieve optimal performance.
sub _get_budget_suggestion {
my ($api_client, $customer_id, $suggestion_info) = @_;
my $request =
Google::Ads::GoogleAds::V10::Services::SmartCampaignSuggestService::SuggestSmartCampaignBudgetOptionsRequest
->new({
customerId => $customer_id,
# You can retrieve suggestions for an existing campaign by setting the
# "campaign" field of the request to the resource name of a campaign and
# leaving the rest of the request fields below unset:
# campaign => "INSERT_CAMPAIGN_RESOURCE_NAME_HERE",
#
# Since these suggestions are for a new campaign, we're going to use the
# "suggestion_info" field instead.
suggestionInfo => $suggestion_info
});
# Issue a request to retrieve a budget suggestion.
my $response = $api_client->SmartCampaignSuggestService()
->suggest_smart_campaign_budget_options($request);
# Three tiers of options will be returned: "low", "high", and "recommended".
# Here we will use the "recommended" option. The amount is specified in micros,
# where one million is equivalent to one currency unit.
printf "A daily budget amount of %d was suggested, garnering an estimated " .
"minimum of %d clicks and an estimated maximum of %d clicks per day.\n",
$response->{recommended}{dailyAmountMicros},
$response->{recommended}{metrics}{minDailyClicks},
$response->{recommended}{metrics}{maxDailyClicks};
return $response->{recommended}{dailyAmountMicros};
}
# [END add_smart_campaign_1]
# [START add_smart_campaign_10]
# Retrieves creative suggestions for a Smart campaign ad.
# Using the SmartCampaignSuggestService to suggest creatives for new and
# existing Smart campaigns is highly recommended because it helps the campaigns
# achieve optimal performance.
sub _get_ad_suggestions {
my ($api_client, $customer_id, $suggestion_info) = @_;
# Issue a request to retrieve ad creative suggestions.
my $response =
$api_client->SmartCampaignSuggestService()->suggest_smart_campaign_ad(
Google::Ads::GoogleAds::V10::Services::SmartCampaignSuggestService::SuggestSmartCampaignAdRequest
->new({
customerId => $customer_id,
# Unlike the SuggestSmartCampaignBudgetOptions method, it's only
# possible to use suggestion_info to retrieve ad creative suggestions.
suggestionInfo => $suggestion_info
}));
# The SmartCampaignAdInfo object in the response contains a list of up to
# three headlines and two descriptions. Note that some of the suggestions
# may have empty strings as text. Before setting these on the ad you should
# review them and filter out any empty values.
my $ad_suggestions = $response->{adInfo};
printf "The following headlines were suggested:\n";
foreach my $headline (@{$ad_suggestions->{headlines}}) {
printf "\t%s\n", defined $headline->{text} ? $headline->{text} : "<None>";
}
printf "And the following descriptions were suggested:\n";
foreach my $description (@{$ad_suggestions->{descriptions}}) {
printf "\t%s\n",
defined $description->{text} ? $description->{text} : "<None>";
}
return $ad_suggestions;
}
# [END add_smart_campaign_10]
# [START add_smart_campaign_2]
# Creates a MutateOperation that creates a new CampaignBudget.
# A temporary ID will be assigned to this campaign budget so that it can be
# referenced by other objects being created in the same Mutate request.
sub _create_campaign_budget_operation {
my ($customer_id, $suggested_budget_amount) = @_;
return
Google::Ads::GoogleAds::V10::Services::GoogleAdsService::MutateOperation->
new({
campaignBudgetOperation =>
Google::Ads::GoogleAds::V10::Services::CampaignBudgetService::CampaignBudgetOperation
->new({
create => Google::Ads::GoogleAds::V10::Resources::CampaignBudget->new(
{
name => "Smart campaign budget #" . uniqid(),
# A budget used for Smart campaigns must have the type SMART_CAMPAIGN.
type =>
Google::Ads::GoogleAds::V10::Enums::BudgetTypeEnum::SMART_CAMPAIGN,
# The suggested budget amount from the SmartCampaignSuggestService is
# a daily budget. We don't need to specify that here, because the
# budget period already defaults to DAILY.
amountMicros => $suggested_budget_amount,
# Set a temporary ID in the budget's resource name so it can be
# referenced by the campaign in later steps.
resourceName =>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::campaign_budget(
$customer_id, BUDGET_TEMPORARY_ID
)})})});
}
# [END add_smart_campaign_2]
# [START add_smart_campaign_3]
# Creates a MutateOperation that creates a new Smart campaign.
# A temporary ID will be assigned to this campaign so that it can be referenced
# by other objects being created in the same Mutate request.
sub _create_smart_campaign_operation {
my ($customer_id) = @_;
return
Google::Ads::GoogleAds::V10::Services::GoogleAdsService::MutateOperation->
new({
campaignOperation =>
Google::Ads::GoogleAds::V10::Services::CampaignService::CampaignOperation
->new({
create => Google::Ads::GoogleAds::V10::Resources::Campaign->new({
name => "Smart campaign #" . uniqid(),
# Set the campaign status as PAUSED. The campaign is the only
# entity in the mutate request that should have its status set.
status => PAUSED,
# AdvertisingChannelType must be SMART.
advertisingChannelType => SMART,
# AdvertisingChannelSubType must be SMART_CAMPAIGN.
advertisingChannelSubType =>
Google::Ads::GoogleAds::V10::Enums::AdvertisingChannelSubTypeEnum::SMART_CAMPAIGN,
# Assign the resource name with a temporary ID.
resourceName =>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::campaign(
$customer_id, SMART_CAMPAIGN_TEMPORARY_ID
),
# Set the budget using the given budget resource name.
campaignBudget =>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::campaign_budget(
$customer_id, BUDGET_TEMPORARY_ID
)})})});
}
# [END add_smart_campaign_3]
# [START add_smart_campaign_4]
# Creates a MutateOperation to create a new SmartCampaignSetting.
# SmartCampaignSettings are unique in that they only support UPDATE operations,
# which are used to update and create them. Below we will use a temporary ID in
# the resource name to associate it with the campaign created in the previous step.
sub _create_smart_campaign_setting_operation {
my ($customer_id, $business_location_id, $business_name) = @_;
my $smart_campaign_setting =
Google::Ads::GoogleAds::V10::Resources::SmartCampaignSetting->new({
# Set a temporary ID in the campaign setting's resource name to associate it
# with the campaign created in the previous step.
resourceName =>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::smart_campaign_setting(
$customer_id, SMART_CAMPAIGN_TEMPORARY_ID
),
# Below we configure the SmartCampaignSetting using many of the same
# details used to generate a budget suggestion.
phoneNumber => Google::Ads::GoogleAds::V10::Resources::PhoneNumber->new({
countryCode => COUNTRY_CODE,
phoneNumber => PHONE_NUMBER
}
),
finalUrl => LANDING_PAGE_URL,
advertisingLanguageCode => LANGUAGE_CODE
});
# It's required that either a business location ID or a business name is
# added to the SmartCampaignSetting.
if (defined $business_location_id) {
$smart_campaign_setting->{businessLocationId} =
_convert_business_location_id($business_location_id);
} else {
$smart_campaign_setting->{businessName} = $business_name;
}
return
Google::Ads::GoogleAds::V10::Services::GoogleAdsService::MutateOperation->
new({
smartCampaignSettingOperation =>
Google::Ads::GoogleAds::V10::Services::SmartCampaignSettingService::SmartCampaignSettingOperation
->new({
update => $smart_campaign_setting,
# Set the update mask on the operation. This is required since the
# smart campaign setting is created in an UPDATE operation. Here the
# update mask will be a list of all the fields that were set on the
# SmartCampaignSetting.
updateMask => all_set_fields_of($smart_campaign_setting)})});
}
# [END add_smart_campaign_4]
# [START add_smart_campaign_8]
# Creates a list of MutateOperations that create new campaign criteria.
sub _create_campaign_criterion_operations {
my ($customer_id, $keyword_theme_infos, $suggestion_info) = @_;
my $campaign_criterion_operations = [];
foreach my $keyword_theme_info (@$keyword_theme_infos) {
push @$campaign_criterion_operations,
Google::Ads::GoogleAds::V10::Services::GoogleAdsService::MutateOperation
->new({
campaignCriterionOperation =>
Google::Ads::GoogleAds::V10::Services::CampaignCriterionService::CampaignCriterionOperation
->new({
create =>
Google::Ads::GoogleAds::V10::Resources::CampaignCriterion->new({
# Set the campaign ID to a temporary ID.
campaign =>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::campaign(
$customer_id, SMART_CAMPAIGN_TEMPORARY_ID
),
# Set the keyword theme to the given KeywordThemeInfo.
keywordTheme => $keyword_theme_info
})})});
}
# Create a location criterion for each location in the suggestion info object
# to add corresponding location targeting to the Smart campaign.
foreach my $location_info (@{$suggestion_info->{locationList}{locations}}) {
push @$campaign_criterion_operations,
Google::Ads::GoogleAds::V10::Services::GoogleAdsService::MutateOperation
->new({
campaignCriterionOperation =>
Google::Ads::GoogleAds::V10::Services::CampaignCriterionService::CampaignCriterionOperation
->new({
create =>
Google::Ads::GoogleAds::V10::Resources::CampaignCriterion->new({
# Set the campaign ID to a temporary ID.
campaign =>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::campaign(
$customer_id, SMART_CAMPAIGN_TEMPORARY_ID
),
# Set the location to the given location.
location => $location_info
})})});
}
return $campaign_criterion_operations;
}
# [END add_smart_campaign_8]
# [START add_smart_campaign_5]
# Creates a MutateOperation that creates a new ad group.
# A temporary ID will be used in the campaign resource name for this ad group to
# associate it with the Smart campaign created in earlier steps. A temporary ID
# will also be used for its own resource name so that we can associate an ad group ad
# with it later in the process.
# Only one ad group can be created for a given Smart campaign.
sub _create_ad_group_operation {
my ($customer_id) = @_;
return
Google::Ads::GoogleAds::V10::Services::GoogleAdsService::MutateOperation->
new({
adGroupOperation =>
Google::Ads::GoogleAds::V10::Services::AdGroupService::AdGroupOperation
->new({
create => Google::Ads::GoogleAds::V10::Resources::AdGroup->new({
# Set the ad group ID to a temporary ID.
resourceName =>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::ad_group(
$customer_id, AD_GROUP_TEMPORARY_ID
),
name => "Smart campaign ad group #" . uniqid(),
# Set the campaign ID to a temporary ID.
campaign =>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::campaign(
$customer_id, SMART_CAMPAIGN_TEMPORARY_ID
),
# The ad group type must be set to SMART_CAMPAIGN_ADS.
type => SMART_CAMPAIGN_ADS
})})});
}
# [END add_smart_campaign_5]
# [START add_smart_campaign_6]
# Creates a MutateOperation that creates a new ad group ad.
# A temporary ID will be used in the ad group resource name for this ad group ad
# to associate it with the ad group created in earlier steps.
sub _create_ad_group_ad_operation {
my ($customer_id, $ad_suggestions) = @_;
my $mutate_operation =
Google::Ads::GoogleAds::V10::Services::GoogleAdsService::MutateOperation->
new({
adGroupAdOperation =>
Google::Ads::GoogleAds::V10::Services::AdGroupAdService::AdGroupAdOperation
->new({
create => Google::Ads::GoogleAds::V10::Resources::AdGroupAd->new({
adGroup =>
# Set the ad group ID to a temporary ID.
Google::Ads::GoogleAds::V10::Utils::ResourceNames::ad_group(
$customer_id, AD_GROUP_TEMPORARY_ID
),
ad => Google::Ads::GoogleAds::V10::Resources::Ad->new({
# Set the type to SMART_CAMPAIGN_AD.
type => SMART_CAMPAIGN_AD,
smartCampaignAd =>
Google::Ads::GoogleAds::V10::Common::SmartCampaignAdInfo->
new({
headlines => [],
descriptions => []})})})})});
# The SmartCampaignAdInfo object includes headlines and descriptions
# retrieved from the SmartCampaignSuggestService.SuggestSmartCampaignAd
# 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 meaningful texts from the user. Below
# we just accept the creatives that were suggested while filtering out empty
# 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.
my $smart_campaign_ad =
$mutate_operation->{adGroupAdOperation}{create}{ad}{smartCampaignAd};
foreach my $asset (@{$ad_suggestions->{headlines}}) {
push @{$smart_campaign_ad->{headlines}}, $asset
if defined $asset->{text};
}
# If there are fewer headlines than are required, we manually add additional
# headlines to make up for the difference.
my $num_missing_headlines =
REQUIRED_NUM_HEADLINES - scalar @{$smart_campaign_ad->{headlines}};
for (my $i = 0 ; $i < $num_missing_headlines ; $i++) {
push @{$smart_campaign_ad->{headlines}},
Google::Ads::GoogleAds::V10::Common::AdTextAsset->new({
text => "placeholder headline " . $i
});
}
foreach my $asset (@{$ad_suggestions->{descriptions}}) {
push @{$smart_campaign_ad->{descriptions}}, $asset
if defined $asset->{text};
}
# If there are fewer descriptions than are required, we manually add
# additional descriptions to make up for the difference.
my $num_missing_descriptions =
REQUIRED_NUM_DESCRIPTIONS - scalar @{$smart_campaign_ad->{descriptions}};
for (my $i = 0 ; $i < $num_missing_descriptions ; $i++) {
push @{$smart_campaign_ad->{descriptions}},
Google::Ads::GoogleAds::V10::Common::AdTextAsset->new({
text => "placeholder description " . $i
});
}
return $mutate_operation;
}
# [END add_smart_campaign_6]
# Prints the details of a MutateGoogleAdsResponse.
sub _print_response_details {
my ($response) = @_;
my $mutate_operation_responses = $response->{mutateOperationResponses};
foreach my $operation_response (@$mutate_operation_responses) {
my $resource_name = "<not found>";
my $entity_name = "unknown";
if ($operation_response->{adGroupResult}) {
$entity_name = "AdGroup";
$resource_name = $operation_response->{adGroupResult}{resourceName};
} elsif ($operation_response->{adGroupAdResult}) {
$entity_name = "AdGroupAd";
$resource_name = $operation_response->{adGroupAdResult}{resourceName};
} elsif ($operation_response->{campaignResult}) {
$entity_name = "Campaign";
$resource_name = $operation_response->{campaignResult}{resourceName};
} elsif ($operation_response->{campaignBudgetResult}) {
$entity_name = "CampaignBudget";
$resource_name =
$operation_response->{campaignBudgetResult}{resourceName};
} elsif ($operation_response->{campaignCriterionResult}) {
$entity_name = "CampaignCriterion";
$resource_name =
$operation_response->{campaignCriterionResult}{resourceName};
} elsif ($operation_response->{smartCampaignSettingResult}) {
$entity_name = "SmartCampaignSetting";
$resource_name =
$operation_response->{smartCampaignSettingResult}{resourceName};
}
printf "Created a(n) $entity_name with resource name '$resource_name'.\n";
}
}
# [START add_smart_campaign_14]
# Converts the business location ID from the format returned by Business Profile
# to the format expected by the API.
# The business location ID is an unsigned 64-bit integer. However, the Google Ads
# 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.
sub _convert_business_location_id {
my ($business_location_id) = @_;
if ($business_location_id >= _64_BIT_RANGE_CEILING) {
die "The given business_location_id is outside of the range for " .
"a 64 bit integer.";
} elsif ($business_location_id >= _SIGNED_64_BIT_RANGE_CEILING) {
# Perform the two's complement.
return -1 * (_64_BIT_RANGE_CEILING - $business_location_id);
} else {
return $business_location_id;
}
}
# [END add_smart_campaign_14]
# Don't run the example if the file is being included.
if (abs_path($0) ne abs_path(__FILE__)) {
return 1;
}
# Get Google Ads Client, credentials will be read from ~/googleads.properties.
my $api_client = Google::Ads::GoogleAds::Client->new();
# By default examples are set to die on any server returned fault.
$api_client->set_die_on_faults(1);
# Parameters passed on the command line will override any parameters set in code.
GetOptions(
"customer_id=s" => \$customer_id,
"keyword_text=s" => \$keyword_text,
"freeform_keyword_text=s" => \$freeform_keyword_text,
"business_location_id=i" => \$business_location_id,
"business_name=s" => \$business_name
);
# Print the help message if the parameters are not initialized in the code nor
# in the command line.
pod2usage(2) if not check_params($customer_id);
# Call the example.
add_smart_campaign($api_client, $customer_id =~ s/-//gr,
$keyword_text, $freeform_keyword_text, $business_location_id, $business_name);
=pod
=head1 NAME
add_smart_campaign
=head1 DESCRIPTION
This example shows how to create a Smart campaign.
More details on Smart campaigns can be found here:
=head1 SYNOPSIS
add_smart_campaign.pl [options]
-help Show the help message.
-customer_id The Google Ads customer ID.
-keyword_text [optional] 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.
-freeform_keyword_text [optional] 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.
-business_location_id [optional] The ID of a Business Profile location.
This is required if a business name is not provided.
This ID can be retrieved using the Business Profile API, for details see:
-business_name [optional] The name of a business in Business Profile.
This is required if a business location ID is not provided.
=cut