#!/usr/bin/perl -w
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
constant
GEO_TARGET_CONSTANT
=> 1023191;
use
constant
PHONE_NUMBER
=>
"555-555-5555"
;
use
constant
SMART_CAMPAIGN_TEMPORARY_ID
=> -2;
use
constant
AD_GROUP_TEMPORARY_ID
=> -3;
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;
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
)
=
@_
;
my
$suggestion_info
=
_get_smart_campaign_suggestion_info(
$business_location_id
,
$business_name
);
my
$keyword_theme_constants
=
_get_keyword_theme_suggestions(
$api_client
,
$customer_id
,
$suggestion_info
);
if
(
defined
$keyword_text
) {
push
@$keyword_theme_constants
,
@{_get_keyword_text_auto_completions(
$api_client
,
$keyword_text
)};
}
my
$keyword_theme_infos
=
_map_keyword_theme_constants_to_infos(
$keyword_theme_constants
);
if
(
defined
$freeform_keyword_text
) {
push
@$keyword_theme_infos
,
_get_freeform_keyword_theme_info(
$freeform_keyword_text
);
}
$suggestion_info
->{keywordThemes} =
$keyword_theme_infos
;
my
$suggested_budget_amount
=
_get_budget_suggestion(
$api_client
,
$customer_id
,
$suggestion_info
);
my
$ad_suggestions
=
_get_ad_suggestions(
$api_client
,
$customer_id
,
$suggestion_info
);
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
);
my
$mutate_operations
= [
$campaign_budget_operation
,
$smart_campaign_operation
,
$smart_campaign_setting_operation
,
@$campaign_criterion_operations
,
$ad_group_operation
,
$ad_group_ad_operation
];
my
$mutate_google_ads_response
=
$api_client
->GoogleAdsService()->mutate({
customerId
=>
$customer_id
,
mutateOperations
=>
$mutate_operations
});
_print_response_details(
$mutate_google_ads_response
);
return
1;
}
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};
}
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};
}
sub
_get_freeform_keyword_theme_info {
my
(
$freeform_keyword_text
) =
@_
;
return
Google::Ads::GoogleAds::V10::Common::KeywordThemeInfo->new({
freeFormKeywordTheme
=>
$freeform_keyword_text
});
}
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
;
}
sub
_get_smart_campaign_suggestion_info {
my
(
$business_location_id
,
$business_name
) =
@_
;
my
$suggestion_info
=
Google::Ads::GoogleAds::V10::Services::SmartCampaignSuggestService::SmartCampaignSuggestionInfo
->new({
finalUrl
=> LANDING_PAGE_URL,
languageCode
=> LANGUAGE_CODE,
locationList
=>
Google::Ads::GoogleAds::V10::Services::SmartCampaignSuggestService::LocationList
->new(
)});
push
@{
$suggestion_info
->{locationList}{locations}},
Google::Ads::GoogleAds::V10::Common::LocationInfo->new({
geoTargetConstant
=>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::geo_target_constant(
GEO_TARGET_CONSTANT)});
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
});
}
push
@{
$suggestion_info
->{adSchedules}},
Google::Ads::GoogleAds::V10::Common::AdScheduleInfo->new({
dayOfWeek
=> MONDAY,
startHour
=> 9,
endHour
=> 17,
startMinute
=> ZERO,
endMinute
=> ZERO
});
return
$suggestion_info
;
}
sub
_get_budget_suggestion {
my
(
$api_client
,
$customer_id
,
$suggestion_info
) =
@_
;
my
$request
=
Google::Ads::GoogleAds::V10::Services::SmartCampaignSuggestService::SuggestSmartCampaignBudgetOptionsRequest
->new({
customerId
=>
$customer_id
,
suggestionInfo
=>
$suggestion_info
});
my
$response
=
$api_client
->SmartCampaignSuggestService()
->suggest_smart_campaign_budget_options(
$request
);
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};
}
sub
_get_ad_suggestions {
my
(
$api_client
,
$customer_id
,
$suggestion_info
) =
@_
;
my
$response
=
$api_client
->SmartCampaignSuggestService()->suggest_smart_campaign_ad(
Google::Ads::GoogleAds::V10::Services::SmartCampaignSuggestService::SuggestSmartCampaignAdRequest
->new({
customerId
=>
$customer_id
,
suggestionInfo
=>
$suggestion_info
}));
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
;
}
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(),
type
=>
Google::Ads::GoogleAds::V10::Enums::BudgetTypeEnum::SMART_CAMPAIGN,
amountMicros
=>
$suggested_budget_amount
,
resourceName
=>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::campaign_budget(
$customer_id
, BUDGET_TEMPORARY_ID
)})})});
}
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(),
status
=> PAUSED,
advertisingChannelType
=> SMART,
advertisingChannelSubType
=>
Google::Ads::GoogleAds::V10::Enums::AdvertisingChannelSubTypeEnum::SMART_CAMPAIGN,
resourceName
=>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::campaign(
$customer_id
, SMART_CAMPAIGN_TEMPORARY_ID
),
campaignBudget
=>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::campaign_budget(
$customer_id
, BUDGET_TEMPORARY_ID
)})})});
}
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({
resourceName
=>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::smart_campaign_setting(
$customer_id
, SMART_CAMPAIGN_TEMPORARY_ID
),
phoneNumber
=> Google::Ads::GoogleAds::V10::Resources::PhoneNumber->new({
countryCode
=> COUNTRY_CODE,
phoneNumber
=> PHONE_NUMBER
}
),
finalUrl
=> LANDING_PAGE_URL,
advertisingLanguageCode
=> LANGUAGE_CODE
});
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
,
updateMask
=> all_set_fields_of(
$smart_campaign_setting
)})});
}
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({
campaign
=>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::campaign(
$customer_id
, SMART_CAMPAIGN_TEMPORARY_ID
),
keywordTheme
=>
$keyword_theme_info
})})});
}
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({
campaign
=>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::campaign(
$customer_id
, SMART_CAMPAIGN_TEMPORARY_ID
),
location
=>
$location_info
})})});
}
return
$campaign_criterion_operations
;
}
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({
resourceName
=>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::ad_group(
$customer_id
, AD_GROUP_TEMPORARY_ID
),
name
=>
"Smart campaign ad group #"
. uniqid(),
campaign
=>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::campaign(
$customer_id
, SMART_CAMPAIGN_TEMPORARY_ID
),
type
=> SMART_CAMPAIGN_ADS
})})});
}
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
=>
Google::Ads::GoogleAds::V10::Utils::ResourceNames::ad_group(
$customer_id
, AD_GROUP_TEMPORARY_ID
),
ad
=> Google::Ads::GoogleAds::V10::Resources::Ad->new({
type
=> SMART_CAMPAIGN_AD,
smartCampaignAd
=>
Google::Ads::GoogleAds::V10::Common::SmartCampaignAdInfo->
new({
headlines
=> [],
descriptions
=> []})})})})});
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};
}
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};
}
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
;
}
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"
;
}
}
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) {
return
-1 * (_64_BIT_RANGE_CEILING -
$business_location_id
);
}
else
{
return
$business_location_id
;
}
}
if
(abs_path($0) ne abs_path(__FILE__)) {
return
1;
}
my
$api_client
= Google::Ads::GoogleAds::Client->new();
$api_client
->set_die_on_faults(1);
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
);
pod2usage(2)
if
not check_params(
$customer_id
);
add_smart_campaign(
$api_client
,
$customer_id
=~ s/-//gr,
$keyword_text
,
$freeform_keyword_text
,
$business_location_id
,
$business_name
);