The code samples below provide examples for managing campaigns using the AdWords API. Client Library.
Add a campaign group and set its performance target
#!/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 a campaign group and sets a performance target for # that group. To get campaigns, run get_campaigns.pl. To download reports, run # download_criteria_report_with_awql.pl. use strict; use lib "../../../lib"; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::Campaign; use Google::Ads::AdWords::v201809::CampaignGroup; use Google::Ads::AdWords::v201809::CampaignGroupOperation; use Google::Ads::AdWords::v201809::CampaignGroupPerformanceTarget; use Google::Ads::AdWords::v201809::CampaignGroupPerformanceTargetOperation; use Google::Ads::AdWords::v201809::CampaignOperation; use Google::Ads::AdWords::v201809::Money; use Google::Ads::AdWords::v201809::PerformanceTarget; use Cwd qw(abs_path); use Data::Uniqid qw(uniqid); # Replace with valid values of your account. my $campaign_ids = ["INSERT_CAMPAIGN_ID_1_HERE", "INSERT_CAMPAIGN_ID_2_HERE"]; # Example main subroutine. sub add_campaign_groups_and_performance_targets { my $client = shift; my $campaign_ids = shift; my $campaign_group = _create_campaign_group($client); _add_campaigns_to_group($client, $campaign_group->get_id(), $campaign_ids); _create_performance_target($client, $campaign_group->get_id()); printf( "Campaign group and its performance target were setup successfully.\n"); return 1; } # Create a campaign group. sub _create_campaign_group { my ($client) = @_; # Create the campaign group. my $campaign_group = Google::Ads::AdWords::v201809::CampaignGroup->new({ name => sprintf("Mars campaign group - #%s", uniqid()), }); # Create the operation. my $operation = Google::Ads::AdWords::v201809::CampaignGroupOperation->new({ operator => "ADD", operand => $campaign_group }); my $result = $client->CampaignGroupService()->mutate({operations => [$operation]}); $campaign_group = $result->get_value()->[0]; printf( "Campaign group with ID %d and name '%s' was created.\n", $campaign_group->get_id(), $campaign_group->get_name()); return $campaign_group; } # Add multiple campaigns to the campaign group. sub _add_campaigns_to_group { my ($client, $campaign_group_id, $campaign_ids) = @_; my @operations = (); foreach my $campaign_id (@{$campaign_ids}) { my $campaign = Google::Ads::AdWords::v201809::Campaign->new({ id => $campaign_id, campaignGroupId => $campaign_group_id }); # Create operation. my $campaign_operation = Google::Ads::AdWords::v201809::CampaignOperation->new({ operator => "SET", operand => $campaign }); push @operations, $campaign_operation; } # Add campaigns. my $result = $client->CampaignService()->mutate({operations => \@operations}); # Display campaigns. foreach my $campaign (@{$result->get_value()}) { printf "Campaign with ID %d was added to campaign group with ID %d.\n", $campaign->get_id(), $campaign->get_campaignGroupId(); } } # Creates a performance target for the campaign group. sub _create_performance_target { my ($client, $campaign_group_id) = @_; # Start the performance target today, and run it for the next 90 days. my (undef, undef, undef, $mday, $mon, $year) = localtime(time); my $start_date = sprintf("%d%02d%02d", ($year + 1900), ($mon + 1), $mday); (undef, undef, undef, $mday, $mon, $year) = localtime(time + 60 * 60 * 24 * 90); my $end_date = sprintf("%d%02d%02d", ($year + 1900), ($mon + 1), $mday); my $performance_target = Google::Ads::AdWords::v201809::PerformanceTarget->new({ # Keep the CPC for the campaigns < $3. efficiencyTargetType => "CPC_LESS_THAN_OR_EQUAL_TO", efficiencyTargetValue => 3000000, # Keep the maximum spend under $50. spendTargetType => "MAXIMUM", spendTarget => Google::Ads::AdWords::v201809::Money->new({microAmount => 500000000}), # Aim for at least 3000 clicks. volumeTargetValue => 3000, volumeGoalType => "MAXIMIZE_CLICKS", startDate => $start_date, endDate => $end_date }); # Create the performance target. my $campaign_group_performance_target = Google::Ads::AdWords::v201809::CampaignGroupPerformanceTarget->new({ campaignGroupId => $campaign_group_id, performanceTarget => $performance_target }); # Create the operation. my $operation = Google::Ads::AdWords::v201809::CampaignGroupPerformanceTargetOperation->new( { operator => "ADD", operand => $campaign_group_performance_target }); my $result = $client->CampaignGroupPerformanceTargetService() ->mutate({operations => [$operation]}); $campaign_group_performance_target = $result->get_value()->[0]; printf( "Campaign performance target with ID %d was added for campaign group ID " . "%d.\n", $campaign_group_performance_target->get_id(), $campaign_group_performance_target->get_campaignGroupId()); } # 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_campaign_groups_and_performance_targets($client, $campaign_ids);
Add a label to multiple campaigns
#!/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 label to multiple campaigns. use strict; use lib "../../../lib"; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::Campaign; use Google::Ads::AdWords::v201809::CampaignLabel; use Google::Ads::AdWords::v201809::CampaignLabelOperation; use Cwd qw(abs_path); use Data::Uniqid qw(uniqid); # Replace with valid values of your account. my $campaign_ids = ["INSERT_CAMPAIGN_ID_1_HERE", "INSERT_CAMPAIGN_ID_2_HERE"]; my $label_id = "INSERT_LABEL_ID_HERE"; # Example main subroutine. sub add_campaign_labels { my $client = shift; my $campaign_ids = shift; my $label_id = shift; my @operations = (); # Create label operations. foreach my $campaign_id (@{$campaign_ids}) { my $campaign_label = Google::Ads::AdWords::v201809::CampaignLabel->new({ campaignId => $campaign_id, labelId => $label_id }); my $campaign_label_operation = Google::Ads::AdWords::v201809::CampaignLabelOperation->new({ operator => "ADD", operand => $campaign_label }); push @operations, $campaign_label_operation; } # Add campaign labels. my $result = $client->CampaignService()->mutateLabel({operations => \@operations}); # Display campaign labels. foreach my $campaign_label (@{$result->get_value()}) { printf "Campaign label for campaign ID %d and label ID %d was added.\n", $campaign_label->get_campaignId(), $campaign_label->get_labelId(); } 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_campaign_labels($client, $campaign_ids, $label_id);
Add a campaign using BatchJobService
#!/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 illustrates how to perform multiple requests using the # BatchJobService. use strict; use lib "../../../lib"; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::AdGroup; use Google::Ads::AdWords::v201809::AdGroupAd; use Google::Ads::AdWords::v201809::AdGroupAdOperation; use Google::Ads::AdWords::v201809::AdGroupCriterionOperation; use Google::Ads::AdWords::v201809::AdGroupOperation; use Google::Ads::AdWords::v201809::BatchJob; use Google::Ads::AdWords::v201809::BatchJobOperation; use Google::Ads::AdWords::v201809::BiddableAdGroupCriterion; use Google::Ads::AdWords::v201809::Budget; use Google::Ads::AdWords::v201809::BudgetOperation; use Google::Ads::AdWords::v201809::CampaignCriterionOperation; use Google::Ads::AdWords::v201809::CampaignOperation; use Google::Ads::AdWords::v201809::CpcBid; use Google::Ads::AdWords::v201809::ExpandedTextAd; use Google::Ads::AdWords::v201809::Keyword; use Google::Ads::AdWords::v201809::Money; use Google::Ads::AdWords::v201809::NegativeCampaignCriterion; use Google::Ads::AdWords::v201809::Predicate; use Google::Ads::AdWords::v201809::Paging; use Google::Ads::AdWords::v201809::Selector; use Google::Ads::AdWords::Utilities::BatchJobHandler; use Google::Ads::AdWords::Utilities::BatchJobHandlerError; use Cwd qw(abs_path); use Data::Uniqid qw(uniqid); # Set a timeout to fail if the job does not complete in a specified amount # of time. use constant JOB_TIMEOUT_IN_MILLISECONDS => 180000; # The time to sleep in between polls will start at this time. Then an # exponential back-off will be instituted. use constant JOB_BASE_WAITTIME_IN_MILLISECONDS => 30000; use constant NUMBER_OF_CAMPAIGNS_TO_ADD => 2; use constant NUMBER_OF_ADGROUPS_TO_ADD => 2; use constant NUMBER_OF_KEYWORDS_TO_ADD => 5; # Temporary IDs are negative. Keep decrementing the number in order to always # have a unique temporary ID. my $temporary_id = -1; # Example main subroutine. sub add_complete_campaign_using_batch_job { my $client = shift; # Create a batch job, which returns an upload URL to upload the batch # operations and a job ID to track the job. my $operation = Google::Ads::AdWords::v201809::BatchJobOperation->new({ operator => 'ADD', operand => Google::Ads::AdWords::v201809::BatchJob->new({})}); my $batch_job_result = $client->BatchJobService()->mutate({operations => [$operation]}); if (!$batch_job_result->get_value()) { print "A batch job could not be created. No operations were uploaded.\n"; return 1; } my $batch_job = $batch_job_result->get_value()->[0]; printf("Batch job with ID %d was created.\n\tInitial upload URL: '%s'\n", $batch_job->get_id(), $batch_job->get_uploadUrl()->get_url()); my @operations = (); # Create and add an operation to create a new budget. my $budget_operation = _create_budget_operation(); push @operations, $budget_operation; # Create and add operations to create new campaigns. my @campaign_operations = _create_campaign_operations($budget_operation); push @operations, @campaign_operations; # Create and add operations to create new negative keyword criteria # for each campaign. my @campaign_criterion_operations = _create_campaign_criterion_operations(@campaign_operations); push @operations, @campaign_criterion_operations; # Create and add operations to create new ad groups. my @ad_group_operations = _create_ad_group_operations(@campaign_operations); push @operations, @ad_group_operations; # Create and add operations to create new ad group criteria (keywords). my @ad_group_criterion_operations = _create_ad_group_criterion_operations(@ad_group_operations); push @operations, @ad_group_criterion_operations; # Create and add operations to create new ad group ads (text ads). my @ad_group_ad_operations = _create_ad_group_ad_operations(@ad_group_operations); push @operations, @ad_group_ad_operations; # Get an instance of a utility that helps with uploading batch operations. my $batch_job_handler = Google::Ads::AdWords::Utilities::BatchJobHandler->new({client => $client}); # Convert the list of operations into XML. # POST the XML to the upload URL. my $upload_result = $batch_job_handler->upload_operations(\@operations, $batch_job->get_uploadUrl()->get_url()); if (!$upload_result) { printf("%s Error. %s\n", $upload_result->get_type(), $upload_result->get_description()); if ($upload_result->get_type() eq "HTTP") { printf( "Type: %s\nCode: %s\nMessage: %s\nTrigger: %s\nField Path: %s\n", $upload_result->get_http_type(), $upload_result->get_http_response_code(), $upload_result->get_http_response_message(), $upload_result->get_http_trigger(), $upload_result->get_http_field_path()); } return 1; } printf("\tOperations uploaded to upload URL: '%s'\n", $upload_result->get_resumable_upload_uri()); # Verify that the operations completed. # This will poll until the job has completed or the timeout has expired. my $verify_result = _verify_operations($client, $batch_job_handler, $batch_job); # Display the results. my $error = $verify_result->{error}; my $job_result = $verify_result->{batch_job}; my $operations_result = $verify_result->{result}; printf("Job with ID %d has completed with a status of '%s'.\n", $job_result->get_id(), $job_result->get_status()); if (defined $error) { printf("%s Error. %s\n", $error->get_type(), $error->get_description()); if ($error->get_type() eq "PROCESSING") { printf("%s\n", $error->get_processing_errors()); } if ($error->get_type() eq "HTTP") { printf( "Type: %s\nCode: %s\nMessage: %s\nTrigger: %s\nField Path: %s\n", $error->get_http_type(), $error->get_http_response_code(), $error->get_http_response_message(), $error->get_http_trigger(), $error->get_http_field_path()); } } if ($operations_result) { for my $item (@{$operations_result->get_rval()}) { if ($item->get_errorList()) { printf("Error on index %d: %s\n", $item->get_index(), $item->get_errorList()->get_errors()); } else { # Print the XML output. printf("Successful on index %d\n%s\n", $item->get_index(), $item); } } } return 1; } # Create a BudgetOperation for the Campaign. sub _create_budget_operation { my $budget = Google::Ads::AdWords::v201809::Budget->new({ # Required attributes. budgetId => _next_id(), name => "Interplanetary budget #" . uniqid(), amount => Google::Ads::AdWords::v201809::Money->new({microAmount => 5000000}), deliveryMethod => "STANDARD" }); my $budget_operation = Google::Ads::AdWords::v201809::BudgetOperation->new({ operator => "ADD", operand => $budget }); return $budget_operation; } # Create a CampaignOperations to add Campaigns. sub _create_campaign_operations { my ($budget_operation) = @_; my @campaign_operations = (); for (my $i = 1 ; $i < NUMBER_OF_CAMPAIGNS_TO_ADD ; $i++) { my $campaign = Google::Ads::AdWords::v201809::Campaign->new({ id => _next_id(), name => "Batch Campaign #" . uniqid(), advertisingChannelType => "SEARCH", # Recommendation: Set the campaign to PAUSED when creating it to stop # the ads from immediately serving. Set to ENABLED once you've added # targeting and the ads are ready to serve. status => "PAUSED", # Bidding strategy (required). biddingStrategyConfiguration => Google::Ads::AdWords::v201809::BiddingStrategyConfiguration->new({ biddingStrategyType => "MANUAL_CPC", # You can optionally provide a bidding scheme in place of the type. } ), budget => Google::Ads::AdWords::v201809::Budget->new( {budgetId => $budget_operation->get_operand()->get_budgetId()})}); my $campaign_operation = Google::Ads::AdWords::v201809::CampaignOperation->new({ operator => "ADD", operand => $campaign }); push @campaign_operations, $campaign_operation; } return @campaign_operations; } # Create CampaignCriterionOperations. sub _create_campaign_criterion_operations() { my (@campaign_operations) = @_; my @campaign_criterion_operations = (); for my $campaign_operation (@campaign_operations) { # Create keyword. my $keyword = Google::Ads::AdWords::v201809::Keyword->new( {matchType => "BROAD", text => "venus"}); my $negative_criterion = Google::Ads::AdWords::v201809::NegativeCampaignCriterion->new({ campaignId => $campaign_operation->get_operand()->get_id(), criterion => $keyword }); # Create operation. my $negative_criterion_operation = Google::Ads::AdWords::v201809::CampaignCriterionOperation->new({ operator => "ADD", operand => $negative_criterion }); push @campaign_criterion_operations, $negative_criterion_operation; } return @campaign_criterion_operations; } # Create AdGroupOperations to add AdGroups. sub _create_ad_group_operations { my (@campaign_operations) = @_; my @ad_group_operations = (); for my $campaign_operation (@campaign_operations) { for (my $i = 1 ; $i < NUMBER_OF_ADGROUPS_TO_ADD ; $i++) { my $ad_group = Google::Ads::AdWords::v201809::AdGroup->new({ id => _next_id(), campaignId => $campaign_operation->get_operand()->get_id(), name => "Batch Ad Group #" . uniqid(), biddingStrategyConfiguration => Google::Ads::AdWords::v201809::BiddingStrategyConfiguration->new({ bids => [ Google::Ads::AdWords::v201809::CpcBid->new({ bid => Google::Ads::AdWords::v201809::Money->new( {microAmount => 10000000})})]})}); my $ad_group_operation = Google::Ads::AdWords::v201809::AdGroupOperation->new({ operator => "ADD", operand => $ad_group }); push @ad_group_operations, $ad_group_operation; } } return @ad_group_operations; } # Create AdGroupCriterionOperations. sub _create_ad_group_criterion_operations { my (@ad_group_operations) = @_; my @ad_group_criterion_operations = (); for my $ad_group_operation (@ad_group_operations) { for (my $i = 1 ; $i < NUMBER_OF_KEYWORDS_TO_ADD ; $i++) { # Create keyword. my $keyword = Google::Ads::AdWords::v201809::Keyword->new({ matchType => "BROAD", # Make 50% of keywords invalid to demonstrate error handling. text => sprintf("mars%d%s", $i, (($i % 2 == 0) ? "!!!" : ""))}); # Create biddable ad group criterion. my $ad_group_criterion = Google::Ads::AdWords::v201809::BiddableAdGroupCriterion->new({ adGroupId => $ad_group_operation->get_operand()->get_id(), criterion => $keyword }); # Create operation. my $ad_group_criterion_operation = Google::Ads::AdWords::v201809::AdGroupCriterionOperation->new({ operator => "ADD", operand => $ad_group_criterion }); push @ad_group_criterion_operations, $ad_group_criterion_operation; } } return @ad_group_criterion_operations; } # Create AdGroupAdOperations. sub _create_ad_group_ad_operations() { my (@ad_group_operations) = @_; my @ad_group_ad_operations = (); for my $ad_group_operation (@ad_group_operations) { my $ad_group_id = $ad_group_operation->get_operand()->get_id(); my $text_ad = Google::Ads::AdWords::v201809::ExpandedTextAd->new({ headlinePart1 => "Cruise to Mars", headlinePart2 => "Visit the Red Planet in style.", description => "Low-gravity for everyone!", finalUrls => ["http://www.example.com/1"]}); # Create ad group ad for the text ad. my $text_ad_group_ad = Google::Ads::AdWords::v201809::AdGroupAd->new({ adGroupId => $ad_group_id, ad => $text_ad, # Additional properties (non-required). status => "PAUSED" }); # Create operation. my $text_ad_group_ad_operation = Google::Ads::AdWords::v201809::AdGroupAdOperation->new({ operator => "ADD", operand => $text_ad_group_ad }); push @ad_group_ad_operations, $text_ad_group_ad_operation; } return @ad_group_ad_operations; } # Return the next available temporary ID. sub _next_id() { return $temporary_id--; } # Poll for completion of the batch job using an exponential back off # waiting until the progress of the job is DONE or CANCELED. # This returns a hash of return values: # error => undef if no error and BatchJobHandlerError if an error occurred # batch_job => the batch job with the id, status, progressStats, # processingErrors, and downloadUrl # result => BatchJobOpsService::mutateResponse object with contents from the # job's download URL sub _verify_operations { my ($client, $batch_job_handler, $batch_job) = @_; my $job_id = sprintf("%d", $batch_job->get_id()); my $predicate = Google::Ads::AdWords::v201809::Predicate->new({ field => "Id", operator => "IN", values => [$job_id]}); my $paging = Google::Ads::AdWords::v201809::Paging->new({ startIndex => 0, numberResults => 1 }); my $selector = Google::Ads::AdWords::v201809::Selector->new({ fields => ["Id", "Status", "ProgressStats", "ProcessingErrors", "DownloadUrl"], predicates => [$predicate], paging => $paging }); # Loop while waiting for the job to complete. my $job; my $poll_attempts = 0; my $end_time = time + JOB_TIMEOUT_IN_MILLISECONDS; do { my $batch_job_page = $client->BatchJobService->get({selector => $selector}); $job = $batch_job_page->get_entries()->[0]; printf("Job with ID %d has a status of: %s.\n", $job->get_id(), $job->get_status()); my $waittime_in_milliseconds = JOB_BASE_WAITTIME_IN_MILLISECONDS * (2**$poll_attempts); if ( (time + $waittime_in_milliseconds) < $end_time and ($job->get_status() eq "ACTIVE" or $job->get_status() eq "AWAITING_FILE")) { printf("Sleeping %d milliseconds...\n", $waittime_in_milliseconds); sleep($waittime_in_milliseconds / 1000); # Convert to seconds. $poll_attempts++; } else { # If there isn't enough time to sleep and do another loop, then get out # of the loop. $end_time = time; } } while ( time < $end_time and !( $job->get_status() eq "DONE" or $job->get_status() eq "CANCELED" )); # If the tiemout was exceeded, then return an error. my $error; if (!($job->get_status() eq "DONE" or $job->get_status() eq "CANCELED")) { $error = Google::Ads::AdWords::Utilities::BatchJobHandlerError->new({ type => "UPLOAD", description => sprintf( "Job with ID %d did not complete" . "within a timeout of %d milliseconds.", $job->get_id(), JOB_TIMEOUT_IN_MILLISECONDS )}); } # Check for processing errors. if ($job->get_processingErrors()) { $error = Google::Ads::AdWords::Utilities::BatchJobHandlerError->new({ type => "PROCESSING", description => sprintf("Job ID %d had processing errors.", $job->get_id()), processing_errors => $job->get_processingErrors()}); } my $download_url = $job->get_downloadUrl()->get_url(); printf("Batch job with ID %d.\n\tDownload URL: '%s'\n", $job->get_id(), $download_url); my $download_url_result = $batch_job_handler->download_response($download_url); if (!$download_url_result) { $error = $download_url_result; $download_url_result = undef; } return { error => $error, batch_job => $job, result => $download_url_result }; } # 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_complete_campaign_using_batch_job($client);
Create a draft and access its campaign
#!/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 illustrates how to create a draft and access its associated # draft campaign. # # See the Campaign Drafts and Experiments guide for more information: # https://developers.google.com/adwords/api/docs/guides/campaign-drafts-experiments use strict; use lib "../../../lib"; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::CampaignCriterion; use Google::Ads::AdWords::v201809::CampaignCriterionOperation; use Google::Ads::AdWords::v201809::Draft; use Google::Ads::AdWords::v201809::DraftOperation; use Google::Ads::AdWords::v201809::Language; use Cwd qw(abs_path); use Data::Uniqid qw(uniqid); # Replace with a valid value from your account. my $base_campaign_id = "INSERT_BASE_CAMPAIGN_ID_HERE"; # Example main subroutine. sub add_draft { my ($client, $base_campaign_id) = @_; my $draft = Google::Ads::AdWords::v201809::Draft->new({ baseCampaignId => $base_campaign_id, draftName => sprintf("Test Draft #%s", uniqid())}); # Create operation. my $draft_operation = Google::Ads::AdWords::v201809::DraftOperation->new({ operator => "ADD", operand => $draft }); # Add draft. my $result = $client->DraftService()->mutate({operations => [$draft_operation]}); if ($result) { $draft = $result->get_value()->[0]; my $draft_id = $draft->get_draftId(); my $draft_campaign_id = $draft->get_draftCampaignId(); printf( "Draft with ID %d and base campaign ID %d" . " and draft campaign ID %d created.\n", $draft_id, $draft->get_baseCampaignId(), $draft_campaign_id ); # Once the draft is created, you can modify the draft campaign as if it # were a real campaign. For example, you may add criteria, adjust bids, # or even include additional ads. Adding a criterion is shown here. my $criterion = Google::Ads::AdWords::v201809::Language->new({ id => 1003 # Spanish }); my $operation = Google::Ads::AdWords::v201809::CampaignCriterionOperation->new({ operator => "ADD", operand => Google::Ads::AdWords::v201809::CampaignCriterion->new({ campaignId => $draft_campaign_id, criterion => $criterion })}); $result = $client->CampaignCriterionService()->mutate({operations => [$operation]}); $criterion = $result->get_value()->[0]; printf("Draft updated to include criteria in campaign %d.\n", $criterion->get_campaignId()); } 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_draft($client, $base_campaign_id);
Upload keywords incrementally using BatchJobService
#!/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 illustrates how to perform multiple requests using the # BatchJobService using incremental uploads. use strict; use lib "../../../lib"; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::AdGroupCriterion; use Google::Ads::AdWords::v201809::AdGroupCriterionOperation; use Google::Ads::AdWords::v201809::BatchJob; use Google::Ads::AdWords::v201809::BatchJobOperation; use Google::Ads::AdWords::v201809::BiddableAdGroupCriterion; use Google::Ads::AdWords::v201809::Keyword; use Google::Ads::AdWords::Utilities::BatchJobHandler; use Google::Ads::AdWords::Utilities::BatchJobHandlerError; use Google::Ads::AdWords::Utilities::BatchJobHandlerStatus; use Cwd qw(abs_path); use constant KEYWORD_COUNT => 100; # Set a timeout to fail if the job does not complete in a specified amount # of time. use constant JOB_TIMEOUT_IN_MILLISECONDS => 600000; # The time to sleep in between polls will start at this time. Then an # exponential back-off will be instituted. use constant JOB_BASE_WAITTIME_IN_MILLISECONDS => 30000; # Replace with valid values of your account. my $ad_group_id = "INSERT_AD_GROUP_ID_HERE"; # Example main subroutine. sub add_keywords_using_incremental_batch_job { my $client = shift; my $ad_group_id = shift; # Create a batch job, which returns an upload URL to upload the batch # operations and a job ID to track the job. my $operation = Google::Ads::AdWords::v201809::BatchJobOperation->new({ operator => 'ADD', operand => Google::Ads::AdWords::v201809::BatchJob->new({})}); my $batch_job_result = $client->BatchJobService()->mutate({operations => [$operation]}); if (!$batch_job_result->get_value()) { print "A batch job could not be created. No operations were uploaded.\n"; return 1; } my $batch_job = $batch_job_result->get_value()->[0]; printf("Batch job with ID %d was created.\n\tInitial upload URL: '%s'\n", $batch_job->get_id(), $batch_job->get_uploadUrl()->get_url()); # Get an instance of a utility that helps with uploading batch operations. my $batch_job_handler = Google::Ads::AdWords::Utilities::BatchJobHandler->new({client => $client}); # # Upload the keywords in three batches to the upload URL. # The process that adds the keywords to the ad group will not start # executing until the last request has been sent. # # Upload #1: This is the first upload. my @operations = _create_keyword_operations($ad_group_id); # Create an initial batch job status. # Convert the list of operations into XML. # POST the XML to the upload URL. my $batch_job_status = Google::Ads::AdWords::Utilities::BatchJobHandlerStatus->new({ total_content_length => 0, resumable_upload_uri => $batch_job->get_uploadUrl()->get_url()}); $batch_job_status = $batch_job_handler->upload_incremental_operations(\@operations, $batch_job_status); if (!_check_status($batch_job_status)) { return 1; } printf("\tResumable upload URL: '%s'\n", $batch_job_status->get_resumable_upload_uri()); # Upload #2: Make sure to pass in the status returned in the last call # into 'upload_incremental_operations'. @operations = _create_keyword_operations($ad_group_id); # Convert the list of operations into XML. # POST the XML to the upload URL. $batch_job_status = $batch_job_handler->upload_incremental_operations(\@operations, $batch_job_status); if (!_check_status($batch_job_status)) { return 1; } # Upload #3: Make sure to pass in the status returned in the last request # and a true value for $is_last_request indicating that the uploads have # finished into 'upload_incremental_operations'. @operations = _create_keyword_operations($ad_group_id); # Convert the list of operations into XML. # POST the XML to the upload URL. $batch_job_status = $batch_job_handler->upload_incremental_operations(\@operations, $batch_job_status, 1); if (!_check_status($batch_job_status)) { return 1; } # Verify that the operations completed. # This will poll until the job has completed or the timeout has expired. my $verify_result = _verify_operations($client, $batch_job_handler, $batch_job); # Display the results. my $error = $verify_result->{error}; my $job_result = $verify_result->{batch_job}; my $operations_result = $verify_result->{result}; printf("Job with ID %d has completed with a status of '%s'.\n", $job_result->get_id(), $job_result->get_status()); if (defined $error) { printf("%s Error. %s\n", $error->get_type(), $error->get_description()); if ($error->get_type() eq "PROCESSING") { printf("%s\n", $error->get_processing_errors()); } if ($error->get_type() eq "HTTP") { printf( "Type: %s\nCode: %s\nMessage: %s\nTrigger: %s\nField Path: %s\n", $error->get_http_type(), $error->get_http_response_code(), $error->get_http_response_message(), $error->get_http_trigger(), $error->get_http_field_path()); } } if ($operations_result and $operations_result->get_rval()) { for my $item (@{$operations_result->get_rval()}) { if ($item->get_errorList()) { printf("Error on index %d: %s\n", $item->get_index(), $item->get_errorList()->get_errors()); } else { # Print the XML output. printf("Successful on index %d\n%s\n", $item->get_index(), $item->get_result()->get_AdGroupCriterion()->get_criterion() ->get_text()); } } } return 1; } # Create AdGroupCriterion to add keywords. sub _create_keyword_operations { my ($ad_group_id) = @_; my @operations = (); for (my $i = 1 ; $i < KEYWORD_COUNT ; $i++) { # Create keyword. my $keyword = Google::Ads::AdWords::v201809::Keyword->new({matchType => "BROAD"}); # Randomly add invalid characters to keyword. if (int(rand(10)) == 0) { $keyword->set_text(sprintf("keyword %d!!!", $i)); } else { $keyword->set_text(sprintf("keyword %d", $i)); } # Create biddable ad group criterion. my $ad_group_criterion = Google::Ads::AdWords::v201809::BiddableAdGroupCriterion->new({ adGroupId => $ad_group_id, criterion => $keyword }); # Create operation. my $ad_group_criterion_operation = Google::Ads::AdWords::v201809::AdGroupCriterionOperation->new({ operator => "ADD", operand => $ad_group_criterion }); push(@operations, $ad_group_criterion_operation); } return @operations; } # Check the status of uploading incremental operations. Print details if an # error is found. sub _check_status { my ($batch_job_status) = @_; if (!$batch_job_status) { # If not given a status back, then this object is an error. my $error = $batch_job_status; printf("%s Error. %s\n", $error->get_type(), $error->get_description()); if ($error->get_type() eq "HTTP") { printf( "Type: %s\nCode: %s\nMessage: %s\nTrigger: %s\nField Path: %s\n", $error->get_http_type(), $error->get_http_response_code(), $error->get_http_response_message(), $error->get_http_trigger(), $error->get_http_field_path()); } } return $batch_job_status; } # Poll for completion of the batch job using an exponential back off # waiting until the progress of the job is DONE or CANCELED. # If the job does not finish in the alloted time, attempt to cancel it once. # This returns a hash of return values: # error => undef if no error and BatchJobHandlerError if an error occurred # batch_job => the batch job with the id, status, progressStats, # processingErrors, and downloadUrl # result => BatchJobOpsService::mutateResponse object with contents from the # job's download URL sub _verify_operations { my ($client, $batch_job_handler, $batch_job) = @_; my $job_id = sprintf("%d", $batch_job->get_id()); my $predicate = Google::Ads::AdWords::v201809::Predicate->new({ field => "Id", operator => "IN", values => [$job_id]}); my $paging = Google::Ads::AdWords::v201809::Paging->new({ startIndex => 0, numberResults => 1 }); my $selector = Google::Ads::AdWords::v201809::Selector->new({ fields => ["Id", "Status", "ProgressStats", "ProcessingErrors", "DownloadUrl"], predicates => [$predicate], paging => $paging }); # Loop while waiting for the job to complete. my $job; my $poll_attempts = 0; my $end_time = time + JOB_TIMEOUT_IN_MILLISECONDS; my $was_cancel_requested = 0; do { my $batch_job_page = $client->BatchJobService->get({selector => $selector}); $job = $batch_job_page->get_entries()->[0]; printf("Job with ID %d has a status of: %s.\n", $job->get_id(), $job->get_status()); my $waittime_in_milliseconds = JOB_BASE_WAITTIME_IN_MILLISECONDS * (2**$poll_attempts); if ( (time + $waittime_in_milliseconds) < $end_time and ($job->get_status() eq "ACTIVE" or $job->get_status() eq "AWAITING_FILE" or $job->get_status() eq "CANCELING") ) { printf("Sleeping %d milliseconds...\n", $waittime_in_milliseconds); sleep($waittime_in_milliseconds / 1000); # Convert to seconds. $poll_attempts++; } else { # Optional: # If there isn't enough time to sleep and do another loop, then cancel. # If a cancel was already unsuccessful, get out of the loop. $end_time = time; if ( !($job->get_status() eq "DONE" or $job->get_status() eq "CANCELED") && !$was_cancel_requested) { $was_cancel_requested = 1; $job->set_status("CANCELING"); my $operation = Google::Ads::AdWords::v201809::BatchJobOperation->new({ operator => 'SET', operand => $job }); my $job_result = $client->BatchJobService()->mutate({operations => [$operation]}); if (!$job_result->get_value()) { sprint("Unable to cancel job with ID %d.", $job->get_id()); } else { $job = $job_result->get_value()->[0]; # Reset the timer to give the job time to cancel. $poll_attempts = 0; $end_time = time + JOB_TIMEOUT_IN_MILLISECONDS; printf("Job with ID %d did not complete within a timeout of %d " . "milliseconds. Requested cancellation of batch job.\n", $job->get_id(), JOB_TIMEOUT_IN_MILLISECONDS); } } } } while ( time < $end_time and !( $job->get_status() eq "DONE" or $job->get_status() eq "CANCELED" )); # If the timeout was exceeded, then return an error. my $error; if (!($job->get_status() eq "DONE" or $job->get_status() eq "CANCELED")) { $error = Google::Ads::AdWords::Utilities::BatchJobHandlerError->new({ type => "UPLOAD", description => sprintf( "Job with ID %d did not complete" . "within a timeout of %d milliseconds.", $job->get_id(), JOB_TIMEOUT_IN_MILLISECONDS )}); } # Check for processing errors. if ($job->get_processingErrors()) { $error = Google::Ads::AdWords::Utilities::BatchJobHandlerError->new({ type => "PROCESSING", description => sprintf("Job ID %d had processing errors.", $job->get_id()), processing_errors => $job->get_processingErrors()}); } my $download_url_result; if ($job->get_downloadUrl()) { my $download_url = $job->get_downloadUrl()->get_url(); printf("Batch job with ID %d.\n\tDownload URL: '%s'\n", $job->get_id(), $download_url); $download_url_result = $batch_job_handler->download_response($download_url); if (!$download_url_result) { $error = $download_url_result; $download_url_result = undef; } } return { error => $error, batch_job => $job, result => $download_url_result }; } # 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_keywords_using_incremental_batch_job($client, $ad_group_id);
Create a trial
#!/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 illustrates how to create a trial and wait for it to complete. # # See the Campaign Drafts and Experiments guide for more information: # https://developers.google.com/adwords/api/docs/guides/campaign-drafts-experiments use strict; use lib "../../../lib"; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::Predicate; use Google::Ads::AdWords::v201809::Selector; use Google::Ads::AdWords::v201809::Trial; use Google::Ads::AdWords::v201809::TrialOperation; use Cwd qw(abs_path); use Data::Uniqid qw(uniqid); # Replace with valid values of your account. my $base_campaign_id = "INSERT_BASE_CAMPAIGN_ID_HERE"; my $draft_id = "INSERT_DRAFT_ID_HERE"; # Set a timeout to fail if the trial is not created in a specified amount # of time. use constant JOB_TIMEOUT_IN_MILLISECONDS => 180000; # The time to sleep in between polls will start at this time. Then an # exponential back-off will be instituted. use constant JOB_BASE_WAITTIME_IN_MILLISECONDS => 10000; # Example main subroutine. sub add_trial { my ($client, $base_campaign_id, $draft_id) = @_; my $trial = Google::Ads::AdWords::v201809::Trial->new({ draftId => $draft_id, baseCampaignId => $base_campaign_id, name => sprintf("Test Trial #%s", uniqid()), trafficSplitPercent => 50, trafficSplitType => "RANDOM_QUERY" }); # Create operation. my $trial_operation = Google::Ads::AdWords::v201809::TrialOperation->new({ operator => "ADD", operand => $trial }); # Add trial. my $result = $client->TrialService()->mutate({operations => [$trial_operation]}); if ($result) { my $trial_id = $result->get_value()->[0]->get_id()->get_value(); my $predicate = Google::Ads::AdWords::v201809::Predicate->new({ field => "Id", operator => "IN", values => [$trial_id]}); my $paging = Google::Ads::AdWords::v201809::Paging->new({ startIndex => 0, numberResults => 1 }); my $selector = Google::Ads::AdWords::v201809::Selector->new({ fields => ["Id", "Status", "BaseCampaignId", "TrialCampaignId"], predicates => [$predicate], paging => $paging }); # Since creating a trial is asynchronous, we have to poll it to wait for # it to finish. my $poll_attempts = 0; my $is_pending = 1; my $end_time = time + JOB_TIMEOUT_IN_MILLISECONDS; do { # Check to see if the trial is still in the process of being created. my $result = $client->TrialService()->get({selector => $selector}); $trial = $result->get_entries()->[0]; my $waittime_in_milliseconds = JOB_BASE_WAITTIME_IN_MILLISECONDS * (2**$poll_attempts); if (((time + $waittime_in_milliseconds) < $end_time) and $trial->get_status() eq 'CREATING') { printf("Sleeping %d milliseconds...\n", $waittime_in_milliseconds); sleep($waittime_in_milliseconds / 1000); # Convert to seconds. $poll_attempts++; } } while (time < $end_time and $trial->get_status() eq 'CREATING'); if ($trial->get_status() eq 'ACTIVE') { # The trial creation was successful. printf("Trial created with ID %d and trial campaign ID %d.\n", $trial->get_id(), $trial->get_trialCampaignId()); } elsif ($trial->get_status() eq 'CREATION_FAILED') { # The trial creation failed, and errors can be fetched from the # TrialAsyncErrorService. my $error_selector = Google::Ads::AdWords::v201809::Selector->new({ fields => ["TrialId", "AsyncError"], predicates => [ Google::Ads::AdWords::v201809::Predicate->new({ field => "TrialId", operator => "IN", values => [$trial_id]})]}); my $errors = $client->TrialAsyncErrorService->get({selector => $error_selector}) ->get_entries(); if (!$errors) { printf("Could not retrieve errors for trial %d", $trial->get_id()); } else { printf("Could not create trial due to the following errors:"); my $index = 0; for my $error ($errors) { printf("Error %d: %s", $index, $error->get_asyncError() ->get_errorString()); $index++; } } } else { # Most likely, the trial is still being created. You can continue polling, # but we have limited the number of attempts in the example. printf("Timed out waiting to create trial from draft %d with base " . "campaign %d.\n", $draft_id, $base_campaign_id); } } 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_trial($client, $base_campaign_id, $draft_id);
Get all disapproved ads in an ad group
#!/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 gets all disapproved ads in an ad group. To add ads, run # basic_operations/add_text_ads.pl. To get ad groups, run # basic_operations/get_ad_groups.pl. use strict; use lib "../../../lib"; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::OrderBy; use Google::Ads::AdWords::v201809::Paging; use Google::Ads::AdWords::v201809::Predicate; use Google::Ads::AdWords::v201809::Selector; use Google::Ads::AdWords::Utilities::PageProcessor; use Cwd qw(abs_path); use constant PAGE_SIZE => 100; # Replace with valid values of your account. my $ad_group_id = "INSERT_AD_GROUP_ID_HERE"; # Example main subroutine. sub get_all_disapproved_ads { my $client = shift; my $ad_group_id = shift; # Create predicates (Filters). my $ad_group_predicate = Google::Ads::AdWords::v201809::Predicate->new({ field => "AdGroupId", operator => "IN", values => [$ad_group_id]}); my $disapproved_predicate = Google::Ads::AdWords::v201809::Predicate->new({ field => "CombinedApprovalStatus", operator => "EQUALS", values => ["DISAPPROVED"]}); # Create selector. my $paging = Google::Ads::AdWords::v201809::Paging->new({ startIndex => 0, numberResults => PAGE_SIZE }); my $selector = Google::Ads::AdWords::v201809::Selector->new({ fields => ["Id", "PolicySummary"], predicates => [$ad_group_predicate, $disapproved_predicate], ordering => [ Google::Ads::AdWords::v201809::OrderBy->new({ field => "Id", sortOrder => "ASCENDING" }) ], paging => $paging }); # Paginate through results. # The contents of the subroutine will be executed for each ad. my $disapproved_ad_count = 0; Google::Ads::AdWords::Utilities::PageProcessor->new({ client => $client, service => $client->AdGroupAdService(), selector => $selector } )->process_entries( sub { my ($ad_group_ad) = @_; $disapproved_ad_count++; my $policy_summary = $ad_group_ad->get_policySummary(); printf "Ad with ID %d and type '%s' was disapproved with the " . "following policy topic entries:\n", $ad_group_ad->get_ad()->get_id(), $ad_group_ad->get_ad()->get_Ad__Type(); foreach my $policy_topic_entry (@{$policy_summary->get_policyTopicEntries()}) { printf " topic id: %s, topic name: '%s', Help Center URL: '%s'\n", $policy_topic_entry->get_policyTopicId(), $policy_topic_entry->get_policyTopicName(), $policy_topic_entry->get_policyTopicHelpCenterUrl(); # Display the attributes and values that triggered the policy topic. if ($policy_topic_entry->get_policyTopicEvidences()) { foreach my $evidence (@{$policy_topic_entry->get_policyTopicEvidences()}) { printf(" evidence type: '%s'\n", $evidence->get_policyTopicEvidenceType()); if ($evidence->get_evidenceTextList()) { for ( my $i = 0; $i < scalar(@{$evidence->get_evidenceTextList()}) ; $i++ ) { printf(" evidence text[%d]: '%s'\n", $i, $evidence->get_evidenceTextList()->[$i]); } } } } } }); if ($disapproved_ad_count == 0) { print("No disapproved ads were found.\n"); } 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 get_all_disapproved_ads($client, $ad_group_id);
Get all disapproved ads in an ad group using AWQL
#!/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 gets all disapproved ads in an ad group using AWQL. # To add ads, run basic_operations/add_text_ads.pl. To get ad groups, run # basic_operations/get_ad_groups.pl. use strict; use lib "../../../lib"; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::OrderBy; use Google::Ads::AdWords::v201809::Paging; use Google::Ads::AdWords::v201809::Predicate; use Google::Ads::AdWords::v201809::Selector; use Google::Ads::AdWords::Utilities::PageProcessor; use Google::Ads::AdWords::Utilities::ServiceQueryBuilder; use Cwd qw(abs_path); use constant PAGE_SIZE => 100; # Replace with valid values of your account. my $ad_group_id = "INSERT_AD_GROUP_ID_HERE"; # Example main subroutine. sub get_all_disapproved_ads_with_awql { my $client = shift; my $ad_group_id = shift; # Get all the disapproved ads for the given ad group. my $query = Google::Ads::AdWords::Utilities::ServiceQueryBuilder->new( {client => $client}) ->select(["Id", "PolicySummary"]) ->where("AdGroupId")->equal_to($ad_group_id) ->where("CombinedApprovalStatus")->equal_to("DISAPPROVED") ->order_by("Id") ->build(); # Paginate through results. # The contents of the subroutine will be executed for each disapproved ad. my $disapproved_ad_count = 0; Google::Ads::AdWords::Utilities::PageProcessor->new({ client => $client, service => $client->AdGroupAdService(), query => $query, page_size => PAGE_SIZE } )->process_entries( sub { my ($ad_group_ad) = @_; $disapproved_ad_count++; my $policy_summary = $ad_group_ad->get_policySummary(); printf "Ad with ID %d and type '%s' was disapproved with the " . "following policy topic entries:\n", $ad_group_ad->get_ad()->get_id(), $ad_group_ad->get_ad()->get_Ad__Type(); # Display the policy topic entries related to the ad disapproval. foreach my $policy_topic_entry (@{$policy_summary->get_policyTopicEntries()}) { printf " topic id: %s, topic name: '%s'\n", $policy_topic_entry->get_policyTopicId(), $policy_topic_entry->get_policyTopicName(); # Display the attributes and values that triggered the policy topic. if ($policy_topic_entry->get_policyTopicEvidences()) { foreach my $evidence (@{$policy_topic_entry->get_policyTopicEvidences()}) { printf(" evidence type: '%s'\n", $evidence->get_policyTopicEvidenceType()); if ($evidence->get_evidenceTextList()) { for ( my $i = 0 ; $i < scalar(@{$evidence->get_evidenceTextList()}) ; $i++ ) { printf(" evidence text[%d]: '%s'\n", $i, $evidence->get_evidenceTextList()->[$i]); } } } } } }); if ($disapproved_ad_count == 0) { print("No disapproved ads were found.\n"); } 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 get_all_disapproved_ads_with_awql($client, $ad_group_id);
Get all campaigns with a specific label
#!/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 gets all campaigns with a specific label. To add a label to # campaigns, run add_campaign_labels.pl. use strict; use lib "../../../lib"; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::OrderBy; use Google::Ads::AdWords::v201809::Paging; use Google::Ads::AdWords::v201809::Predicate; use Google::Ads::AdWords::v201809::Selector; use Google::Ads::AdWords::Utilities::PageProcessor; use constant PAGE_SIZE => 500; use Cwd qw(abs_path); # Replace with valid values of your account. my $label_id = "INSERT_LABEL_ID_HERE"; # Example main subroutine. sub get_campaigns_by_label { my $client = shift; my $label_id = shift; # Create predicate. # Labels filtering is performed by ID. You can use CONTAINS_ANY to select # campaigns with any of the label IDs, CONTAINS_ALL to select campaigns with # all of the label IDs, or CONTAINS_NONE to select campaigns with none of the # label IDs. my $labels_predicate = Google::Ads::AdWords::v201809::Predicate->new({ field => "Labels", operator => "CONTAINS_ANY", values => [$label_id]}); # Create selector. my $paging = Google::Ads::AdWords::v201809::Paging->new({ startIndex => 0, numberResults => PAGE_SIZE }); my $selector = Google::Ads::AdWords::v201809::Selector->new({ fields => ["Id", "Name", "Labels"], predicates => [$labels_predicate], ordering => [ Google::Ads::AdWords::v201809::OrderBy->new({ field => "Name", sortOrder => "ASCENDING" }) ], paging => $paging }); # Paginate through results. # The contents of the subroutine will be executed for each campaign. Google::Ads::AdWords::Utilities::PageProcessor->new({ client => $client, service => $client->CampaignService(), selector => $selector } )->process_entries( sub { my ($campaign) = @_; my @label_strings = map { $_->get_id() . '/' . $_->get_name() } @{$campaign->get_labels()}; printf "Campaign found with name \"%s\" and ID %d and labels: %s.\n", $campaign->get_name(), $campaign->get_id(), join(', ', @label_strings); }); 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 get_campaigns_by_label($client, $label_id);
Graduate a trial
#!/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 illustrates how to graduate a trial. # # See the Campaign Drafts and Experiments guide for more information: # https://developers.google.com/adwords/api/docs/guides/campaign-drafts-experiments use strict; use lib "../../../lib"; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::Budget; use Google::Ads::AdWords::v201809::BudgetOperation; use Google::Ads::AdWords::v201809::Trial; use Google::Ads::AdWords::v201809::TrialOperation; use Cwd qw(abs_path); use Data::Uniqid qw(uniqid); # Replace with a valid value from your account. my $trial_id = "INSERT_TRIAL_ID_HERE"; # Example main subroutine. sub graduate_trial { my ($client, $trial_id) = @_; # To graduate a trial, you must specify a different budget from the base # campaign. The base campaign (in order to have had a trial based on it) # must have a non-shared budget, so it cannot be shared with the new # independent campaign created by graduation. my $budget = Google::Ads::AdWords::v201809::Budget->new({ name => sprintf("Budget #%s", uniqid()), amount => Google::Ads::AdWords::v201809::Money->new({microAmount => 5000000}), deliveryMethod => "STANDARD" }); my $budget_operation = Google::Ads::AdWords::v201809::BudgetOperation->new({ operator => "ADD", operand => $budget }); # Add budget. my $budget_id = $client->BudgetService()->mutate({operations => ($budget_operation)}) ->get_value()->get_budgetId()->get_value(); my $trial = Google::Ads::AdWords::v201809::Trial->new({ id => $trial_id, budgetId => $budget_id, status => "GRADUATED" }); # Create operation. my $trial_operation = Google::Ads::AdWords::v201809::TrialOperation->new({ operator => "SET", operand => $trial }); # Graduate trial. my $result = $client->TrialService()->mutate({operations => [$trial_operation]}); # Update the trial. $trial = $result->get_value()->[0]; # Graduation is a synchronous operation, so the campaign is already ready. # If you promote instead, make sure to see the polling scheme demonstrated # in add_trial.pl to wait for the asynchronous operation to finish. printf("Trial ID %d graduated. Campaign %d was given a new budget ID %d " . "and is no longer dependent on this trial.\n", $trial->get_id(), $trial->get_trialCampaignId(), $budget_id); 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 graduate_trial($client, $trial_id);
Set ad parameters for a keyword ad group criterion
#!/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 sets ad parameters for a keyword in an ad group. To get keywords, # run basic_operations/get_keywords.pl. use strict; use lib "../../../lib"; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::AdParam; use Google::Ads::AdWords::v201809::AdParamOperation; use Cwd qw(abs_path); # Replace with valid values of your account. my $ad_group_id = "INSERT_AD_GROUP_ID_HERE"; my $keyword_id = "INSERT_KEYWORD_ID_HERE"; # Example main subroutine. sub set_ad_parameters { my $client = shift; my $ad_group_id = shift; my $keyword_id = shift; # Create ad parameters. my $ad_param1 = Google::Ads::AdWords::v201809::AdParam->new({ adGroupId => $ad_group_id, criterionId => $keyword_id, insertionText => "100", paramIndex => "1", }); my $ad_param2 = Google::Ads::AdWords::v201809::AdParam->new({ adGroupId => $ad_group_id, criterionId => $keyword_id, insertionText => "\$40", paramIndex => "2", }); # Create operations. my $ad_param_operation1 = Google::Ads::AdWords::v201809::AdParamOperation->new({ operator => "SET", operand => $ad_param1 }); my $ad_param_operation2 = Google::Ads::AdWords::v201809::AdParamOperation->new({ operator => "SET", operand => $ad_param2 }); # Set ad parameters. my $ad_params = $client->AdParamService() ->mutate({operations => [$ad_param_operation1, $ad_param_operation2]}); # Display ad parameters. if ($ad_params) { foreach my $ad_param (@{$ad_params}) { printf "Ad parameter with ad group id \"%d\", criterion id \"%d\", " . "insertion text \"%s\", and parameter index \"%d\" was set.\n", $ad_param->get_adGroupId(), $ad_param->get_criterionId(), $ad_param->get_insertionText(), $ad_param->get_paramIndex(); } } else { print "No ad parameters were set.\n"; } 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 set_ad_parameters($client, $ad_group_id, $keyword_id);
Set a bid modifier on a campaign
#!/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 sets a bid modifier for the mobile platform on given campaign. # To get campaigns, run basic_operations/get_campaigns.pl. use strict; use lib "../../../lib"; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::CampaignCriterionOperation; use Google::Ads::AdWords::v201809::Platform; use Cwd qw(abs_path); use constant BID_MODIFIER => 1.5; # Replace with valid values of your account. my $campaign_id = "INSERT_CAMPAIGN_ID_HERE"; # Example main subroutine. sub set_bid_modifier { my $client = shift; my $campaign_id = shift; # Create mobile platform. The ID can be found in the documentation. # https://developers.google.com/adwords/api/docs/appendix/platforms my $mobile = Google::Ads::AdWords::v201809::Platform->new({id => 30001}); # Create criterion with modified bid. my $criterion = Google::Ads::AdWords::v201809::CampaignCriterion->new({ campaignId => $campaign_id, criterion => $mobile, bidModifier => BID_MODIFIER }); # Create SET operation. my $operation = Google::Ads::AdWords::v201809::CampaignCriterionOperation->new({ operator => "SET", operand => $criterion }); # Update campaign criteria. my $result = $client->CampaignCriterionService()->mutate({operations => [$operation]}); # Display campaign criteria. if ($result->get_value()) { foreach my $campaign_criterion (@{$result->get_value()}) { printf "Campaign criterion with campaign id '%s', criterion id '%s', " . "and type '%s' was modified with bid %.2f.\n", $campaign_criterion->get_campaignId(), $campaign_criterion->get_criterion()->get_id(), $campaign_criterion->get_criterion()->get_type(), $campaign_criterion->get_bidModifier(); } } else { print "No campaign criteria were modified.\n"; } 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 set_bid_modifier($client, $campaign_id);
Validate text ad through setValidateOnly header
#!/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 shows how to use the validate only header to check for errors. # No objects will be created, but exceptions will still be returned. use strict; use lib "../../../lib"; use Google::Ads::AdWords::Client; use Google::Ads::AdWords::Logging; use Google::Ads::AdWords::v201809::AdGroupAd; use Google::Ads::AdWords::v201809::AdGroupAdOperation; use Google::Ads::AdWords::v201809::ExpandedTextAd; use Cwd qw(abs_path); # Replace with valid values of your account. my $ad_group_id = "INSERT_AD_GROUP_ID_HERE"; # Example main subroutine. sub validate_text_ad { my $client = shift; my $ad_group_id = shift; # Don't die on fault it will be handled in code. $client->set_die_on_faults(0); # Set validate only. $client->set_validate_only(1); # Create invalid expanded text ad my $text_ad = Google::Ads::AdWords::v201809::ExpandedTextAd->new({ headlinePart1 => "Luxury Cruise to Mars", headlinePart2 => "Visit the Red Planet in style.", description => "Low-gravity fun for all astronauts in orbit.", finalUrls => ["http://www.example.com"]}); my $text_ad_group_ad = Google::Ads::AdWords::v201809::AdGroupAd->new({ adGroupId => $ad_group_id, ad => $text_ad }); # Create operations. my $operation = Google::Ads::AdWords::v201809::AdGroupAdOperation->new({ operand => $text_ad_group_ad, operator => "ADD" }); # Validate text ad operation. my $result = $client->AdGroupAdService()->mutate({operations => [$operation]}); if (defined($result) and $result->isa("SOAP::WSDL::SOAP::Typelib::Fault11")) { printf "Validation failed for reason: %s\n", $result->get_faultstring(); } else { print "The ad is valid!\n"; } 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 validate_text_ad($client, $ad_group_id);