The code samples below provide examples of common remarketing functions using the AdWords API. Client Library.
Create a remarketing user list (audience)
#!/usr/bin/perl -w # # Copyright 2017, Google Inc. All Rights Reserved. # # 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 remarketing user list (a.k.a. Audience) and shows its # associated conversion tracker code snippet. use strict; use lib "../../../lib"; use utf8; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::Predicate; use Google::Ads::AdWords::v201809::BasicUserList; use Google::Ads::AdWords::v201809::Selector; use Google::Ads::AdWords::v201809::UserListConversionType; use Google::Ads::AdWords::v201809::UserListOperation; use Cwd qw(abs_path); use Data::Uniqid qw(uniqid); # Example main subroutine. sub add_audience { my $client = shift; # Create conversion type (tag). my $name = "Mars cruise customers #" . uniqid(); my $conversion_type = Google::Ads::AdWords::v201809::UserListConversionType->new({name => $name}); # Create remarketing user list. my $user_list = Google::Ads::AdWords::v201809::BasicUserList->new({ name => $name, conversionTypes => [$conversion_type], # Additional properties (non-required). description => "A list of mars cruise customers in the last year", membershipLifeSpan => 365, status => "OPEN" }); # Create operation. my $operation = Google::Ads::AdWords::v201809::UserListOperation->new({ operator => "ADD", operand => $user_list }); # Add user list. my $result = $client->AdwordsUserListService()->mutate({operations => [$operation]}); if ($result->get_value()) { my $user_list = $result->get_value()->[0]; # Due to a bug in the service we need to retrieve the conversion trackers # info in a separate request after a few seconds. sleep(5); my $predicate = Google::Ads::AdWords::v201809::Predicate->new({ field => "Id", operator => "IN", values => [$user_list->get_id()->get_value()]}); my $selector = Google::Ads::AdWords::v201809::Selector->new({ fields => ["ConversionTypes"], predicates => [$predicate]}); my $conversion_trackers_page = $client->AdwordsUserListService()->get({serviceSelector => $selector}); # Get associated conversion snippets. my $conversion_id = $conversion_trackers_page->get_entries()->[0]->get_conversionTypes()->[0] ->get_id()->get_value(); # Create selector. my $conversion_type_predicate = Google::Ads::AdWords::v201809::Predicate->new({ field => "Id", operator => "IN", values => [$conversion_id]}); $selector = Google::Ads::AdWords::v201809::Selector->new({ fields => ["Id", "GoogleGlobalSiteTag", "GoogleEventSnippet"], predicates => [$conversion_type_predicate]}); # Get all conversion trackers. my $page = $client->ConversionTrackerService()->get({serviceSelector => $selector}); my $conversion_tracker = $page->get_entries()->[0]; # Display results. printf "User list with name \"%s\" and id \"%d\" was added.\n", $user_list->get_name(), $user_list->get_id(); printf("Google global site tag:\n%s\n\n", $conversion_tracker->get_googleGlobalSiteTag()); printf("Google event snippet:\n%s\n\n", $conversion_tracker->get_googleEventSnippet()); } else { print "No user list was added."; } return 1; } # Don't run the example if the file is being included. if (abs_path($0) ne abs_path(__FILE__)) { return 1; } # Log SOAP XML request, response and API errors. Google::Ads::AdWords::Logging::enable_all_logging(); # Get AdWords Client, credentials will be read from ~/adwords.properties. my $client = Google::Ads::AdWords::Client->new({version => "v201809"}); # By default examples are set to die on any server returned fault. $client->set_die_on_faults(1); # Call the example add_audience($client);
Create an AdWords conversion tracker and add to it upload conversions
#!/usr/bin/perl -w # # Copyright 2017, Google Inc. All Rights Reserved. # # 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 code example adds an AdWords conversion tracker and an upload conversion # tracker. use strict; use lib "../../../lib"; use utf8; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::AdWordsConversionTracker; use Google::Ads::AdWords::v201809::ConversionTrackerOperation; use Google::Ads::AdWords::v201809::UploadConversion; use Cwd qw(abs_path); use Data::Uniqid qw(uniqid); # Example main subroutine. sub add_conversion_trackers { my $client = shift; my @conversion_trackers = (); # Create AdWords conversion tracker. my $adwords_conversion_tracker = Google::Ads::AdWords::v201809::AdWordsConversionTracker->new({ name => "Earth to Mars Cruises Conversion #" . uniqid(), # Additional properties (non-required). status => "ENABLED", category => "DEFAULT", viewthroughLookbackWindow => 15, defaultRevenueValue => 23.41, alwaysUseDefaultRevenueValue => 1 }); push @conversion_trackers, $adwords_conversion_tracker; # Create an upload conversion for offline conversion imports. my $upload_conversion_tracker = Google::Ads::AdWords::v201809::UploadConversion->new({ # Set an appropriate category. This field is optional, and will be set to # DEFAULT if not mentioned. category => "LEAD", name => "Upload Conversion #" . uniqid(), viewthroughLookbackWindow => 30, ctcLookbackWindow => 90, # Optional: Set the default currency code to use for conversions # that do not specify a conversion currency. This must be an ISO 4217 # 3-character currency code such as "EUR" or "USD". # If this field is not set on this UploadConversion, AdWords will use # the account's currency. defaultRevenueCurrencyCode => "EUR", # Optional: Set the default revenue value to use for conversions # that do not specify a conversion value. Note that this value # should NOT be in micros. defaultRevenueValue => 2.50, # Optional: To upload fractional conversion credits, mark the upload conversion # as externally attributed. See # https://developers.google.com/adwords/api/docs/guides/conversion-tracking#importing_externally_attributed_conversions # to learn more about importing externally attributed conversions. # isExternallyAttributed => true }); push @conversion_trackers, $upload_conversion_tracker; my @operations = (); for my $conversion_tracker (@conversion_trackers) { # Create operation. my $conversion_operation = Google::Ads::AdWords::v201809::ConversionTrackerOperation->new({ operator => "ADD", operand => $conversion_tracker }); push @operations, $conversion_operation; } # Add conversion trackers. my $result = $client->ConversionTrackerService() ->mutate({operations => \@operations}); # Display conversion tracker. if ($result->get_value()) { foreach my $conversion_tracker (@{$result->get_value()}) { printf "Conversion tracker with ID %d, name \"%s\", status \"%s\" " . "and category \"%s\" was added.\n", $conversion_tracker->get_id(), $conversion_tracker->get_name(), $conversion_tracker->get_status(), $conversion_tracker->get_category(); if ($conversion_tracker ->isa("Google::Ads::AdWords::v201809::AdWordsConversionTracker")) { printf("Google global site tag:\n%s\n\n", $conversion_tracker->get_googleGlobalSiteTag()); printf("Google event snippet:\n%s\n\n", $conversion_tracker->get_googleEventSnippet()); } } } else { print "No conversion tracker was added."; } return 1; } # Don't run the example if the file is being included. if (abs_path($0) ne abs_path(__FILE__)) { return 1; } # Log SOAP XML request, response and API errors. Google::Ads::AdWords::Logging::enable_all_logging(); # Get AdWords Client, credentials will be read from ~/adwords.properties. my $client = Google::Ads::AdWords::Client->new({version => "v201809"}); # By default examples are set to die on any server returned fault. $client->set_die_on_faults(1); # Call the example add_conversion_trackers($client);
Create and populate a user list
#!/usr/bin/perl -w # # Copyright 2017, Google Inc. All Rights Reserved. # # 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 user list (a.k.a. audience) and uploads members # to populate the list. # # Note: It may take up to several hours for the list to be populated # with members. Email addresses must be associated with a Google account. # For privacy purposes, the user list size will show as zero until the list # has at least 1000 members. After that, the size will be rounded to the # two most significant digits. use strict; use lib "../../../lib"; use utf8; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::AddressInfo; use Google::Ads::AdWords::v201809::CrmBasedUserList; use Google::Ads::AdWords::v201809::Member; use Google::Ads::AdWords::v201809::MutateMembersOperand; use Google::Ads::AdWords::v201809::MutateMembersOperation; use Google::Ads::AdWords::v201809::UserListOperation; use Cwd qw(abs_path); use Data::Uniqid qw(uniqid); use Digest::SHA qw(sha256_hex); sub add_crm_based_user_list { my $client = shift; # Create a user list. my $user_list = Google::Ads::AdWords::v201809::CrmBasedUserList->new({ name => "Customer relationship management list #" . uniqid(), description => "A list of customers that originated from email addresses", # CRM-based user lists can use a membershipLifeSpan of 10000 to indicate # unlimited; otherwise normal values apply. membershipLifeSpan => "30", uploadKeyType => "CONTACT_INFO" }); # Create operation. my $operation = Google::Ads::AdWords::v201809::UserListOperation->new({ operator => "ADD", operand => $user_list }); # Add user list. my $result = $client->AdwordsUserListService()->mutate({operations => [$operation]}); # Display user list. if ($result->get_value()) { my $user_list_added = $result->get_value()->[0]; printf( "User list with name '%s' and ID '%d' was added.\n", $user_list_added->get_name(), $user_list_added->get_id()); } my @members = (); # Add e-mails to the user list. if ($result->get_value()) { # Use SHA256 to encode the e-mails. # All e-mails MUST be trimmed and lower-cased before encoding. my @email_list = ( 'customer1@example.com', 'customer2@example.com', ' Customer3@example.com ' ); foreach my $email (@email_list) { $email = sha256_hex(_to_normalized_string($email)); my $member = Google::Ads::AdWords::v201809::Member->new({ hashedEmail => $email }); push @members, $member; } my $first_name = "John"; my $last_name = "Doe"; my $country_code = "US"; my $zip_code = "10011"; my $address_info = Google::Ads::AdWords::v201809::AddressInfo->new({ # First and last name must be normalized and hashed. hashedFirstName => sha256_hex(_to_normalized_string($first_name)), hashedLastName => sha256_hex(_to_normalized_string($last_name)), # Country code and zip code are sent in plaintext. countryCode => $country_code, zipCode => $zip_code }); my $member_by_address = Google::Ads::AdWords::v201809::Member->new({ addressInfo => $address_info }); push @members, $member_by_address; my $userlist_id = $result->get_value()->[0]->get_id(); my $operand = Google::Ads::AdWords::v201809::MutateMembersOperand->new({ userListId => $userlist_id, membersList => \@members }); my $member_operation = Google::Ads::AdWords::v201809::MutateMembersOperation->new({ operator => "ADD", operand => $operand }); # Add members to the user list based on email addresses. my $result = $client->AdwordsUserListService() ->mutateMembers({operations => [$member_operation]}); # Display results. # Reminder: it may take up to 9 hours for the list to be populated # with members. for $user_list ($result->get_userLists()) { printf( "%d email addresses were uploaded to user list with name '%s' " . "and ID '%d' and are scheduled for review.\n", scalar(@email_list), $user_list->get_name(), $user_list->get_id()); } } else { print "No user list was added."; } return 1; } sub _to_normalized_string { my ($input_string) = @_; $input_string =~ s/^\s+|\s+$//g; $input_string = lc $input_string; return $input_string; } # Don't run the example if the file is being included. if (abs_path($0) ne abs_path(__FILE__)) { return 1; } # Log SOAP XML request, response and API errors. Google::Ads::AdWords::Logging::enable_all_logging(); # Get AdWords Client, credentials will be read from ~/adwords.properties. my $client = Google::Ads::AdWords::Client->new({version => "v201809"}); # By default examples are set to die on any server returned fault. $client->set_die_on_faults(1); # Call the example add_crm_based_user_list($client);
Create rule-based user lists
#!/usr/bin/perl -w # # Copyright 2017, Google Inc. All Rights Reserved. # # 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 two rule-based remarketing user lists: one with no site # visit date restrictions, and another that will only include users who visit # your site in the next six months. use strict; use lib "../../../lib"; use utf8; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::BasicUserList; use Google::Ads::AdWords::v201809::CombinedRuleUserList; use Google::Ads::AdWords::v201809::DateKey; use Google::Ads::AdWords::v201809::DateRuleItem; use Google::Ads::AdWords::v201809::DateSpecificRuleUserList; use Google::Ads::AdWords::v201809::ExpressionRuleUserList; use Google::Ads::AdWords::v201809::NumberKey; use Google::Ads::AdWords::v201809::NumberRuleItem; use Google::Ads::AdWords::v201809::Operator; use Google::Ads::AdWords::v201809::Rule; use Google::Ads::AdWords::v201809::RuleItem; use Google::Ads::AdWords::v201809::RuleItemGroup; use Google::Ads::AdWords::v201809::StringKey; use Google::Ads::AdWords::v201809::StringRuleItem; use Google::Ads::AdWords::v201809::UserListOperation; use Cwd qw(abs_path); use Data::Uniqid qw(uniqid); # Example main subroutine. sub add_rule_based_user_lists { my $client = shift; # First rule item group - users who visited the checkout page and had more # than one item in their shopping cart. my $checkout_string_rule_item = Google::Ads::AdWords::v201809::StringRuleItem->new({ key => Google::Ads::AdWords::v201809::StringKey->new( {name => "ecomm_pagetype"} ), op => "EQUALS", value => "checkout" }); my $checkout_rule_item = Google::Ads::AdWords::v201809::RuleItem->new( {StringRuleItem => $checkout_string_rule_item}); my $cart_size_number_rule_item = Google::Ads::AdWords::v201809::NumberRuleItem->new({ key => Google::Ads::AdWords::v201809::NumberKey->new({name => "cartsize"}), op => "GREATER_THAN", value => "1" }); my $cart_size_rule_item = Google::Ads::AdWords::v201809::RuleItem->new( {NumberRuleItem => $cart_size_number_rule_item}); # Combine the two rule items into a RuleItemGroup so AdWords will AND their # rules together. my $checkout_multiple_item_group = Google::Ads::AdWords::v201809::RuleItemGroup->new( {items => [$checkout_rule_item, $cart_size_rule_item]}); # Second rule item group - users who check out during the next three months. my ($sec, $min, $hour, $mday, $mon, $year) = localtime(); my $rule_start_date = sprintf("%d%02d%02d", ($year + 1900), ($mon + 1), $mday); ($sec, $min, $hour, $mday, $mon, $year) = localtime(time + 60 * 60 * 24 * 30 * 3); my $rule_end_date = sprintf("%d%02d%02d", ($year + 1900), ($mon + 1), $mday); my $start_date_date_rule_item = Google::Ads::AdWords::v201809::DateRuleItem->new({ key => Google::Ads::AdWords::v201809::DateKey->new({name => "checkoutdate"}), op => "AFTER", value => $rule_start_date }); my $start_date_rule_item = Google::Ads::AdWords::v201809::RuleItem->new( {DateRuleItem => $start_date_date_rule_item}); my $end_date_date_rule_item = Google::Ads::AdWords::v201809::DateRuleItem->new({ key => Google::Ads::AdWords::v201809::DateKey->new({name => "checkoutdate"}), op => "BEFORE", value => $rule_end_date }); my $end_date_rule_item = Google::Ads::AdWords::v201809::RuleItem->new( {DateRuleItem => $end_date_date_rule_item}); # Combine the date rule items into a RuleItemGroup. my $checked_out_next_three_months_item_group = Google::Ads::AdWords::v201809::RuleItemGroup->new( {items => [$start_date_rule_item, $end_date_rule_item]}); # Combine the rule item groups into a Rule so AdWords knows how to apply the # rules. my $rule = Google::Ads::AdWords::v201809::Rule->new({ groups => [ $checkout_multiple_item_group, $checked_out_next_three_months_item_group ], # ExpressionRuleUserLists can use either CNF or DNF for matching. CNF # means 'at least one item in each rule item group must match', and DNF # means 'at least one entire rule item group must match'. # DateSpecificRuleUserList only supports DNF. You can also omit the rule # type altogether to default to DNF. ruleType => 'DNF' }); # Third and fourth rule item groups # Visitors of a page who visited another page. my $site1_string_rule_item = Google::Ads::AdWords::v201809::StringRuleItem->new({ key => Google::Ads::AdWords::v201809::StringKey->new( {name => "url__"} ), op => "EQUALS", value => "example.com/example1" }); my $site1_rule_item = Google::Ads::AdWords::v201809::RuleItem->new( {StringRuleItem => $site1_string_rule_item}); my $site2_string_rule_item = Google::Ads::AdWords::v201809::StringRuleItem->new({ key => Google::Ads::AdWords::v201809::StringKey->new( {name => "url__"} ), op => "EQUALS", value => "example.com/example2" }); my $site2_rule_item = Google::Ads::AdWords::v201809::RuleItem->new( {StringRuleItem => $site2_string_rule_item}); # Create two RuleItemGroups to show that a visitor browsed two sites. my $site1_item_group = Google::Ads::AdWords::v201809::RuleItemGroup->new( {items => [$site1_rule_item]}); my $site2_item_group = Google::Ads::AdWords::v201809::RuleItemGroup->new( {items => [$site2_rule_item]}); # Create two rules to show that a visitor browsed two sites. my $user_visited_site1_rule = Google::Ads::AdWords::v201809::Rule->new({ groups => [$site1_item_group] }); my $user_visited_site2_rule = Google::Ads::AdWords::v201809::Rule->new({ groups => [$site2_item_group] }); # Create the user list with no restrictions on site visit date. ($sec, $min, $hour, $mday, $mon, $year) = localtime(); my $creation_time = sprintf( "%d%02d%02d_%02d%02d%02d", ($year + 1900), ($mon + 1), $mday, $hour, $min, $sec ); my $expression_user_list = Google::Ads::AdWords::v201809::ExpressionRuleUserList->new({ name => "Expression based user list created at ${creation_time}", description => "Users who checked out in six month window OR " . "visited the checkout page with more than one item in their cart", rule => $rule, # Optional: Set the prepopulationStatus to REQUESTED to include past # users in the user list. prepopulationStatus => "REQUESTED" }); # Create the user list restricted to users who visit your site within the # next six months. ($sec, $min, $hour, $mday, $mon, $year) = localtime(); my $list_start_date = sprintf("%d%02d%02d", ($year + 1900), ($mon + 1), $mday); ($sec, $min, $hour, $mday, $mon, $year) = localtime(time + 60 * 60 * 24 * 30 * 6); my $list_end_date = sprintf("%d%02d%02d", ($year + 1900), ($mon + 1), $mday); my $date_user_list = Google::Ads::AdWords::v201809::DateSpecificRuleUserList->new({ name => "Date rule user list created at ${creation_time}", description => "Users who visited the site between " . "${list_start_date} and ${list_end_date} and checked out " . "in three month window OR visited the checkout page with " . "more than one item in their cart.", rule => $rule, startDate => $list_start_date, endDate => $list_end_date }); # Create the user list where "Visitors of a page who did visit another page". # To create a user list where "Visitors of a page who did not visit another # page", change the ruleOperator from AND to AND_NOT. my $combined_user_list = Google::Ads::AdWords::v201809::CombinedRuleUserList->new({ name => "Combined rule user list created at ${creation_time}", description => "Users who visited two sites.", leftOperand => $user_visited_site1_rule, rightOperand => $user_visited_site2_rule, ruleOperator => "AND" }); # Create operations to add the user lists. my $operations = [ Google::Ads::AdWords::v201809::UserListOperation->new({ operator => "ADD", operand => $expression_user_list } ), Google::Ads::AdWords::v201809::UserListOperation->new({ operator => "ADD", operand => $date_user_list } ), Google::Ads::AdWords::v201809::UserListOperation->new({ operator => "ADD", operand => $combined_user_list })]; # Submit the operations. my $result = $client->AdwordsUserListService()->mutate({operations => $operations}); if ($result->get_value()) { foreach my $user_list (@{$result->get_value}) { printf "User list added with ID %d, name '%s', status '%s', list " . "type '%s', accountUserListStatus '%s', description '%s'.\n", $user_list->get_id(), $user_list->get_name(), $user_list->get_status(), $user_list->get_listType(), $user_list->get_accountUserListStatus(), $user_list->get_description(); } } else { print "No user list was added."; } return 1; } # Don't run the example if the file is being included. if (abs_path($0) ne abs_path(__FILE__)) { return 1; } # Log SOAP XML request, response and API errors. Google::Ads::AdWords::Logging::enable_all_logging(); # Get AdWords Client, credentials will be read from ~/adwords.properties. my $client = Google::Ads::AdWords::Client->new({version => "v201809"}); # By default examples are set to die on any server returned fault. $client->set_die_on_faults(1); # Call the example add_rule_based_user_lists($client);
Import conversion adjustments for existing conversions
#!/usr/bin/perl -w # # Copyright 2018 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 # # https://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 code example imports conversion adjustments for conversions that already # exist. To set up a conversion tracker, run the add_conversion_tracker.pl # example. use strict; use lib "../../../lib"; use utf8; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::GclidOfflineConversionAdjustmentFeed; use Google::Ads::AdWords::v201809::OfflineConversionAdjustmentFeedOperation; use Cwd qw(abs_path); use Data::Uniqid qw(uniqid); # Replace with valid values of your account. my $conversion_name = "INSERT_CONVERSION_NAME_HERE"; my $gclid = "INSERT_GCLID_HERE"; my $adjustment_type = "INSERT_ADJUSTMENT_TYPE_HERE"; my $conversion_time = "INSERT_CONVERSION_TIME_HERE"; my $adjustment_time = "INSERT_ADJUSTMENT_TIME_HERE"; my $adjusted_value = "INSERT_ADJUST_VALUE_HERE"; # Example main subroutine. sub upload_conversion_adjustment { my ($client, $conversion_name, $gclid, $adjustment_type, $conversion_time, $adjustment_time, $adjusted_value) = @_; # This example demonstrates adjusting one conversion, but you can add more # than one operation to adjust more in a single mutate request. my @conversion_adjustment_operations = (); # Associate conversion adjustments with the existing named conversion # tracker. The GCLID should have been uploaded before with a conversion. my $feed = Google::Ads::AdWords::v201809::GclidOfflineConversionAdjustmentFeed->new({ conversionName => $conversion_name, adjustmentType => $adjustment_type, conversionTime => $conversion_time, adjustmentTime => $adjustment_time, adjustedValue => $adjusted_value, googleClickId => $gclid, }); my $conversion_adjustment_operation = Google::Ads::AdWords::v201809::OfflineConversionAdjustmentFeedOperation->new({ operator => "ADD", operand => $feed }); push @conversion_adjustment_operations, $conversion_adjustment_operation; # Add the conversion adjustment. my $result = $client->OfflineConversionAdjustmentFeedService() ->mutate({operations => \@conversion_adjustment_operations}); # Display results. if ($result->get_value()) { foreach my $adjustment_feed (@{$result->get_value()}) { printf "Uploaded conversion adjusted value of \"%s\" for Google Click " . "ID \"%s\"\n", $adjustment_feed->get_adjustedValue(), $adjustment_feed->get_googleClickId(); } } else { print "No conversion adjustments were added.\n"; return; } return 1; } # Don't run the example if the file is being included. if (abs_path($0) ne abs_path(__FILE__)) { return 1; } # Log SOAP XML request, response and API errors. Google::Ads::AdWords::Logging::enable_all_logging(); # Get AdWords Client, credentials will be read from ~/adwords.properties. my $client = Google::Ads::AdWords::Client->new({version => "v201809"}); # By default examples are set to die on any server returned fault. $client->set_die_on_faults(1); # Call the example upload_conversion_adjustment($client, $conversion_name, $gclid, $adjustment_type, $conversion_time, $adjustment_time, $adjusted_value);
Import offline call conversions
#!/usr/bin/perl -w # # Copyright 2017, Google Inc. All Rights Reserved. # # 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 code example imports offline call conversion values for calls # related to the ads in your account. To set up a conversion tracker, run the # add_conversion_tracker.pl example using UploadCallConversion as the # conversion tracker. use strict; use lib "../../../lib"; use utf8; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::OfflineCallConversionFeed; use Google::Ads::AdWords::v201809::OfflineCallConversionFeedOperation; use Cwd qw(abs_path); use Data::Uniqid qw(uniqid); # Replace with valid values of your account. my $caller_id = "INSERT_CALLER_ID_HERE"; # For times use the format yyyyMMdd HHmmss tz. For more details on formats, # see: https://developers.google.com/adwords/api/docs/appendix/codes-formats#date-and-time-formats # For time zones, see: https://developers.google.com/adwords/api/docs/appendix/codes-formats#timezone-ids my $call_start_time = "INSERT_CALL_START_TIME_HERE"; my $conversion_name = "INSERT_CONVERSION_NAME_HERE"; my $conversion_time = "INSERT_CONVERSION_TIME_HERE"; my $conversion_value = "INSERT_CONVERSION_VALUE_HERE"; # Example main subroutine. sub upload_offline_call_conversions { my $client = shift; my $caller_id = shift; my $call_start_time = shift; my $conversion_name = shift; my $conversion_time = shift; my $conversion_value = shift; my @offline_call_conversion_operations = (); # Associate offline call conversions with the existing named # conversion tracker. If this tracker was newly created, it may be a # few hours before it can accept conversions. my $feed = Google::Ads::AdWords::v201809::OfflineCallConversionFeed->new({ callerId => $caller_id, callStartTime => $call_start_time, conversionName => $conversion_name, conversionTime => $conversion_time, conversionValue => $conversion_value }); my $offline_call_conversion_operation = Google::Ads::AdWords::v201809::OfflineCallConversionFeedOperation->new({ operator => "ADD", operand => $feed }); push @offline_call_conversion_operations, $offline_call_conversion_operation; # This example uploads only one call conversion, but you can upload multiple # call conversions by passing additional operations. my $result = $client->OfflineCallConversionFeedService() ->mutate({operations => \@offline_call_conversion_operations}); # Display results. if ($result->get_value()) { foreach my $feed_result (@{$result->get_value()}) { printf "Uploaded offline call conversion value of \"%s\" for caller ID " . "\"%s\".\n", $feed_result->get_conversionValue(), $feed_result->get_callerId(); } } else { print "No offline call conversions were added.\n"; return; } return 1; } # Don't run the example if the file is being included. if (abs_path($0) ne abs_path(__FILE__)) { return 1; } # Log SOAP XML request, response and API errors. Google::Ads::AdWords::Logging::enable_all_logging(); # Get AdWords Client, credentials will be read from ~/adwords.properties. my $client = Google::Ads::AdWords::Client->new({version => "v201809"}); # By default examples are set to die on any server returned fault. $client->set_die_on_faults(1); # Call the example upload_offline_call_conversions($client, $caller_id, $call_start_time, $conversion_name, $conversion_time, $conversion_value);
Import offline click conversions
#!/usr/bin/perl -w # # Copyright 2017, Google Inc. All Rights Reserved. # # 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 code example imports offline call conversion values for calls to # your account. To get Google Click ID for a click, run # CLICK_PERFORMANCE_REPORT. To set up a conversion tracker, run the # add_conversion_tracker.pl example. use strict; use lib "../../../lib"; use utf8; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::UploadConversion; use Google::Ads::AdWords::v201809::ConversionTrackerOperation; use Google::Ads::AdWords::v201809::OfflineCallConversionFeed; use Google::Ads::AdWords::v201809::OfflineCallConversionFeedOperation; use Cwd qw(abs_path); use Data::Uniqid qw(uniqid); # Replace with valid values of your account. my $conversion_name = "INSERT_CONVERSION_NAME_HERE"; my $gclid = "INSERT_GCLID_HERE"; my $conversion_time = "INSERT_CONVERSION_TIME_HERE"; my $conversion_value = "INSERT_CONVERSION_VALUE_HERE"; # Example main subroutine. sub upload_offline_conversions { my $client = shift; my $conversion_name = shift; my $gclid = shift; my $conversion_time = shift; my $conversion_value = shift; my @offline_conversion_operations = (); # Associate offline conversions with the existing named conversion tracker. If # this tracker was newly created, it may be a few hours before it can accept # conversions. my $feed = Google::Ads::AdWords::v201809::OfflineCallConversionFeed->new({ conversionName => $conversion_name, conversionTime => $conversion_time, conversionValue => $conversion_value, googleClickId => $gclid }); my $offline_conversion_operation = Google::Ads::AdWords::v201809::OfflineCallConversionFeedOperation->new({ operator => "ADD", operand => $feed }); push @offline_conversion_operations, $offline_conversion_operation; # Add the upload conversion. my $feed_result = $client->OfflineCallConversionFeedService() ->mutate({operations => \@offline_conversion_operations}); # Display results. if ($feed_result->get_value()) { foreach my $oc_feed (@{$feed_result->get_value()}) { printf "Uploaded offline conversion value of \"%s\" for Google Click " . "ID \"%s\" was created.\n", $oc_feed->get_conversionName(), $oc_feed->get_googleClickId(); } } else { print "No offline conversion were added.\n"; return; } return 1; } # Don't run the example if the file is being included. if (abs_path($0) ne abs_path(__FILE__)) { return 1; } # Log SOAP XML request, response and API errors. Google::Ads::AdWords::Logging::enable_all_logging(); # Get AdWords Client, credentials will be read from ~/adwords.properties. my $client = Google::Ads::AdWords::Client->new({version => "v201809"}); # By default examples are set to die on any server returned fault. $client->set_die_on_faults(1); # Call the example upload_offline_conversions($client, $conversion_name, $gclid, $conversion_time, $conversion_value);
Upload offline data for store sales transactions
#!/usr/bin/perl -w # # Copyright 2017, Google Inc. All Rights Reserved. # # 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 code example shows how to upload offline data for store sales # transactions. use strict; use lib "../../../lib"; use utf8; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::ConversionTrackerOperation; use Google::Ads::AdWords::v201809::FirstPartyUploadMetadata; use Google::Ads::AdWords::v201809::Money; use Google::Ads::AdWords::v201809::MoneyWithCurrency; use Google::Ads::AdWords::v201809::OfflineCallConversionFeed; use Google::Ads::AdWords::v201809::OfflineCallConversionFeedOperation; use Google::Ads::AdWords::v201809::OfflineData; use Google::Ads::AdWords::v201809::OfflineDataUploadOperation; use Google::Ads::AdWords::v201809::StoreSalesTransaction; use Google::Ads::AdWords::v201809::ThirdPartyUploadMetadata; use Google::Ads::AdWords::v201809::UploadConversion; use Google::Ads::AdWords::v201809::UploadMetadata; use Google::Ads::AdWords::v201809::UserIdentifier; use Cwd qw(abs_path); use Data::Uniqid qw(uniqid); use Digest::SHA qw(sha256_hex); # Replace with valid values of your account. # The external upload ID can be any number that you use to keep track of your # uploads. my $external_upload_id = 'INSERT_EXTERNAL_UPLOAD_ID'; # Insert the conversion type name that you'd like to attribute this upload to. my $conversion_name = 'INSERT_CONVERSION_NAME'; # Change the below constant to ThirdPartyUploadMetadata if uploading third # party data. my $store_sales_upload_common_metadata_type = "FirstPartyUploadMetadata"; # Insert email addresses below for creating user identifiers. my @email_addresses = ("EMAIL_ADDRESS_1", "EMAIL_ADDRESS_2"); # The three constants below are needed when uploading third party data. # You can safely ignore them if you are uploading first party data. # For times, use the format yyyyMMdd HHmmss tz. For more details on formats, # see: # https://developers.google.com/adwords/api/docs/appendix/codes-formats#date-and-time-formats # For time zones, see: # https://developers.google.com/adwords/api/docs/appendix/codes-formats#timezone-ids my $advertiser_upload_time = "INSERT_ADVERTISER_UPLOAD_TIME"; my $bridge_map_version_id = "INSERT_BRIDGE_MAP_VERSION_ID"; my $partner_id = "INSERT_PARTNER_ID"; # Example main subroutine. sub upload_offline_data { my ( $client, $external_upload_id, $conversion_name, $store_sales_upload_common_metadata_type, $email_addresses, $advertiser_upload_time, $bridge_map_version_id, $partner_id ) = @_; # Create the first offline data for upload. # This transaction occurred 7 days ago with amount of 200 USD. my ($second, $minute, $hour, $mday, $mon, $year) = localtime(time - 60 * 60 * 24 * 7); my $transaction_time_1 = sprintf( "%d%02d%02d %02d%02d%02d", ($year + 1900), ($mon + 1), $mday, $hour, $minute, $second ); my $transaction_amount_1 = 200000000; my $transaction_currency_code_1 = 'USD'; my $user_identifier_list_1 = [ _create_user_identifier('HASHED_EMAIL', $email_addresses->[0]), _create_user_identifier('STATE', 'New York')]; my $offline_data_1 = _create_offline_data( $transaction_time_1, $transaction_amount_1, $transaction_currency_code_1, $conversion_name, $user_identifier_list_1 ); # Create the second offline data for upload. # This transaction occurred 14 days ago with amount of 450 EUR. ($second, $minute, $hour, $mday, $mon, $year) = localtime(time - 60 * 60 * 24 * 14); my $transaction_time_2 = sprintf( "%d%02d%02d %02d%02d%02d", ($year + 1900), ($mon + 1), $mday, $hour, $minute, $second ); my $transaction_amount_2 = 450000000; my $transaction_currency_code_2 = 'EUR'; my $user_identifier_list_2 = [ _create_user_identifier('HASHED_EMAIL', $email_addresses->[1]), _create_user_identifier('STATE', 'California')]; my $offline_data_2 = _create_offline_data( $transaction_time_2, $transaction_amount_2, $transaction_currency_code_2, $conversion_name, $user_identifier_list_2 ); # Create offline data upload object. my $offline_data_upload = undef; if ($store_sales_upload_common_metadata_type eq 'FirstPartyUploadMetadata') { $offline_data_upload = Google::Ads::AdWords::v201809::OfflineDataUpload->new({ externalUploadId => $external_upload_id, offlineDataList => [$offline_data_1, $offline_data_2], uploadType => 'STORE_SALES_UPLOAD_FIRST_PARTY', uploadMetadata => Google::Ads::AdWords::v201809::UploadMetadata->new({ StoreSalesUploadCommonMetadata => Google::Ads::AdWords::v201809::FirstPartyUploadMetadata->new({ loyaltyRate => "1.0", transactionUploadRate => "1.0", }) }) }); } elsif ( $store_sales_upload_common_metadata_type eq 'ThirdPartyUploadMetadata') { $offline_data_upload = Google::Ads::AdWords::v201809::OfflineDataUpload->new({ externalUploadId => $external_upload_id, offlineDataList => [$offline_data_1, $offline_data_2], # Set the type and metadata of this upload. uploadType => 'STORE_SALES_UPLOAD_THIRD_PARTY', uploadMetadata => Google::Ads::AdWords::v201809::UploadMetadata->new({ StoreSalesUploadCommonMetadata => Google::Ads::AdWords::v201809::ThirdPartyUploadMetadata->new({ loyaltyRate => "1.0", transactionUploadRate => "1.0", advertiserUploadTime => $advertiser_upload_time, validTransactionRate => "1.0", partnerMatchRate => "1.0", partnerUploadRate => "1.0", bridgeMapVersionId => $bridge_map_version_id, partnerId => $partner_id }) }) }); } # Create an offline data upload operation. my @operations = (); my $offline_data_upload_operation = Google::Ads::AdWords::v201809::OfflineDataUploadOperation->new({ operator => 'ADD', operand => $offline_data_upload }); push @operations, $offline_data_upload_operation; # Upload offline data on the server and print some information. my $result = $client->OfflineDataUploadService()->mutate({operations => \@operations}); $offline_data_upload = $result->get_value()->[0]; printf( "Uploaded offline data with external upload ID %d and upload status" . " %s\n", $offline_data_upload->get_externalUploadId(), $offline_data_upload->get_uploadStatus()); # Print any partial failure errors from the response. if ($result->get_partialFailureErrors()) { foreach my $api_error (@{$result->get_partialFailureErrors()}) { # Get the index of the failed operation from the error's field path # elements. my $operation_index = _get_field_path_element_index($api_error, "operations"); if (defined($operation_index)) { my $failed_offline_data_upload = $operations[$operation_index]->get_operand(); # Get the index of the entry in the offline data list from the error's # field path elements. my $offline_data_list_index = _get_field_path_element_index($api_error, "offlineDataList"); printf("Offline data list entry %d in operation %d with external" . " upload ID %d and type \"%s\" has triggered a failure for the " . " following reason: \"%s\".\n", $offline_data_list_index, $operation_index, $offline_data_upload->get_externalUploadId(), $offline_data_upload->get_uploadType(), $api_error->get_errorString()); } else { printf "A failure for the following reason: \"%s\" has occurred.\n", $api_error->get_errorString(); } } } return 1; } # Returns the FieldPathElement#getIndex() for the specified field name, if # present in the error's field path elements. sub _get_field_path_element_index { my ($api_error, $field) = @_; my $field_path_elements = $api_error->get_fieldPathElements(); if (!$field_path_elements) { return; } for (my $i = 0 ; $i < scalar $field_path_elements; $i++) { my $field_path_element = $field_path_elements->[$i]; if ($field eq $field_path_element->get_field()) { return $field_path_element->get_index(); } } return; } # Creates the offline data from the specified transaction time, transaction # micro amount, transaction currency, conversion name and user identifier # list. sub _create_offline_data { my ( $transaction_time, $transaction_micro_amount, $transaction_currency, $conversion_name, $user_identifier_list ) = @_; my $store_sales_transaction = Google::Ads::AdWords::v201809::StoreSalesTransaction->new({ conversionName => $conversion_name, # For times use the format yyyyMMdd HHmmss [tz]. # For details, see # https://developers.google.com/adwords/api/docs/appendix/codes-formats#date-and-time-formats transactionTime => $transaction_time, userIdentifiers => $user_identifier_list, transactionAmount => Google::Ads::AdWords::v201809::MoneyWithCurrency->new({ currencyCode => $transaction_currency, money => Google::Ads::AdWords::v201809::Money->new( {microAmount => $transaction_micro_amount})})}); # There is a temporary issue with the WSDL in which there is a # namespace conflict. As a workaround, the namespace is explicitly set here. $Google::Ads::AdWords::v201809::MoneyWithCurrency::OBJECT_NAMESPACE = "https://adwords.google.com/api/adwords/rm/v201809"; my $offline_data = Google::Ads::AdWords::v201809::OfflineData->new({ StoreSalesTransaction => $store_sales_transaction }); return $offline_data; } # Creates a user identifier from the specified type and value. sub _create_user_identifier { my ($type, $value) = @_; # If the user identifier type is a hashed type, also call hash function # on the value. if ($type =~ /^HASHED_/) { $value = sha256_hex($value); } my $user_identifier = Google::Ads::AdWords::v201809::UserIdentifier->new({ userIdentifierType => $type, value => $value }); return $user_identifier; } # Don't run the example if the file is being included. if (abs_path($0) ne abs_path(__FILE__)) { return 1; } # Log SOAP XML request, response and API errors. Google::Ads::AdWords::Logging::enable_all_logging(); # Get AdWords Client, credentials will be read from ~/adwords.properties. my $client = Google::Ads::AdWords::Client->new({version => "v201809"}); # By default examples are set to die on any server returned fault. $client->set_die_on_faults(0); # Setting partial failures to true as this example show how to handle them. $client->set_partial_failure(1); # Call the example upload_offline_data( $client, $external_upload_id, $conversion_name, $store_sales_upload_common_metadata_type, \@email_addresses, $advertiser_upload_time, $bridge_map_version_id, $partner_id );