#!/usr/bin/perl -w
use
lib
"$Bin/../../lib"
;
use
Google::Ads::GoogleAds::V13::Services::AdGroupAssetService::AdGroupAssetOperation;
use
Google::Ads::GoogleAds::V13::Services::CampaignAssetService::CampaignAssetOperation;
use
Google::Ads::GoogleAds::V13::Services::GoogleAdsService::SearchGoogleAdsStreamRequest;
my
$customer_id
=
"INSERT_CUSTOMER_ID_HERE"
;
my
$feed_item_id
=
"INSERT_FEED_ITEM_ID_HERE"
;
sub
migrate_promotion_feed_to_asset {
my
(
$api_client
,
$customer_id
,
$feed_item_id
) =
@_
;
my
$google_ads_service
=
$api_client
->GoogleAdsService();
my
$extension_feed_item_resource_name
=
Google::Ads::GoogleAds::V13::Utils::ResourceNames::extension_feed_item(
$customer_id
,
$feed_item_id
);
my
$extension_feed_item
=
get_extension_feed_item(
$google_ads_service
,
$customer_id
,
$feed_item_id
);
my
@campaign_ids
=
get_targeted_campaign_ids(
$google_ads_service
,
$customer_id
,
$extension_feed_item_resource_name
);
my
@ad_group_ids
=
get_targeted_ad_group_ids(
$google_ads_service
,
$customer_id
,
$extension_feed_item_resource_name
);
my
$promotion_asset_resource_name
=
create_promotion_asset_from_feed(
$api_client
,
$customer_id
,
$extension_feed_item
);
associate_asset_with_campaigns(
$api_client
,
$customer_id
,
$promotion_asset_resource_name
,
@campaign_ids
);
associate_asset_with_ad_groups(
$api_client
,
$customer_id
,
$promotion_asset_resource_name
,
@ad_group_ids
);
return
1;
}
sub
get_extension_feed_item {
my
(
$google_ads_service
,
$customer_id
,
$feed_item_id
) =
@_
;
my
$extension_feed_item_query
= "
SELECT
extension_feed_item.id,
extension_feed_item.ad_schedules,
extension_feed_item.device,
extension_feed_item.status,
extension_feed_item.start_date_time,
extension_feed_item.end_date_time,
extension_feed_item.targeted_campaign,
extension_feed_item.targeted_ad_group,
extension_feed_item.promotion_feed_item.discount_modifier,
extension_feed_item.promotion_feed_item.final_mobile_urls,
extension_feed_item.promotion_feed_item.final_url_suffix,
extension_feed_item.promotion_feed_item.final_urls,
extension_feed_item.promotion_feed_item.language_code,
extension_feed_item.promotion_feed_item.money_amount_off.amount_micros,
extension_feed_item.promotion_feed_item.money_amount_off.currency_code,
extension_feed_item.promotion_feed_item.occasion,
extension_feed_item.promotion_feed_item.orders_over_amount.amount_micros,
extension_feed_item.promotion_feed_item.orders_over_amount.currency_code,
extension_feed_item.promotion_feed_item.percent_off,
extension_feed_item.promotion_feed_item.promotion_code,
extension_feed_item.promotion_feed_item.promotion_end_date,
extension_feed_item.promotion_feed_item.promotion_start_date,
extension_feed_item.promotion_feed_item.promotion_target,
extension_feed_item.promotion_feed_item.tracking_url_template
FROM extension_feed_item
WHERE
extension_feed_item.extension_type =
'PROMOTION'
AND extension_feed_item.id =
$feed_item_id
LIMIT 1";
my
$fetched_extension_feed_item
;
my
$search_stream_request
=
Google::Ads::GoogleAds::V13::Services::GoogleAdsService::SearchGoogleAdsStreamRequest
->new({
customerId
=>
$customer_id
,
query
=>
$extension_feed_item_query
});
my
$search_stream_handler
=
Google::Ads::GoogleAds::Utils::SearchStreamHandler->new({
service
=>
$google_ads_service
,
request
=>
$search_stream_request
});
$search_stream_handler
->process_contents(
sub
{
my
$google_ads_row
=
shift
;
$fetched_extension_feed_item
=
$google_ads_row
->{extensionFeedItem};
});
my
$url_custom_parameters_query
= "
SELECT feed_item.url_custom_parameters
FROM feed_item
WHERE feed_item.id =
$feed_item_id
";
$search_stream_request
=
Google::Ads::GoogleAds::V13::Services::GoogleAdsService::SearchGoogleAdsStreamRequest
->new({
customerId
=>
$customer_id
,
query
=>
$url_custom_parameters_query
});
$search_stream_handler
=
Google::Ads::GoogleAds::Utils::SearchStreamHandler->new({
service
=>
$google_ads_service
,
request
=>
$search_stream_request
});
$search_stream_handler
->process_contents(
sub
{
my
$google_ads_row
=
shift
;
push
@{
$fetched_extension_feed_item
->{promotionFeedItem}{urlCustomParameters}
}, @{
$google_ads_row
->{feedItem}{urlCustomParameters}};
});
printf
"Retrieved details for ad extension with ID %d.\n"
,
$fetched_extension_feed_item
->{id};
return
$fetched_extension_feed_item
;
}
sub
get_targeted_campaign_ids {
my
(
$google_ads_service
,
$customer_id
,
$extension_feed_item_resource_name
) =
@_
;
my
@campaign_ids
;
my
$query
= "
SELECT campaign.id, campaign_extension_setting.extension_feed_items
FROM campaign_extension_setting
WHERE campaign_extension_setting.extension_type =
'PROMOTION'
AND campaign.status !=
'REMOVED'
";
my
$search_stream_request
=
Google::Ads::GoogleAds::V13::Services::GoogleAdsService::SearchGoogleAdsStreamRequest
->new({
customerId
=>
$customer_id
,
query
=>
$query
});
my
$search_stream_handler
=
Google::Ads::GoogleAds::Utils::SearchStreamHandler->new({
service
=>
$google_ads_service
,
request
=>
$search_stream_request
});
$search_stream_handler
->process_contents(
sub
{
my
$google_ads_row
=
shift
;
if
(
grep
{
$_
eq
$extension_feed_item_resource_name
}
@{
$google_ads_row
->{campaignExtensionSetting}{extensionFeedItems}})
{
printf
"Found matching campaign with ID $google_ads_row->{campaign}{id}.\n"
;
push
@campaign_ids
,
$google_ads_row
->{campaign}{id};
}
});
return
@campaign_ids
;
}
sub
get_targeted_ad_group_ids {
my
(
$google_ads_service
,
$customer_id
,
$extension_feed_item_resource_name
) =
@_
;
my
@ad_group_ids
;
my
$query
= "
SELECT ad_group.id, ad_group_extension_setting.extension_feed_items
FROM ad_group_extension_setting
WHERE ad_group_extension_setting.extension_type =
'PROMOTION'
AND ad_group.status !=
'REMOVED'
";
my
$search_stream_request
=
Google::Ads::GoogleAds::V13::Services::GoogleAdsService::SearchGoogleAdsStreamRequest
->new({
customerId
=>
$customer_id
,
query
=>
$query
});
my
$search_stream_handler
=
Google::Ads::GoogleAds::Utils::SearchStreamHandler->new({
service
=>
$google_ads_service
,
request
=>
$search_stream_request
});
$search_stream_handler
->process_contents(
sub
{
my
$google_ads_row
=
shift
;
if
(
grep
{
$_
eq
$extension_feed_item_resource_name
}
@{
$google_ads_row
->{adGroupExtensionSetting}{extensionFeedItems}})
{
printf
"Found matching ad group with ID $google_ads_row->{adGroup}{id}.\n"
;
push
@ad_group_ids
,
$google_ads_row
->{adGroup}{id};
}
});
return
@ad_group_ids
;
}
sub
create_promotion_asset_from_feed {
my
(
$api_client
,
$customer_id
,
$extension_feed_item
) =
@_
;
my
$promotion_feed_item
=
$extension_feed_item
->{promotionFeedItem};
my
$asset
= Google::Ads::GoogleAds::V13::Resources::Asset->new({
name
=>
"Migrated from feed item #"
.
$extension_feed_item
->{id},
trackingUrlTemplate
=>
$promotion_feed_item
->{trackingUrlTemplate},
finalUrlSuffix
=>
$promotion_feed_item
->{finalUrlSuffix},
promotionAsset
=>
Google::Ads::GoogleAds::V13::Common::PromotionAsset->new({
promotionTarget
=>
$promotion_feed_item
->{promotionTarget},
discountModifier
=>
$promotion_feed_item
->{discountModifier},
redemptionStartDate
=>
$promotion_feed_item
->{promotionStartDate},
redemptionEndDate
=>
$promotion_feed_item
->{promotionEndDate},
occasion
=>
$promotion_feed_item
->{occasion},
languageCode
=>
$promotion_feed_item
->{languageCode}})});
push
@{
$asset
->{finalUrls}}, @{
$promotion_feed_item
->{finalUrls}};
if
(
defined
(
$extension_feed_item
->{adSchedules})) {
push
@{
$asset
->{promotionAsset}{adScheduleTargets}},
@{
$extension_feed_item
->{adSchedules}};
}
if
(
defined
(
$promotion_feed_item
->{finalMobileUrls})) {
push
@{
$asset
->{finalMobileUrls}},
@{
$promotion_feed_item
->{finalMobileUrls}};
}
if
(
defined
(
$promotion_feed_item
->{urlCustomParameters})) {
push
@{
$asset
->{urlCustomParameters}},
@{
$promotion_feed_item
->{urlCustomParameters}};
}
if
(
defined
(
$promotion_feed_item
->{percentOff})) {
$asset
->{promotionAsset}{percentOff} =
$promotion_feed_item
->{percentOff} / 100;
}
else
{
$asset
->{promotionAsset}{moneyAmountOff} =
Google::Ads::GoogleAds::V13::Common::Money->new({
amountMicros
=>
$promotion_feed_item
->{moneyAmountOff}{amountMicros},
currencyCode
=>
$promotion_feed_item
->{moneyAmountOff}{currencyCode}});
}
if
(
defined
(
$promotion_feed_item
->{promotionCode})) {
$asset
->{promotionAsset}{promotionCode} =
$promotion_feed_item
->{promotionCode};
}
else
{
$asset
->{promotionAsset}{ordersOverAmount} =
Google::Ads::GoogleAds::V13::Common::Money->new({
amountMicros
=>
$promotion_feed_item
->{ordersOverAmount}{amountMicros},
currencyCode
=>
$promotion_feed_item
->{ordersOverAmount}{currencyCode}}
);
}
if
(
defined
(
$extension_feed_item
->{startDateTime})) {
$asset
->{promotionAsset}{startDate} =
substr
(
$extension_feed_item
->{startDateTime},
0,
index
(
$extension_feed_item
->{startDateTime},
' '
));
}
if
(
defined
(
$extension_feed_item
->{endDateTime})) {
$asset
->{promotionAsset}{endDate} =
substr
(
$extension_feed_item
->{endDateTime},
0,
index
(
$extension_feed_item
->{endDateTime},
' '
));
}
my
$operation
=
Google::Ads::GoogleAds::V13::Services::AssetService::AssetOperation->new({
create
=>
$asset
});
my
$response
=
$api_client
->AssetService()->mutate({
customerId
=>
$customer_id
,
operations
=> [
$operation
]});
printf
"Created Promotion asset with resource name '%s'.\n"
,
$response
->{results}[0]{resourceName};
return
$response
->{results}[0]{resourceName};
}
sub
associate_asset_with_campaigns {
my
(
$api_client
,
$customer_id
,
$promotion_asset_resource_name
,
@campaign_ids
)
=
@_
;
if
(
scalar
(
@campaign_ids
) == 0) {
printf
"Asset was not associated with any campaigns.\n"
;
return
();
}
my
$operations
= [];
foreach
my
$campaign_id
(
@campaign_ids
) {
my
$campaign_asset
=
Google::Ads::GoogleAds::V13::Resources::CampaignAsset->new({
asset
=>
$promotion_asset_resource_name
,
fieldType
=> PROMOTION,
campaign
=> Google::Ads::GoogleAds::V13::Utils::ResourceNames::campaign(
$customer_id
,
$campaign_id
)});
my
$operation
=
Google::Ads::GoogleAds::V13::Services::CampaignAssetService::CampaignAssetOperation
->new({
create
=>
$campaign_asset
});
push
@$operations
,
$operation
;
}
my
$response
=
$api_client
->CampaignAssetService()->mutate({
customerId
=>
$customer_id
,
operations
=>
$operations
});
foreach
my
$result
(@{
$response
->{results}}) {
printf
"Created campaign asset with resource name '%s'.\n"
,
$result
->{resourceName};
}
}
sub
associate_asset_with_ad_groups {
my
(
$api_client
,
$customer_id
,
$promotion_asset_resource_name
,
@ad_group_ids
)
=
@_
;
if
(
scalar
(
@ad_group_ids
) == 0) {
printf
"Asset was not associated with any ad groups.\n"
;
return
();
}
my
$operations
= [];
foreach
my
$ad_group_id
(
@ad_group_ids
) {
my
$ad_group_asset
=
Google::Ads::GoogleAds::V13::Resources::AdGroupAsset->new({
asset
=>
$promotion_asset_resource_name
,
fieldType
=> PROMOTION,
adGroup
=> Google::Ads::GoogleAds::V13::Utils::ResourceNames::ad_group(
$customer_id
,
$ad_group_id
)});
my
$operation
=
Google::Ads::GoogleAds::V13::Services::AdGroupAssetService::AdGroupAssetOperation
->new({
create
=>
$ad_group_asset
});
push
@$operations
,
$operation
;
}
my
$response
=
$api_client
->AdGroupAssetService()->mutate({
customerId
=>
$customer_id
,
operations
=>
$operations
});
foreach
my
$result
(@{
$response
->{results}}) {
printf
"Created ad group asset with resource name '%s'.\n"
,
$result
->{resourceName};
}
}
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
,
"feed_item_id=i"
=> \
$feed_item_id
);
pod2usage(2)
if
not check_params(
$customer_id
,
$feed_item_id
);
migrate_promotion_feed_to_asset(
$api_client
,
$customer_id
=~ s/-//gr,
$feed_item_id
);