Java
// Copyright 2020 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. package com.google.ads.googleads.examples.errorhandling; import com.beust.jcommander.Parameter; import com.google.ads.googleads.examples.utils.ArgumentNames; import com.google.ads.googleads.examples.utils.CodeSampleParams; import com.google.ads.googleads.lib.GoogleAdsClient; import com.google.ads.googleads.v17.common.KeywordInfo; import com.google.ads.googleads.v17.common.PolicyViolationKey; import com.google.ads.googleads.v17.enums.AdGroupCriterionStatusEnum.AdGroupCriterionStatus; import com.google.ads.googleads.v17.enums.KeywordMatchTypeEnum.KeywordMatchType; import com.google.ads.googleads.v17.errors.GoogleAdsError; import com.google.ads.googleads.v17.errors.GoogleAdsException; import com.google.ads.googleads.v17.errors.PolicyViolationDetails; import com.google.ads.googleads.v17.resources.AdGroupCriterion; import com.google.ads.googleads.v17.services.AdGroupCriterionOperation; import com.google.ads.googleads.v17.services.AdGroupCriterionServiceClient; import com.google.ads.googleads.v17.services.MutateAdGroupCriteriaResponse; import com.google.ads.googleads.v17.utils.ResourceNames; import com.google.common.collect.ImmutableList; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * Demonstrates how to request an exemption for policy violations of a keyword. * * <p>The example uses an exemptible policy-violating keyword by default. If you use a keyword that * contains non-exemptible policy violations, it will not be sent with exemptions requested and you * will still fail to create a keyword. * * <p>If you specify a keyword that doesn't violate any policies, this example will just add the * keyword as usual, similar to what the AddKeywords example does. * * <p>When you send a request to add a keyword after requesting a policy exemption for that keyword, * the request will pass as if you were adding a non-violating keyword. */ public class HandleKeywordPolicyViolations { private static class HandleKeywordPolicyViolationsParams extends CodeSampleParams { @Parameter(names = ArgumentNames.CUSTOMER_ID, required = true) private Long customerId; @Parameter(names = ArgumentNames.AD_GROUP_ID, required = true) private Long adGroupId; @Parameter(names = ArgumentNames.KEYWORD_TEXT) private String keywordText = "medication"; } public static void main(String[] args) throws IOException { HandleKeywordPolicyViolationsParams params = new HandleKeywordPolicyViolationsParams(); if (!params.parseArguments(args)) { // Either pass the required parameters for this example on the command line, or insert them // into the code here. See the parameter class definition above for descriptions. params.customerId = Long.parseLong("INSERT_CUSTOMER_ID_HERE"); params.adGroupId = Long.parseLong("INSERT_AD_GROUP_ID_HERE"); // Optional: Specify a keywordText here, or the default specified above will be used. // params.keywordText = "INSERT_KEYWORD_TEXT_HERE"; } GoogleAdsClient googleAdsClient = null; try { googleAdsClient = GoogleAdsClient.newBuilder().fromPropertiesFile().build(); } catch (FileNotFoundException fnfe) { System.err.printf( "Failed to load GoogleAdsClient configuration from file. Exception: %s%n", fnfe); System.exit(1); } catch (IOException ioe) { System.err.printf("Failed to create GoogleAdsClient. Exception: %s%n", ioe); System.exit(1); } try { new HandleKeywordPolicyViolations() .runExample(googleAdsClient, params.customerId, params.adGroupId, params.keywordText); } catch (GoogleAdsException gae) { // GoogleAdsException is the base class for most exceptions thrown by an API request. // Instances of this exception have a message and a GoogleAdsFailure that contains a // collection of GoogleAdsErrors that indicate the underlying causes of the // GoogleAdsException. System.err.printf( "Request ID %s failed due to GoogleAdsException. Underlying errors:%n", gae.getRequestId()); int i = 0; for (GoogleAdsError googleAdsError : gae.getGoogleAdsFailure().getErrorsList()) { System.err.printf(" Error %d: %s%n", i++, googleAdsError); } System.exit(1); } } /** * Runs the example. * * @param googleAdsClient the Google Ads API client. * @param customerId the client customer ID. * @param adGroupId the ID of the ad group to add a keyword to. * @param keywordText the keyword text to add. * @throws GoogleAdsException if an API request failed with one or more service errors. */ private void runExample( GoogleAdsClient googleAdsClient, long customerId, Long adGroupId, String keywordText) { try (AdGroupCriterionServiceClient adGroupCriterionServiceClient = googleAdsClient.getLatestVersion().createAdGroupCriterionServiceClient()) { // Configures the keyword text and match type settings. KeywordInfo keywordInfo = KeywordInfo.newBuilder() .setText(keywordText) .setMatchType(KeywordMatchType.EXACT) .build(); // Constructs an ad group criterion using the keyword text info above. AdGroupCriterion adGroupCriterion = AdGroupCriterion.newBuilder() .setAdGroup(ResourceNames.adGroup(customerId, adGroupId)) .setStatus(AdGroupCriterionStatus.ENABLED) .setKeyword(keywordInfo) .build(); // Constructs an operation to create the ad group criterion. AdGroupCriterionOperation operation = AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterion).build(); // Tries sending a mutate request to add the keyword. List<PolicyViolationKey> exemptibleKeys = new ArrayList<>(); int errorCount = 0; try { MutateAdGroupCriteriaResponse response = adGroupCriterionServiceClient.mutateAdGroupCriteria( String.valueOf(customerId), ImmutableList.of(operation)); // If the request succeeded, then either the keyword does not require a policy exemption or // a policy exemption was previously submitted for the keyword. In either case, returns and // skips the remaining portion of this example that resubmits with an exemption request. System.out.printf( "Successfully added a keyword with resource name '%s'. No exemptions needed.%n", response.getResults(0).getResourceName()); return; } catch (GoogleAdsException e) { exemptibleKeys = extractExemptiblePolicyViolationKeys(e); errorCount = e.getGoogleAdsFailure().getErrorsCount(); } // Tries sending exemption requests for creating the keyword. However, if your keyword // contains many policy violations, but not all of them are exemptible, the request will not // be sent. if (exemptibleKeys.size() == errorCount) { System.out.println( "Attempting to add the keyword again by requesting exemption for its policy" + " violations."); // Creates a modified version of the operation with the exempt policy violation keys. operation = operation.toBuilder().addAllExemptPolicyViolationKeys(exemptibleKeys).build(); // Tries sending the mutate request again. MutateAdGroupCriteriaResponse response = adGroupCriterionServiceClient.mutateAdGroupCriteria( String.valueOf(customerId), ImmutableList.of(operation)); System.out.printf( "Successfully added a keyword with resource name '%s' by requesting " + "policy violation exemptions.%n", response.getResults(0).getResourceName()); } else { System.out.println("No exemption request was sent because either:"); System.out.println("1) your keyword contained some non-exemptible policy violations, or"); System.out.println("2) other non-policy related errors were thrown"); } } } /** * Collects all policy violation keys that can be exempted for sending an exemption request later. * * @param googleAdsException the exception to extract the keys from. * @return the list of extracted exemptible keys. */ private List<PolicyViolationKey> extractExemptiblePolicyViolationKeys( GoogleAdsException googleAdsException) { List<PolicyViolationKey> exemptibleKeys = new ArrayList<>(); System.out.println("Google Ads failure details:"); for (GoogleAdsError googleAdsError : googleAdsException.getGoogleAdsFailure().getErrorsList()) { System.out.printf("\t%s: %s%n", googleAdsError.getErrorCode(), googleAdsError.getMessage()); if (googleAdsError.hasDetails() && googleAdsError.getDetails().hasPolicyViolationDetails()) { PolicyViolationDetails policyViolationDetails = googleAdsError.getDetails().getPolicyViolationDetails(); System.out.println("\tPolicy violation details:"); System.out.printf( "\t\tExternal policy name: '%s'%n", policyViolationDetails.getExternalPolicyName()); System.out.printf( "\t\tExternal policy description: '%s'%n", policyViolationDetails.getExternalPolicyDescription()); System.out.printf("\t\tIs exemptible? '%s'%n", policyViolationDetails.getIsExemptible()); if (policyViolationDetails.getIsExemptible() && policyViolationDetails.hasKey()) { PolicyViolationKey policyViolationKey = policyViolationDetails.getKey(); exemptibleKeys.add(policyViolationKey); System.out.println("\t\tPolicy violation key:"); System.out.printf("\t\t\tName: '%s'%n", policyViolationKey.getPolicyName()); System.out.printf("\t\t\tViolating text: '%s'%n", policyViolationKey.getViolatingText()); } } } return exemptibleKeys; } }
C#
// Copyright 2020 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 // // 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. using CommandLine; using Google.Ads.Gax.Examples; using Google.Ads.GoogleAds.Lib; using Google.Ads.GoogleAds.V17.Common; using Google.Ads.GoogleAds.V17.Errors; using Google.Ads.GoogleAds.V17.Resources; using Google.Ads.GoogleAds.V17.Services; using System; using System.Collections.Generic; using static Google.Ads.GoogleAds.V17.Enums.AdGroupCriterionStatusEnum.Types; using static Google.Ads.GoogleAds.V17.Enums.KeywordMatchTypeEnum.Types; namespace Google.Ads.GoogleAds.Examples.V17 { /// <summary> /// This code example demonstrates how to request an exemption for policy violations of a /// keyword. Note that the example uses an exemptible policy-violating keyword by default. /// If you use a keyword that contains non-exemptible policy violations, they will not be /// sent for exemption request and you will still fail to create a keyword. /// If you specify a keyword that doesn't violate any policies, this example will just add the /// keyword as usual, similar to what the AddKeywords example does. /// Note that once you've requested policy exemption for a keyword, when you send a request for /// adding it again, the request will pass like when you add a non-violating keyword. /// </summary> public class HandleKeywordPolicyViolations : ExampleBase { /// <summary> /// Command line options for running the <see cref="HandleKeywordPolicyViolations"/> example. /// </summary> public class Options : OptionsBase { /// <summary> /// The customer ID for which the call is made. /// </summary> [Option("customerId", Required = true, HelpText = "The customer ID for which the call is made.")] public long CustomerId { get; set; } /// <summary> /// ID of the ad group to which keywords are added. /// </summary> [Option("adGroupId", Required = true, HelpText = "ID of the ad group to which keywords are added.")] public long AdGroupId { get; set; } /// <summary> /// The keyword text to add to the ad group. /// </summary> [Option("keywordText", Required = false, HelpText = "The keyword text to add to the ad group.")] public string KeywordText { get; set; } } /// <summary> /// Main method, to run this code example as a standalone application. /// </summary> /// <param name="args">The command line arguments.</param> public static void Main(string[] args) { Options options = ExampleUtilities.ParseCommandLine<Options>(args); HandleKeywordPolicyViolations codeExample = new HandleKeywordPolicyViolations(); Console.WriteLine(codeExample.Description); codeExample.Run(new GoogleAdsClient(), options.CustomerId, options.AdGroupId, options.KeywordText); } /// <summary> /// The default keyword to be used if keyword is not provided. /// </summary> private const string DEFAULT_KEYWORD = "medication"; /// <summary> /// Returns a description about the code example. /// </summary> public override string Description => "This code example demonstrates how to request an exemption for policy violations of " + "a keyword. Note that the example uses an exemptible policy-violating keyword by " + "default. If you use a keyword that contains non-exemptible policy violations, they " + "will not be sent for exemption request and you will still fail to create a keyword. " + "If you specify a keyword that doesn't violate any policies, this example will just " + "add the keyword as usual, similar to what the AddKeywords example does. Note that " + "once you've requested policy exemption for a keyword, when you send a request for " + "adding it again, the request will pass like when you add a non-violating keyword."; /// <summary> /// Runs the code example. /// </summary> /// <param name="client">The Google Ads client.</param> /// <param name="customerId">The customer ID for which the call is made.</param> /// <param name="adGroupId">ID of the ad group to which keywords are added.</param> /// <param name="keywordText">The keyword text to add to the ad group.</param> public void Run(GoogleAdsClient client, long customerId, long adGroupId, string keywordText) { // Get the AdGroupCriterionServiceClient. AdGroupCriterionServiceClient service = client.GetService( Services.V17.AdGroupCriterionService); if (string.IsNullOrEmpty(keywordText)) { keywordText = DEFAULT_KEYWORD; } // Configures the keyword text and match type settings. KeywordInfo keywordInfo = new KeywordInfo() { Text = keywordText, MatchType = KeywordMatchType.Exact }; // Constructs an ad group criterion using the keyword text info above. AdGroupCriterion adGroupCriterion = new AdGroupCriterion() { AdGroup = ResourceNames.AdGroup(customerId, adGroupId), Status = AdGroupCriterionStatus.Paused, Keyword = keywordInfo }; AdGroupCriterionOperation operation = new AdGroupCriterionOperation() { Create = adGroupCriterion }; try { try { // Try sending a mutate request to add the keyword. MutateAdGroupCriteriaResponse response = service.MutateAdGroupCriteria( customerId.ToString(), new[] { operation }); Console.WriteLine($"Added a keyword with resource name " + $"'{response.Results[0].ResourceName}'."); } catch (GoogleAdsException ex) { PolicyViolationKey[] exemptPolicyViolationKeys = FetchExemptPolicyViolationKeys(ex); // Try sending exemption requests for creating a keyword. However, if your // keyword contains many policy violations, but not all of them are exemptible, // the request will not be sent. RequestExemption(customerId, service, operation, exemptPolicyViolationKeys); } } catch (GoogleAdsException e) { Console.WriteLine("Failure:"); Console.WriteLine($"Message: {e.Message}"); Console.WriteLine($"Failure: {e.Failure}"); Console.WriteLine($"Request ID: {e.RequestId}"); throw; } } /// <summary> /// Collects all policy violation keys that can be exempted for sending a exemption /// request later. /// </summary> /// <param name="ex">The Google Ads exception.</param> /// <returns>The exemptible policy violation keys.</returns> private static PolicyViolationKey[] FetchExemptPolicyViolationKeys(GoogleAdsException ex) { bool isFullyExemptable = true; List<PolicyViolationKey> exemptPolicyViolationKeys = new List<PolicyViolationKey>(); Console.WriteLine("Google Ads failure details:"); foreach (GoogleAdsError error in ex.Failure.Errors) { if (error.ErrorCode.ErrorCodeCase != ErrorCode.ErrorCodeOneofCase.PolicyViolationError) { Console.WriteLine("No exemption request is sent because there are other " + "non-policy related errors thrown."); throw ex; } if (error.Details != null && error.Details.PolicyViolationDetails != null) { PolicyViolationDetails details = error.Details.PolicyViolationDetails; Console.WriteLine($"- Policy violation details:"); Console.WriteLine(" - Policy violation details:"); Console.WriteLine($" - External policy name: '{details.ExternalPolicyName}'"); Console.WriteLine($" - External policy description: " + $"'{details.ExternalPolicyDescription}'"); Console.WriteLine($" - Is exemptable: '{details.IsExemptible}'"); if (details.IsExemptible && details.Key != null) { PolicyViolationKey key = details.Key; Console.WriteLine($" - Policy violation key:"); Console.WriteLine($" - Name: {key.PolicyName}"); Console.WriteLine($" - Violating Text: {key.ViolatingText}"); exemptPolicyViolationKeys.Add(key); } else { isFullyExemptable = false; } } } if (!isFullyExemptable) { Console.WriteLine("No exemption request is sent because your keyword " + "contained some non-exemptible policy violations."); throw ex; } return exemptPolicyViolationKeys.ToArray(); } /// <summary> /// Sends exemption requests for creating a keyword. /// </summary> /// <param name="customerId">The customer ID for which the call is made.</param> /// <param name="service">The ad group criterion service.</param> /// <param name="operation">The ad group criterion operation to request exemption for. /// </param> /// <param name="exemptPolicyViolationKeys">The exemptable policy violation keys.</param> private static void RequestExemption( long customerId, AdGroupCriterionServiceClient service, AdGroupCriterionOperation operation, PolicyViolationKey[] exemptPolicyViolationKeys) { Console.WriteLine("Try adding a keyword again by requesting exemption for its policy " + "violations."); PolicyValidationParameter validationParameter = new PolicyValidationParameter(); validationParameter.ExemptPolicyViolationKeys.AddRange(exemptPolicyViolationKeys); operation.ExemptPolicyViolationKeys.AddRange(exemptPolicyViolationKeys); MutateAdGroupCriteriaResponse response = service.MutateAdGroupCriteria( customerId.ToString(), new[] { operation }); Console.WriteLine($"Successfully added a keyword with resource name " + $"'{response.Results[0].ResourceName}' by requesting for policy violation " + $"exemption."); } } }
PHP
<?php /** * Copyright 2019 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. */ namespace Google\Ads\GoogleAds\Examples\ErrorHandling; require __DIR__ . '/../../vendor/autoload.php'; use GetOpt\GetOpt; use Google\Ads\GoogleAds\Examples\Utils\ArgumentNames; use Google\Ads\GoogleAds\Examples\Utils\ArgumentParser; use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder; use Google\Ads\GoogleAds\Lib\V17\GoogleAdsClient; use Google\Ads\GoogleAds\Lib\V17\GoogleAdsClientBuilder; use Google\Ads\GoogleAds\Lib\V17\GoogleAdsException; use Google\Ads\GoogleAds\Util\V17\ResourceNames; use Google\Ads\GoogleAds\V17\Common\KeywordInfo; use Google\Ads\GoogleAds\V17\Common\PolicyViolationKey; use Google\Ads\GoogleAds\V17\Enums\AdGroupCriterionStatusEnum\AdGroupCriterionStatus; use Google\Ads\GoogleAds\V17\Enums\KeywordMatchTypeEnum\KeywordMatchType; use Google\Ads\GoogleAds\V17\Errors\GoogleAdsError; use Google\Ads\GoogleAds\V17\Resources\AdGroupCriterion; use Google\Ads\GoogleAds\V17\Services\AdGroupCriterionOperation; use Google\Ads\GoogleAds\V17\Services\Client\AdGroupCriterionServiceClient; use Google\Ads\GoogleAds\V17\Services\MutateAdGroupCriteriaRequest; use Google\ApiCore\ApiException; /** * This example demonstrates how to request an exemption for policy violations of a keyword. * Note that the example uses an exemptible policy-violating keyword by default. If you use a * keyword that contains non-exemptible policy violations, they will not be sent for exemption * request and you will still fail to create a keyword. * If you specify a keyword that doesn't violate any policies, this example will just add the * keyword as usual, similar to what the AddKeywords example does. * * Note that once you've requested policy exemption for a keyword, when you send a request for * adding it again, the request will pass like when you add a non-violating keyword. */ class HandleKeywordPolicyViolations { private const CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE'; private const AD_GROUP_ID = 'INSERT_AD_GROUP_ID_HERE'; // Specify the keyword text here or the default specified below will be used. private const KEYWORD_TEXT = 'medication'; public static function main() { // Either pass the required parameters for this example on the command line, or insert them // into the constants above. $options = (new ArgumentParser())->parseCommandArguments([ ArgumentNames::CUSTOMER_ID => GetOpt::REQUIRED_ARGUMENT, ArgumentNames::AD_GROUP_ID => GetOpt::REQUIRED_ARGUMENT, ArgumentNames::KEYWORD_TEXT => GetOpt::OPTIONAL_ARGUMENT ]); // Generate a refreshable OAuth2 credential for authentication. $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build(); // Construct a Google Ads client configured from a properties file and the // OAuth2 credentials above. $googleAdsClient = (new GoogleAdsClientBuilder())->fromFile() ->withOAuth2Credential($oAuth2Credential) // We set this value to true to show how to use GAPIC v2 source code. You can remove the // below line if you wish to use the old-style source code. Note that in that case, you // probably need to modify some parts of the code below to make it work. // For more information, see // https://developers.devsite.corp.google.com/google-ads/api/docs/client-libs/php/gapic. ->usingGapicV2Source(true) ->build(); try { self::runExample( $googleAdsClient, $options[ArgumentNames::CUSTOMER_ID] ?: self::CUSTOMER_ID, $options[ArgumentNames::AD_GROUP_ID] ?: self::AD_GROUP_ID, $options[ArgumentNames::KEYWORD_TEXT] ?: self::KEYWORD_TEXT ); } catch (GoogleAdsException $googleAdsException) { printf( "Request with ID '%s' has failed.%sGoogle Ads failure details:%s", $googleAdsException->getRequestId(), PHP_EOL, PHP_EOL ); foreach ($googleAdsException->getGoogleAdsFailure()->getErrors() as $error) { /** @var GoogleAdsError $error */ printf( "\t%s: %s%s", $error->getErrorCode()->getErrorCode(), $error->getMessage(), PHP_EOL ); } exit(1); } catch (ApiException $apiException) { printf( "ApiException was thrown with message '%s'.%s", $apiException->getMessage(), PHP_EOL ); exit(1); } } /** * Runs the example. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the customer ID * @param int $adGroupId the ad group ID to add a keyword to * @param string $keywordText the keyword text to add */ public static function runExample( GoogleAdsClient $googleAdsClient, int $customerId, int $adGroupId, string $keywordText ) { // Configures the keyword text and match type settings. $keywordInfo = new KeywordInfo([ 'text' => $keywordText, 'match_type' => KeywordMatchType::EXACT ]); // Constructs an ad group criterion using the keyword text info above. $adGroupCriterion = new AdGroupCriterion([ 'ad_group' => ResourceNames::forAdGroup($customerId, $adGroupId), 'status' => AdGroupCriterionStatus::ENABLED, 'keyword' => $keywordInfo ]); $adGroupCriterionOperation = new AdGroupCriterionOperation(); $adGroupCriterionOperation->setCreate($adGroupCriterion); $adGroupCriterionServiceClient = $googleAdsClient->getAdGroupCriterionServiceClient(); try { // Try sending a mutate request to add the keyword. $response = $adGroupCriterionServiceClient->mutateAdGroupCriteria( MutateAdGroupCriteriaRequest::build($customerId, [$adGroupCriterionOperation]) ); printf( "Added a keyword with resource name '%s'.%s", $response->getResults()[0]->getResourceName(), PHP_EOL ); } catch (GoogleAdsException $googleAdsException) { // Try sending exemption requests for creating a keyword. However, if your keyword // contains many policy violations, but not all of them are exemptible, the request // will not be sent. $exemptPolicyViolationKeys = self::fetchExemptPolicyViolationKeys($googleAdsException); self::requestExemption( $customerId, $adGroupCriterionServiceClient, $adGroupCriterionOperation, $exemptPolicyViolationKeys ); } } /** * Collects all policy violation keys that can be exempted for sending a exemption request * later. * * @param GoogleAdsException $googleAdsException the Google Ads exception * @return PolicyViolationKey[] the exemptible policy violation keys */ private static function fetchExemptPolicyViolationKeys(GoogleAdsException $googleAdsException) { $exemptPolicyViolationKeys = []; printf("Google Ads failure details:%s", PHP_EOL); foreach ($googleAdsException->getGoogleAdsFailure()->getErrors() as $error) { /** @var GoogleAdsError $error */ printf( "\t%s: %s%s", $error->getErrorCode()->getErrorCode(), $error->getMessage(), PHP_EOL ); if ( !is_null($error->getDetails()) && !is_null($error->getDetails()->getPolicyViolationDetails()) ) { $policyViolationDetails = $error->getDetails()->getPolicyViolationDetails(); printf("\tPolicy violation details:%s", PHP_EOL); printf( "\t\tExternal policy name: '%s'%s", $policyViolationDetails->getExternalPolicyName(), PHP_EOL ); printf( "\t\tExternal policy description: '%s'%s", $policyViolationDetails->getExternalPolicyDescription(), PHP_EOL ); printf( "\t\tIs exemptible? '%s'%s", $policyViolationDetails->getIsExemptible() ? 'yes' : 'no', PHP_EOL ); if ( $policyViolationDetails->getIsExemptible() && !is_null($policyViolationDetails->getKey()) ) { $policyViolationDetailsKey = $policyViolationDetails->getKey(); $exemptPolicyViolationKeys[] = $policyViolationDetailsKey; printf("\t\tPolicy violation key:%s", PHP_EOL); printf( "\t\t\tName: '%s'%s", $policyViolationDetailsKey->getPolicyName(), PHP_EOL ); printf( "\t\t\tViolating text: '%s'%s", $policyViolationDetailsKey->getViolatingText(), PHP_EOL ); } else { print "No exemption request is sent because your keyword contained some " . "non-exemptible policy violations." . PHP_EOL; throw $googleAdsException; } } else { print "No exemption request is sent because there are other non-policy related " . "errors thrown." . PHP_EOL; throw $googleAdsException; } } return $exemptPolicyViolationKeys; } /** * Sends exemption requests for creating a keyword. * * @param int $customerId the customer ID * @param AdGroupCriterionServiceClient $adGroupCriterionServiceClient the ad group criterion * service API client * @param AdGroupCriterionOperation $adGroupCriterionOperation the ad group criterion operation * to request exemption for * @param PolicyViolationKey[] $exemptPolicyViolationKeys the exemptible policy violation keys */ private static function requestExemption( int $customerId, AdGroupCriterionServiceClient $adGroupCriterionServiceClient, AdGroupCriterionOperation $adGroupCriterionOperation, array $exemptPolicyViolationKeys ) { print "Try adding a keyword again by requesting exemption for its policy" . " violations." . PHP_EOL; $adGroupCriterionOperation->setExemptPolicyViolationKeys($exemptPolicyViolationKeys); $response = $adGroupCriterionServiceClient->mutateAdGroupCriteria( MutateAdGroupCriteriaRequest::build($customerId, [$adGroupCriterionOperation]) ); printf( "Successfully added a keyword with resource name '%s' by requesting for" . " policy violation exemption.%s", $response->getResults()[0]->getResourceName(), PHP_EOL ); } } HandleKeywordPolicyViolations::main();
Python
#!/usr/bin/env python # Copyright 2020 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. """Demonstrates how to request an exemption for policy violations of a keyword. Note that the example uses an exemptible policy-violating keyword by default. If you use a keyword that contains non-exemptible policy violations, they will not be sent for exemption request, and you will still fail to create a keyword. If you specify a keyword that doesn't violate any policies, this example will just add the keyword as usual, similar to what the AddKeywords example does. Note that once you've requested policy exemption for a keyword, when you send a request for adding it again, the request will pass like when you add a non-violating keyword. """ import argparse import sys from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException def main(client, customer_id, ad_group_id, keyword_text): """Demonstrates how to request an exemption for keyword policy violations. Args: client: The Google Ads client. customer_id: The customer ID for which to add the keyword. ad_group_id: The ad group ID to which to add keyword. keyword_text: The keyword text to add. """ ad_group_criterion_service = client.get_service("AdGroupCriterionService") ( googleads_exception, ad_group_criterion_operation, ) = create_keyword_criterion( client, ad_group_criterion_service, customer_id, ad_group_id, keyword_text, ) try: # Try sending exemption requests for creating a keyword. However, if # your keyword contains many policy violations, but not all of them are # exemptible, the request will not be sent. if googleads_exception is not None: exempt_policy_violation_keys = fetch_exempt_policy_violation_keys( googleads_exception ) request_exemption( customer_id, ad_group_criterion_service, ad_group_criterion_operation, exempt_policy_violation_keys, ) except GoogleAdsException as ex: print( f"Request with ID '{ex.request_id}' failed with status " f"'{ex.error.code().name}' and includes the following errors:" ) for error in ex.failure.errors: print(f"\tError with message '{error.message}'.") if error.location: for field_path_element in error.location.field_path_elements: print(f"\t\tOn field: {field_path_element.field_name}") sys.exit(1) def create_keyword_criterion( client, ad_group_criterion_service, customer_id, ad_group_id, keyword_text ): """Attempts to add a keyword criterion to an ad group. Args: client: The GoogleAds client instance. ad_group_criterion_service: The AdGroupCriterionService client instance. customer_id: The customer ID for which to add the expanded text ad. ad_group_id: The ad group ID to which to add an expanded text ad. keyword_text: The keyword text to add. Returns: The GoogleAdsException that occurred (or None if the operation was successful) and the modified operation. """ # Constructs an ad group criterion using the keyword text provided. ad_group_criterion_operation = client.get_type("AdGroupCriterionOperation") ad_group_criterion = ad_group_criterion_operation.create ad_group_criterion.ad_group = client.get_service( "AdGroupService" ).ad_group_path(customer_id, ad_group_id) ad_group_criterion.status = client.enums.AdGroupCriterionStatusEnum.ENABLED ad_group_criterion.keyword.text = keyword_text ad_group_criterion.keyword.match_type = ( client.enums.KeywordMatchTypeEnum.EXACT ) try: # Try sending a mutate request to add the keyword. response = ad_group_criterion_service.mutate_ad_group_criteria( customer_id=customer_id, operations=[ad_group_criterion_operation] ) except GoogleAdsException as googleads_exception: # Return the exception in order to extract keyword violation details. return googleads_exception, ad_group_criterion_operation # Report that the mutate request was completed successfully. print( "Added a keyword with resource name " f"'{response.results[0].resource_name}'." ) return None, ad_group_criterion_operation def fetch_exempt_policy_violation_keys(googleads_exception): """Collects all policy violation keys that can be exempted. Args: googleads_exception: The exception to check for policy violation(s). Returns: A list of policy violation keys. """ exempt_policy_violation_keys = [] print("Google Ads failure details:") for error in googleads_exception.failure.errors: print(f"\t{error.error_code}: {error.message}") if ( error.details is not None and error.details.policy_violation_details is not None ): policy_violation_details = error.details.policy_violation_details print( "\tPolicy violation details:\n" f"\t\tExternal policy name: '{policy_violation_details}'\n" "\t\tExternal policy description: " f"'{policy_violation_details.external_policy_description}'\n" f"\t\tIs exemptible? '{policy_violation_details.is_exemptible}'" ) if ( policy_violation_details.is_exemptible and policy_violation_details.key is not None ): exempt_policy_violation_keys.append( policy_violation_details.key ) print( f"\t\tPolicy violation key: {policy_violation_details.key}" ) print( f"\t\t\tName: '{policy_violation_details.key.policy_name}'" "\t\t\tViolating text: " f"'{policy_violation_details.key.violating_text}'" ) else: print( "No exemption request is sent because your keyword " "contained some non-exemptible policy violations." ) raise googleads_exception else: print( "No exemption request is sent because there are non-policy " "related errors thrown." ) raise googleads_exception return exempt_policy_violation_keys def request_exemption( customer_id, ad_group_criterion_service, ad_group_criterion_operation, exempt_policy_violation_keys, ): """Sends exemption requests for creating a keyword. Args: customer_id: The customer ID for which to add the expanded text ad. ad_group_criterion_service: The AdGroupCriterionService client instance. ad_group_criterion_operation: The AdGroupCriterionOperation for which to request exemption. exempt_policy_violation_keys: The exemptible policy violation keys. """ print( "Attempting to add a keyword again by requesting exemption for its " "policy violations." ) ad_group_criterion_operation.exempt_policy_violation_keys.extend( exempt_policy_violation_keys ) response = ad_group_criterion_service.mutate_ad_group_criteria( customer_id=customer_id, operations=[ad_group_criterion_operation] ) print( "Successfully added a keyword with resource name " f"'{response.results[0].resource_name}' by requesting a policy " "violation exemption." ) if __name__ == "__main__": parser = argparse.ArgumentParser( description="Demonstrates how to request an exemption for policy " "violations of a keyword." ) # The following argument(s) should be provided to run the example. parser.add_argument( "-c", "--customer_id", type=str, required=True, help="The Google Ads customer ID.", ) parser.add_argument( "-a", "--ad_group_id", type=str, required=True, help="The ad group ID to which to add an expanded text ad.", ) parser.add_argument( "-k", "--keyword_text", type=str, required=False, default="medication", help="Specify the keyword text here or use the default keyword " "'medication'.", ) args = parser.parse_args() # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client = GoogleAdsClient.load_from_storage(version="v17") main( googleads_client, args.customer_id, args.ad_group_id, args.keyword_text )
Ruby
# Encoding: utf-8 # # Copyright 2020 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. # # Demonstrates how to request an exemption for policy violations of a keyword. # # Note that the example uses an exemptible policy-violating keyword by default. # If you use a keyword that contains non-exemptible policy violations, they # will not be sent for exemption request and you will still fail to create a # keyword. If you specify a keyword that doesn't violate any policies, this # example will just add the keyword as usual, similar to what the AddKeywords # example does. # # Note that once you've requested policy exemption for a keyword, when you send # a request for adding it again, the request will pass like when you add a # non-violating keyword. require 'optparse' require 'google/ads/google_ads' require 'date' def handle_keyword_policy_violations(customer_id, ad_group_id, keyword_text) # GoogleAdsClient will read a config file from # ENV['HOME']/google_ads_config.rb when called without parameters client = Google::Ads::GoogleAds::GoogleAdsClient.new ad_group_criterion_service = client.service.ad_group_criterion exception, ad_group_criterion_operation = create_keyword_criterion( client, ad_group_criterion_service, customer_id, ad_group_id, keyword_text, ) unless exception.nil? exempt_policy_violation_keys = fetch_exempt_policy_violation_keys(exception) request_exemption( client, customer_id, ad_group_criterion_service, ad_group_criterion_operation, exempt_policy_violation_keys, ) end end def create_keyword_criterion( client, ad_group_criterion_service, customer_id, ad_group_id, keyword_text) ad_group_criterion_operation = client.operation.create_resource.ad_group_criterion do |agc| agc.ad_group = client.path.ad_group(customer_id, ad_group_id) agc.status = :ENABLED agc.keyword = client.resource.keyword_info do |ki| ki.match_type = :EXACT ki.text = keyword_text end end ignorable_policy_topics = [] begin ad_group_criterion_service.mutate_ad_group_criteria( customer_id: customer_id, operations: [ad_group_criterion_operation], ) rescue Google::Ads::GoogleAds::Errors::GoogleAdsError => e return e, ad_group_criterion_operation end return nil, ad_group_criterion_operation end def fetch_exempt_policy_violation_keys(exception) exempt_policy_violation_keys = [] exception.failure.errors.each do |error| details = error.details.policy_violation_details puts "Policy violation details:" puts "\tExternal policy name: #{details.external_policy_name}" puts "\tExternal policy description:\n#{details.external_policy_description}" puts "\tIs exemptible: #{details.is_exemptible}" if details.is_exemptible && !details.key.nil? exempt_policy_violation_keys << details.key puts "Policy violation key:" puts "\tPolicy Name: #{details.key.policy_name}" puts "\tViolating Text: #{details.key.violating_text}" else puts "No exemption request will be sent because your keyword contained "\ "some non-exemptible policy violations." end end exempt_policy_violation_keys end def request_exemption( client, customer_id, ad_group_criterion_service, ad_group_criterion_operation, exempt_policy_violation_keys ) # Add all the found ignorable policy topics to the operation. ad_group_criterion_operation.exempt_policy_violation_keys.push( *exempt_policy_violation_keys ) response = ad_group_criterion_service.mutate_ad_group_criteria( customer_id: customer_id, operations: [ad_group_criterion_operation], ) puts "Successfully added a keyword with resource name " \ "#{response.results.first.resource_name} for policy violation exception." end if __FILE__ == $PROGRAM_NAME options = {} # The following parameter(s) should be provided to run the example. You can # either specify these by changing the INSERT_XXX_ID_HERE values below, or on # the command line. # # Parameters passed on the command line will override any parameters set in # code. # # Running the example with -h will print the command line usage. options[:customer_id] = 'INSERT_CUSTOMER_ID_HERE' options[:ad_group_id] = 'INSERT_AD_GROUP_ID_HERE' options[:keyword_text] = 'INSERT_KEYWORD_TEXT_HERE' OptionParser.new do |opts| opts.banner = sprintf('Usage: ruby %s [options]', File.basename(__FILE__)) opts.separator '' opts.separator 'Options:' opts.on('-C', '--customer-id CUSTOMER-ID', String, 'Customer ID') do |v| options[:customer_id] = v end opts.on('-A', '--ad-group-id AD-GROUP-ID', String, 'Ad Group ID') do |v| options[:ad_group_id] = v end opts.on('-k', '--keyword-text KEYWORD-TEXT', String, 'Keyword') do |v| options[:keyword_text] = v end opts.separator '' opts.separator 'Help:' opts.on_tail('-h', '--help', 'Show this message') do puts opts exit end end.parse! begin handle_keyword_policy_violations( options.fetch(:customer_id).tr("-", ""), options.fetch(:ad_group_id), options.fetch(:keyword_text), ) rescue Google::Ads::GoogleAds::Errors::GoogleAdsError => e e.failure.errors.each do |error| STDERR.printf("Error with message: %s\n", error.message) if error.location error.location.field_path_elements.each do |field_path_element| STDERR.printf("\tOn field: %s\n", field_path_element.field_name) end end error.error_code.to_h.each do |k, v| next if v == :UNSPECIFIED STDERR.printf("\tType: %s\n\tCode: %s\n", k, v) end end raise end end
Perl
#!/usr/bin/perl -w # # Copyright 2019, 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 # # 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 demonstrates how to request an exemption for policy violations # of a keyword. Note that the example uses an exemptible policy-violating # keyword by default. If you use a keyword that contains non-exemptible policy # violations, they will not be sent for exemption request and you will still # fail to create a keyword. # If you specify a keyword that doesn't violate any policies, this example will # just add the keyword as usual, similar to what the add_keywords.pl example does. # # Note that once you've requested policy exemption for a keyword, when you send # a request for adding it again, the request will pass like when you add a # non-violating keyword. use strict; use warnings; use utf8; use FindBin qw($Bin); use lib "$Bin/../../lib"; use Google::Ads::GoogleAds::Client; use Google::Ads::GoogleAds::Utils::GoogleAdsHelper; use Google::Ads::GoogleAds::V17::Resources::AdGroupCriterion; use Google::Ads::GoogleAds::V17::Common::KeywordInfo; use Google::Ads::GoogleAds::V17::Enums::KeywordMatchTypeEnum qw(EXACT); use Google::Ads::GoogleAds::V17::Enums::AdGroupCriterionStatusEnum qw(ENABLED); use Google::Ads::GoogleAds::V17::Services::AdGroupCriterionService::AdGroupCriterionOperation; use Google::Ads::GoogleAds::V17::Utils::ResourceNames; use Getopt::Long qw(:config auto_help); use Pod::Usage; use Cwd qw(abs_path); # The following parameter(s) should be provided to run the example. You can # either specify these by changing the INSERT_XXX_ID_HERE values below, or on # the command line. # # Parameters passed on the command line will override any parameters set in # code. # # Running the example with -h will print the command line usage. my $customer_id = "INSERT_CUSTOMER_ID_HERE"; my $ad_group_id = "INSERT_AD_GROUP_ID_HERE"; my $keyword_text = "medication"; sub handle_keyword_policy_violations { my ($api_client, $customer_id, $ad_group_id, $keyword_text) = @_; # Configure the keyword text and match type settings. my $keyword_info = Google::Ads::GoogleAds::V17::Common::KeywordInfo->new({ text => $keyword_text, matchType => EXACT }); # Construct an ad group criterion using the keyword info above. my $ad_group_criterion = Google::Ads::GoogleAds::V17::Resources::AdGroupCriterion->new({ adGroup => Google::Ads::GoogleAds::V17::Utils::ResourceNames::ad_group( $customer_id, $ad_group_id ), status => ENABLED, keyword => $keyword_info }); # Create an ad group criterion operation. my $ad_group_criterion_operation = Google::Ads::GoogleAds::V17::Services::AdGroupCriterionService::AdGroupCriterionOperation ->new({create => $ad_group_criterion}); # Try sending a mutate request to add the keyword. my $response = $api_client->AdGroupCriterionService()->mutate({ customerId => $customer_id, operations => [$ad_group_criterion_operation]}); if ($response->isa("Google::Ads::GoogleAds::GoogleAdsException")) { my $exempt_policy_violation_keys = fetch_exempt_policy_violation_keys($response); # Try sending exemption requests for creating a keyword. However, if your # keyword contains many policy violations, but not all of them are exemptible, # the request will not be sent. if (@$exempt_policy_violation_keys == @{$response->get_google_ads_failure()->{errors}}) { request_exemption($api_client, $customer_id, $ad_group_criterion_operation, $exempt_policy_violation_keys); } else { print "No exemption request is sent because 1) your keyword contained " . "some non-exemptible policy violations or 2) there are other " . "non-policy related errors thrown.\n"; } } else { printf "Added a keyword with resource name '%s'.\n", $response->{results}[0]{resourceName}; } return 1; } # Collects all policy violation keys that can be exempted for sending a exemption # request later. sub fetch_exempt_policy_violation_keys { my $google_ads_exception = shift; my $exempt_policy_violation_keys = []; print "Google Ads failure details:\n"; foreach my $error (@{$google_ads_exception->get_google_ads_failure()->{errors}}) { printf "\t%s: %s\n", [keys %{$error->{errorCode}}]->[0], $error->{message}; if ($error->{details}{policyViolationDetails}) { my $policy_violation_details = $error->{details}{policyViolationDetails}; printf "\tPolicy violation details:\n"; printf "\t\tExternal policy name: '%s'\n", $policy_violation_details->{externalPolicyName}; printf "\t\tExternal policy description: '%s'\n", $policy_violation_details->{externalPolicyDescription}; printf "\t\tIs exemptible? '%s'\n", $policy_violation_details->{isExemptible} ? "yes" : "no"; if ( $policy_violation_details->{isExemptible} and $policy_violation_details->{key}) { my $policy_violation_details_key = $policy_violation_details->{key}; push @$exempt_policy_violation_keys, $policy_violation_details_key; printf "\t\tPolicy violation key:\n"; printf "\t\t\tName: '%s'\n", $policy_violation_details_key->{policyName}; printf "\t\t\tViolating text: '%s'\n", $policy_violation_details_key->{violatingText}; } } } return $exempt_policy_violation_keys; } # Sends exemption requests for creating a keyword. sub request_exemption { my ($api_client, $customer_id, $ad_group_criterion_operation, $exempt_policy_violation_keys) = @_; print "Try adding a keyword again by requesting exemption for its " . "policy violations.\n"; $ad_group_criterion_operation->{exemptPolicyViolationKeys} = $exempt_policy_violation_keys; my $ad_group_criteria_response = $api_client->AdGroupCriterionService()->mutate({ customerId => $customer_id, operations => [$ad_group_criterion_operation]}); printf "Successfully added a keyword with resource name '%s' by requesting " . "for policy violation exemption.\n", $ad_group_criteria_response->{results}[0]{resourceName}; } # Don't run the example if the file is being included. if (abs_path($0) ne abs_path(__FILE__)) { return 1; } # Get Google Ads Client, credentials will be read from ~/googleads.properties. my $api_client = Google::Ads::GoogleAds::Client->new(); # By default examples are set to die on any server returned fault. $api_client->set_die_on_faults(0); # Parameters passed on the command line will override any parameters set in code. GetOptions( "customer_id=s" => \$customer_id, "ad_group_id=i" => \$ad_group_id, "keyword_text=s" => \$keyword_text ); # Print the help message if the parameters are not initialized in the code nor # in the command line. pod2usage(2) if not check_params($customer_id, $ad_group_id, $keyword_text); # Call the example. handle_keyword_policy_violations($api_client, $customer_id =~ s/-//gr, $ad_group_id, $keyword_text); =pod =head1 NAME handle_keyword_policy_violations =head1 DESCRIPTION This example demonstrates how to request an exemption for policy violations of a keyword. Note that the example uses an exemptible policy-violating keyword by default. If you use a keyword that contains non-exemptible policy violations, they will not be sent for exemption request and you will still fail to create a keyword. If you specify a keyword that doesn't violate any policies, this example will just add the keyword as usual, similar to what the add_keywords.pl example does. Note that once you've requested policy exemption for a keyword, when you send a request for adding it again, the request will pass like when you add a non-violating keyword. =head1 SYNOPSIS handle_keyword_policy_violations.pl [options] -help Show the help message. -customer_id The Google Ads customer ID. -ad_group_id The ad group ID. -keyword_text [optional] The keyword to be added to the ad group. =cut