The steps for requesting exemption for ads are as follows:
- Store all the ignorable policy topics included in
PolicyTopicEntry
, which is stored insidePolicyFindingDetails
, returned when your first attempt to mutate an ad failed. - Send a mutate request to create or update the ad again by including the stored ignorable policy topics.
In this guide, we create an expanded text ad as an example, but the steps for requesting exemption is the same for all ad types and similar for all mutates (create & update).
Store all ignorable policy topics
The error details for ads will be included in
PolicyFindingDetails
, which in turn stores a
list of PolicyTopicEntry
objects.
In this step, you need to store the topic
field of each PolicyTopicEntry
:
Java
private List<String> fetchIgnorablePolicyTopics(GoogleAdsException gae) { System.out.println("Google Ads failure details:"); // Creates a list to store the result. List<String> ignorableTopics = new ArrayList<>(); // Searches all errors for ignorable policy topics. for (GoogleAdsError error : gae.getGoogleAdsFailure().getErrorsList()) { // Supports sending exemption request for the policy finding error only. if (error.getErrorCode().getErrorCodeCase() != ErrorCodeCase.POLICY_FINDING_ERROR) { throw gae; } // Shows some information about the error encountered. System.out.printf("\t%s: %s%n", error.getErrorCode().getErrorCodeCase(), error.getMessage()); // Checks policy finding details for ignorable policy topics. if (error.getDetails() != null) { PolicyFindingDetails policyFindingDetails = error.getDetails().getPolicyFindingDetails(); if (policyFindingDetails != null) { System.out.println("\tPolicy finding details:"); // Shows all the policy topics for the current error. for (PolicyTopicEntry policyTopicEntry : policyFindingDetails.getPolicyTopicEntriesList()) { // Adds this topic to the result. ignorableTopics.add(policyTopicEntry.getTopic()); System.out.printf("\t\tPolicy topic name: '%s'%n", policyTopicEntry.getTopic()); System.out.printf("\t\tPolicy topic entry type: '%s'%n", policyTopicEntry.getType()); // For the sake of brevity, we exclude printing "policy topic evidences" and // "policy topic constraints" here. You can fetch those data by calling: // - policyTopicEntry.getEvidences() // - policyTopicEntry.getConstraints() } } } } return ignorableTopics; }
C#
private static string[] FetchIgnorablePolicyTopics(GoogleAdsException ex) { List<string> ignorablePolicyTopics = new List<string>(); ; Console.WriteLine("Google Ads failure details:"); foreach (GoogleAdsError error in ex.Failure.Errors) { if (error.ErrorCode.ErrorCodeCase != ErrorCode.ErrorCodeOneofCase.PolicyFindingError) { throw ex; } if (error.Details != null && error.Details.PolicyFindingDetails != null) { PolicyFindingDetails details = error.Details.PolicyFindingDetails; Console.WriteLine($"- Policy finding details:"); foreach (PolicyTopicEntry entry in details.PolicyTopicEntries) { ignorablePolicyTopics.Add(entry.Topic); Console.WriteLine($" - Policy topic name: '{entry.Topic}"); Console.WriteLine($" - Policy topic entry type: '{entry.Type}"); // For the sake of brevity, we exclude printing "policy topic evidences" // and "policy topic constraints" here. You can fetch those data by // calling: // - entry.Evidences // - entry.Constraints } } } return ignorablePolicyTopics.ToArray(); }
PHP
private static function fetchIgnorablePolicyTopics(GoogleAdsException $googleAdsException) { $ignorablePolicyTopics = []; printf("Google Ads failure details:%s", PHP_EOL); foreach ($googleAdsException->getGoogleAdsFailure()->getErrors() as $error) { /** @var GoogleAdsError $error */ if ($error->getErrorCode()->getErrorCode() !== 'policy_finding_error') { // This example supports sending exemption request for the policy finding error // only. throw $googleAdsException; } printf( "\t%s: %s%s", $error->getErrorCode()->getErrorCode(), $error->getMessage(), PHP_EOL ); if ( !is_null($error->getDetails()) && !is_null($error->getDetails()->getPolicyFindingDetails()) ) { $policyFindingDetails = $error->getDetails()->getPolicyFindingDetails(); printf("\tPolicy finding details:%s", PHP_EOL); foreach ($policyFindingDetails->getPolicyTopicEntries() as $policyTopicEntry) { /** @var PolicyTopicEntry $policyTopicEntry */ $ignorablePolicyTopics[] = $policyTopicEntry->getTopic(); printf( "\t\tPolicy topic name: '%s'%s", $policyTopicEntry->getTopic(), PHP_EOL ); printf( "\t\tPolicy topic entry type: '%s'%s", PolicyTopicEntryType::name($policyTopicEntry->getType()), PHP_EOL ); // For the sake of brevity, we exclude printing "policy topic evidences" and // "policy topic constraints" here. You can fetch those data by calling: // - $policyTopicEntry->getEvidences() // - $policyTopicEntry->getConstraints() } } } return $ignorablePolicyTopics; }
Python
def _fetch_ignorable_policy_topics(client, googleads_exception): """Collects all ignorable policy topics to be sent for exemption request. Args: client: The GoogleAds client instance. googleads_exception: The exception that contains the policy violation(s). Returns: A list of ignorable policy topics. """ ignorable_policy_topics = [] print("Google Ads failure details:") for error in googleads_exception.failure.errors: if ( error.error_code.policy_finding_error != client.get_type( "PolicyFindingErrorEnum" ).PolicyFindingError.POLICY_FINDING ): print( "This example supports sending exemption request for the " "policy finding error only." ) raise googleads_exception print(f"\t{error.error_code.policy_finding_error}: {error.message}") if ( error.details is not None and error.details.policy_finding_details is not None ): policy_finding_details = error.details.policy_finding_details print("\tPolicy finding details:") for ( policy_topic_entry ) in policy_finding_details.policy_topic_entries: ignorable_policy_topics.append(policy_topic_entry.topic) print(f"\t\tPolicy topic name: '{policy_topic_entry.topic}'") print( f"\t\tPolicy topic entry type: '{policy_topic_entry.type_}'" ) # For the sake of brevity, we exclude printing "policy topic # evidences" and "policy topic constraints" here. You can fetch # those data by calling: # - policy_topic_entry.evidences # - policy_topic_entry.constraints return ignorable_policy_topics
Ruby
def fetch_ignorable_policy_topics(exception) ignorable_policy_topics = [] exception.failure.errors.each do |error| if error.error_code.policy_finding_error != :POLICY_FINDING puts "Non-policy finding error found. Aborting." raise exception end puts "#{error.error_code.policy_finding_error}: #{error.message}" error&.details&.policy_finding_details&.policy_topic_entries.each do |entry| ignorable_policy_topics << entry.topic puts "\tPolicy topic name: #{entry.topic}" puts "\tPolicy topic entry type: #{entry.type}" end end ignorable_policy_topics end
Perl
sub fetch_ignorable_policy_topics { my $google_ads_exception = shift; my $ignorable_policy_topics = []; printf "Google Ads failure details:\n"; foreach my $error (@{$google_ads_exception->get_google_ads_failure()->{errors}}) { if ([keys %{$error->{errorCode}}]->[0] ne "policyFindingError") { # This example supports sending exemption request for the policy finding # error only. die $google_ads_exception->get_message(); } printf "\t%s: %s\n", [keys %{$error->{errorCode}}]->[0], $error->{message}; if ($error->{details}{policyFindingDetails}) { my $policy_finding_details = $error->{details}{policyFindingDetails}; printf "\tPolicy finding details:\n"; foreach my $policy_topic_entry ( @{$policy_finding_details->{policyTopicEntries}}) { push @$ignorable_policy_topics, $policy_topic_entry->{topic}; printf "\t\tPolicy topic name: '%s'\n", $policy_topic_entry->{topic}; printf "\t\tPolicy topic entry type: '%s'\n", $policy_topic_entry->{type}; # For the sake of brevity, we exclude printing "policy topic evidences" and # "policy topic constraints" here. You can fetch those data by calling: # - $policy_topic_entry->{evidences} # - $policy_topic_entry->{constraints} } } } return $ignorable_policy_topics; }
Send another mutate request by including ignorable policy topics
- Create an object of
PolicyValidationParameter
. - Set stored ignorable policy topics to the
ignorable_policy_topics
field of the createdPolicyValidationParameter
. - Set the created
PolicyValidationParameter
to thepolicy_validation_parameter
field of anAdGroupAdOperation
in the case of a creation or anAdOperation
in the case of an update. - Send a mutate request with the created operation using
AdGroupAdService.MutateAdGroupAds
in the case of a creation orAdService.MutateAds
in the case of an update.
Java
private void requestExemption( List<String> ignorablePolicyTopics, AdGroupAdServiceClient client, AdGroupAdOperation operation, long customerID) { System.out.println( "Trying to add an expanded text ad again by requesting exemption for its policy" + " violations."); // Converts the operation back to a builder. AdGroupAdOperation.Builder operationBuilder = operation.toBuilder(); // Adds the exemption request. operationBuilder .getPolicyValidationParameterBuilder() .addAllIgnorablePolicyTopics(ignorablePolicyTopics); // Sends the request back to the API. MutateAdGroupAdsResponse response = client.mutateAdGroupAds( String.valueOf(customerID), ImmutableList.of(operationBuilder.build())); // Shows the newly added ad resource name. System.out.printf( "Successfully added an expanded text ad with resource name '%s' by requesting a policy" + " violation exemption.%n", response.getResults(0).getResourceName()); }
C#
private static void RequestExemption(long customerId, AdGroupAdServiceClient service, AdGroupAdOperation operation, string[] ignorablePolicyTopics) { Console.WriteLine("Try adding an expanded text ad again by requesting exemption for " + "its policy violations."); PolicyValidationParameter validationParameter = new PolicyValidationParameter(); validationParameter.IgnorablePolicyTopics.AddRange(ignorablePolicyTopics); operation.PolicyValidationParameter = validationParameter; MutateAdGroupAdsResponse response = service.MutateAdGroupAds( customerId.ToString(), new[] { operation }); Console.WriteLine($"Successfully added an expanded text ad with resource name " + $"'{response.Results[0].ResourceName}' by requesting for policy violation " + $"exemption."); }
PHP
private static function requestExemption( int $customerId, AdGroupAdServiceClient $adGroupAdServiceClient, AdGroupAdOperation $adGroupAdOperation, array $ignorablePolicyTopics ) { print "Try adding an expanded text ad again by requesting exemption for its policy" . " violations." . PHP_EOL; $adGroupAdOperation->setPolicyValidationParameter( new PolicyValidationParameter(['ignorable_policy_topics' => $ignorablePolicyTopics]) ); $response = $adGroupAdServiceClient->mutateAdGroupAds( $customerId, [$adGroupAdOperation] ); printf( "Successfully added an expanded text ad with resource name '%s' by requesting" . " for policy violation exemption.%s", $response->getResults()[0]->getResourceName(), PHP_EOL ); }
Python
def _request_exemption( customer_id, ad_group_ad_service_client, ad_group_ad_operation, ignorable_policy_topics, ): """Sends exemption requests for creating an expanded text ad. Args: customer_id: The customer ID for which to add the expanded text ad. ad_group_ad_service_client: The AdGroupAdService client instance. ad_group_ad_operation: The AdGroupAdOperation that returned policy violation(s). ignorable_policy_topics: The extracted list of policy topic entries. """ print( "Attempting to add an expanded text ad again by requesting exemption " "for its policy violations." ) ad_group_ad_operation.policy_validation_parameter.ignorable_policy_topics.extend( ignorable_policy_topics ) response = ad_group_ad_service_client.mutate_ad_group_ads( customer_id=customer_id, operations=[ad_group_ad_operation] ) print( "Successfully added an expanded text ad with resource name " f"'{response.results[0].resource_name}' for policy violation " "exemption." )
Ruby
def request_exemption( client, customer_id, ad_group_ad_service, ad_group_ad_operation, ignorable_policy_topics) # Add all the found ignorable policy topics to the operation. ad_group_ad_operation.policy_validation_parameter = client.resource.policy_validation_parameter do |pvp| pvp.ignorable_policy_topics.push( *ignorable_policy_topics ) end response = ad_group_ad_service.mutate_ad_group_ads( customer_id: customer_id, operations: [ad_group_ad_operation], ) puts "Successfully added an expanded text ad with resource name " \ "#{response.results.first.resource_name} for policy violation exception." end
Perl
sub request_exemption { my ($api_client, $customer_id, $ad_group_ad_operation, $ignorable_policy_topics) = @_; print "Try adding an expanded text ad again by requesting exemption for its " . "policy violations.\n"; $ad_group_ad_operation->{policyValidationParameter} = Google::Ads::GoogleAds::V10::Common::PolicyValidationParameter->new( {ignorablePolicyTopics => $ignorable_policy_topics}); my $ad_group_ads_response = $api_client->AdGroupAdService()->mutate({ customerId => $customer_id, operations => [$ad_group_ad_operation]}); printf "Successfully added an expanded text ad with resource name '%s' by " . "requesting for policy violation exemption.\n", $ad_group_ads_response->{results}[0]{resourceName}; }
Code examples
The ErrorHandling
folder of each client library
contains the following code example that shows how to use this feature: