/// <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."); }
/// <summary>Snippet for MutateAdGroupCriteria</summary> /// <remarks> /// This snippet has been automatically generated for illustrative purposes only. /// It may require modifications to work in your environment. /// </remarks> public void MutateAdGroupCriteriaRequestObject() { // Create client AdGroupCriterionServiceClient adGroupCriterionServiceClient = AdGroupCriterionServiceClient.Create(); // Initialize request argument(s) MutateAdGroupCriteriaRequest request = new MutateAdGroupCriteriaRequest { CustomerId = "", Operations = { new AdGroupCriterionOperation(), }, PartialFailure = false, ValidateOnly = false, }; // Make the request MutateAdGroupCriteriaResponse response = adGroupCriterionServiceClient.MutateAdGroupCriteria(request); }
/// <summary>Snippet for MutateAdGroupCriteriaAsync</summary> public async Task MutateAdGroupCriteriaAsync() { // Snippet: MutateAdGroupCriteriaAsync(string, IEnumerable<AdGroupCriterionOperation>, CallSettings) // Additional: MutateAdGroupCriteriaAsync(string, IEnumerable<AdGroupCriterionOperation>, CancellationToken) // Create client AdGroupCriterionServiceClient adGroupCriterionServiceClient = await AdGroupCriterionServiceClient.CreateAsync(); // Initialize request argument(s) string customerId = ""; IEnumerable <AdGroupCriterionOperation> operations = new AdGroupCriterionOperation[] { new AdGroupCriterionOperation(), }; // Make the request MutateAdGroupCriteriaResponse response = await adGroupCriterionServiceClient.MutateAdGroupCriteriaAsync(customerId, operations); // End snippet }
/// <summary> /// Runs the code example. /// </summary> /// <param name="client">The Google Ads client.</param> /// <param name="customerId">The Google Ads customer Id.</param> /// <param name="adGroupId">The Google Ads ad group Id.</param> /// <param name="keywordId">The Google Ads keyword Id.</param> public void Run(GoogleAdsClient client, long customerId, long adGroupId, long keywordId) { // Get the CampaignCriterionService. AdGroupCriterionServiceClient adGroupCriterionService = client.GetService(Services.V4.AdGroupCriterionService); // Create the keyword for update. AdGroupCriterion keyword = new AdGroupCriterion() { ResourceName = ResourceNames.AdGroupCriterion(customerId, adGroupId, keywordId), CriterionId = keywordId, Status = AdGroupCriterionStatus.Enabled, FinalUrls = { "https://www.example.com" } }; AdGroupCriterionOperation keywordOperation = new AdGroupCriterionOperation() { Update = keyword, UpdateMask = FieldMasks.AllSetFieldsOf(keyword) }; try { // Update the keyword. MutateAdGroupCriteriaResponse response = adGroupCriterionService.MutateAdGroupCriteria(customerId.ToString(), new AdGroupCriterionOperation[] { keywordOperation }); // Display the results. foreach (MutateAdGroupCriterionResult criterionResult in response.Results) { Console.WriteLine($"Keyword with resource name = " + $"'{criterionResult.ResourceName}' was updated."); } } catch (GoogleAdsException e) { Console.WriteLine("Failure:"); Console.WriteLine($"Message: {e.Message}"); Console.WriteLine($"Failure: {e.Failure}"); Console.WriteLine($"Request ID: {e.RequestId}"); throw; } }
/// <summary> /// Removes all the ad group criteria that define the existing listing group tree for an /// ad group. Returns without an error if all listing group criterion are successfully /// removed. /// </summary> /// <param name="client">The Google Ads API client..</param> /// <param name="customerId">The client customer ID.</param> /// <param name="adGroupId">The ID of the ad group that the new listing group tree will /// be removed from.</param> /// <exception cref="GoogleAdsException">Thrown if an API request failed with one or more /// service errors.</exception> private void RemoveListingGroupTree(GoogleAdsClient client, long customerId, long adGroupId) { // Get the GoogleAdsService. GoogleAdsServiceClient googleAdsService = client.GetService( Services.V4.GoogleAdsService); // Get the AdGroupCriterionService. AdGroupCriterionServiceClient adGroupCriterionService = client.GetService(Services.V4.AdGroupCriterionService); String searchQuery = "SELECT ad_group_criterion.resource_name FROM " + "ad_group_criterion WHERE ad_group_criterion.type = LISTING_GROUP AND " + "ad_group_criterion.listing_group.parent_ad_group_criterion IS NULL " + $"AND ad_group.id = {adGroupId}"; // Creates a request that will retrieve all listing groups where the parent ad group // criterion is NULL (and hence the root node in the tree) for a given ad group ID. SearchGoogleAdsRequest request = new SearchGoogleAdsRequest() { CustomerId = customerId.ToString(), PageSize = PAGE_SIZE, Query = searchQuery }; // Issues the search request. GoogleAdsRow googleAdsRow = googleAdsService.Search(request).First(); AdGroupCriterion adGroupCriterion = googleAdsRow.AdGroupCriterion; Console.WriteLine("Found ad group criterion with the resource name: '{0}'.", adGroupCriterion.ResourceName); AdGroupCriterionOperation operation = new AdGroupCriterionOperation() { Remove = adGroupCriterion.ResourceName }; MutateAdGroupCriteriaResponse response = adGroupCriterionService.MutateAdGroupCriteria( customerId.ToString(), new AdGroupCriterionOperation[] { operation }); Console.WriteLine($"Removed {response.Results.Count}."); }
/// <summary> /// Runs the code example. /// </summary> /// <param name="client">The Google Ads client.</param> /// <param name="customerId">The Google Ads customer ID.</param> /// <param name="adGroupId">The ad group ID of the ad group to which the hotel listing will /// be added.</param> /// <param name="percentCpcBidMicroAmount">The CPC bid micro amount to be set on created /// ad group criteria.</param> public void Run(GoogleAdsClient client, long customerId, long adGroupId, long percentCpcBidMicroAmount) { // Get the AdGroupCriterionService client. AdGroupCriterionServiceClient adGroupCriterionService = client.GetService(Services.V6.AdGroupCriterionService); List <AdGroupCriterionOperation> operations = new List <AdGroupCriterionOperation>(); try { // Creates the root of the tree as a SUBDIVISION node. string rootResourceName = AddRootNode(customerId, adGroupId, operations, percentCpcBidMicroAmount); // Creates child nodes of level 1, partitioned by the hotel class info. string otherHotelResourceName = AddLevel1Nodes(customerId, adGroupId, rootResourceName, operations, percentCpcBidMicroAmount); // Creates child nodes of level 2, partitioned by the hotel country region info. AddLevel2Nodes(customerId, adGroupId, otherHotelResourceName, operations, percentCpcBidMicroAmount); // Adds the listing group and prints the resulting node resource names. MutateAdGroupCriteriaResponse response = adGroupCriterionService.MutateAdGroupCriteria(customerId.ToString(), operations); Console.WriteLine($"Added {response.Results.Count} listing group info entities " + "with resource names:"); foreach (MutateAdGroupCriterionResult adGroupCriterionResult in response.Results) { Console.WriteLine($"\t{adGroupCriterionResult.ResourceName}"); } } catch (GoogleAdsException e) { Console.WriteLine("Failure:"); Console.WriteLine($"Message: {e.Message}"); Console.WriteLine($"Failure: {e.Failure}"); Console.WriteLine($"Request ID: {e.RequestId}"); throw; } }
/// <summary>Snippet for MutateAdGroupCriteriaAsync</summary> /// <remarks> /// This snippet has been automatically generated for illustrative purposes only. /// It may require modifications to work in your environment. /// </remarks> public async Task MutateAdGroupCriteriaRequestObjectAsync() { // Create client AdGroupCriterionServiceClient adGroupCriterionServiceClient = await AdGroupCriterionServiceClient.CreateAsync(); // Initialize request argument(s) MutateAdGroupCriteriaRequest request = new MutateAdGroupCriteriaRequest { CustomerId = "", Operations = { new AdGroupCriterionOperation(), }, PartialFailure = false, ValidateOnly = false, ResponseContentType = ResponseContentTypeEnum.Types.ResponseContentType.Unspecified, }; // Make the request MutateAdGroupCriteriaResponse response = await adGroupCriterionServiceClient.MutateAdGroupCriteriaAsync(request); }
/// <summary>Snippet for MutateAdGroupCriteria</summary> public void MutateAdGroupCriteriaRequestObject() { // Snippet: MutateAdGroupCriteria(MutateAdGroupCriteriaRequest, CallSettings) // Create client AdGroupCriterionServiceClient adGroupCriterionServiceClient = AdGroupCriterionServiceClient.Create(); // Initialize request argument(s) MutateAdGroupCriteriaRequest request = new MutateAdGroupCriteriaRequest { CustomerId = "", Operations = { new AdGroupCriterionOperation(), }, PartialFailure = false, ValidateOnly = false, ResponseContentType = ResponseContentTypeEnum.Types.ResponseContentType.Unspecified, }; // Make the request MutateAdGroupCriteriaResponse response = adGroupCriterionServiceClient.MutateAdGroupCriteria(request); // End snippet }
/// <summary>Snippet for MutateAdGroupCriteriaAsync</summary> public async Task MutateAdGroupCriteriaRequestObjectAsync() { // Snippet: MutateAdGroupCriteriaAsync(MutateAdGroupCriteriaRequest, CallSettings) // Additional: MutateAdGroupCriteriaAsync(MutateAdGroupCriteriaRequest, CancellationToken) // Create client AdGroupCriterionServiceClient adGroupCriterionServiceClient = await AdGroupCriterionServiceClient.CreateAsync(); // Initialize request argument(s) MutateAdGroupCriteriaRequest request = new MutateAdGroupCriteriaRequest { CustomerId = "", Operations = { new AdGroupCriterionOperation(), }, PartialFailure = false, ValidateOnly = false, }; // Make the request MutateAdGroupCriteriaResponse response = await adGroupCriterionServiceClient.MutateAdGroupCriteriaAsync(request); // End snippet }
// [END add_shopping_product_ad] /// <summary> /// Creates a new default shopping listing group for the specified ad group. A listing /// group is the Google Ads API representation of a "product group" described in the /// Google Ads user interface. The listing group will be added to the ad group using an /// "ad group criterion". /// </summary> /// <param name="client">The Google Ads API client.</param> /// <param name="customerId">The client customer ID.</param> /// <param name="adGroupResourceName">The resource name of the ad group that the new /// listing group will belong to.</param> /// <returns>Resource name of the newly created ad group criterion containing the /// listing group.</returns> /// <exception cref="GoogleAdsException">Thrown if an API request failed with one or more /// service errors.</exception> private string AddDefaultShoppingListingGroup(GoogleAdsClient client, long customerId, string adGroupResourceName) { // Get the AdGroupCriterionService. AdGroupCriterionServiceClient adGroupCriterionService = client.GetService( Services.V10.AdGroupCriterionService); // Creates a new ad group criterion. This will contain the "default" listing group (All // products). AdGroupCriterion adGroupCriterion = new AdGroupCriterion() { AdGroup = adGroupResourceName, Status = AdGroupCriterionStatus.Enabled, // Creates a new listing group. This will be the top-level "root" node. // Set the type of the listing group to be a biddable unit. ListingGroup = new ListingGroupInfo() { Type = ListingGroupType.Unit }, // Set the bid for products in this listing group unit. CpcBidMicros = 500_000L }; AdGroupCriterionOperation operation = new AdGroupCriterionOperation() { Create = adGroupCriterion }; MutateAdGroupCriterionResult mutateAdGroupCriteriaResult = adGroupCriterionService.MutateAdGroupCriteria(customerId.ToString(), new AdGroupCriterionOperation[] { operation }).Results[0]; Console.WriteLine("Added an ad group criterion containing a listing group with " + "resource name: '{0}'.", mutateAdGroupCriteriaResult.ResourceName); return(mutateAdGroupCriteriaResult.ResourceName); }
// [END setup_remarketing] /// <summary> /// Creates an ad group criterion that targets a user list with an ad group. /// </summary> /// <param name="client">The Google Ads API client.</param> /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> /// <param name="adGroupId">The ad group on which the user list will be targeted.</param> /// <param name="userListResourceName">The resource name of the user list to be /// targeted.</param> /// <returns>The resource name of the newly created ad group criterion.</returns> // [START setup_remarketing_1] private string TargetAdsInAdGroupToUserList( GoogleAdsClient client, long customerId, long adGroupId, string userListResourceName) { // Get the AdGroupCriterionService client. AdGroupCriterionServiceClient adGroupCriterionServiceClient = client.GetService (Services.V10.AdGroupCriterionService); // Create the ad group criterion targeting members of the user list. AdGroupCriterion adGroupCriterion = new AdGroupCriterion { AdGroup = ResourceNames.AdGroup(customerId, adGroupId), UserList = new UserListInfo { UserList = userListResourceName } }; // Create the operation. AdGroupCriterionOperation adGroupCriterionOperation = new AdGroupCriterionOperation { Create = adGroupCriterion }; // Add the ad group criterion, then print and return the new criterion's resource name. MutateAdGroupCriteriaResponse mutateAdGroupCriteriaResponse = adGroupCriterionServiceClient.MutateAdGroupCriteria(customerId.ToString(), new[] { adGroupCriterionOperation }); string adGroupCriterionResourceName = mutateAdGroupCriteriaResponse.Results.First().ResourceName; Console.WriteLine("Successfully created ad group criterion with resource name " + $"'{adGroupCriterionResourceName}' targeting user list with resource name " + $"'{userListResourceName}' with ad group with ID {adGroupId}."); return(adGroupCriterionResourceName); }
/// <summary> /// Runs the code example. /// </summary> /// <param name="client">The Google Ads client.</param> /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> /// <param name="adGroupId">The ID of the ad group.</param> /// <param name="replaceExistingTree">The boolean to indicate whether to replace the /// existing listing group tree on the ad group, if it already exists. The example will /// throw a <code>LISTING_GROUP_ALREADY_EXISTS</code> error if listing group tree already /// exists and this option is not set to true.</param> // [START add_shopping_product_listing_group_tree] public void Run(GoogleAdsClient client, long customerId, long adGroupId, bool replaceExistingTree) { // Get the AdGroupCriterionService. AdGroupCriterionServiceClient adGroupCriterionService = client.GetService(Services.V10.AdGroupCriterionService); try { // 1) Optional: Remove the existing listing group tree, if it already exists on the // ad group. if (replaceExistingTree) { RemoveListingGroupTree(client, customerId, adGroupId); } // Create a list of ad group criterion to add List <AdGroupCriterionOperation> operations = new List <AdGroupCriterionOperation>(); // 2) Construct the listing group tree "root" node. // Subdivision node: (Root node) AdGroupCriterion adGroupCriterionRoot = CreateListingGroupSubdivisionRoot( customerId, adGroupId, -1L); // Get the resource name that will be used for the root node. // This resource has not been created yet and will include the temporary ID as // part of the criterion ID. String adGroupCriterionResourceNameRoot = adGroupCriterionRoot.ResourceName; operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionRoot }); // 3) Construct the listing group unit nodes for NEW, USED and other // Biddable Unit node: (Condition NEW node) // * Product Condition: NEW // * CPC bid: $0.20 AdGroupCriterion adGroupCriterionConditionNew = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameRoot, new ListingDimensionInfo() { ProductCondition = new ProductConditionInfo() { Condition = ProductCondition.New } }, 200_000L); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionConditionNew }); // Biddable Unit node: (Condition USED node) // * Product Condition: USED // * CPC bid: $0.10 AdGroupCriterion adGroupCriterionConditionUsed = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameRoot, new ListingDimensionInfo() { ProductCondition = new ProductConditionInfo() { Condition = ProductCondition.Used } }, 100_000L ); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionConditionUsed }); // Sub-division node: (Condition "other" node) // * Product Condition: (not specified) AdGroupCriterion adGroupCriterionConditionOther = CreateListingGroupSubdivision( customerId, adGroupId, -2L, adGroupCriterionResourceNameRoot, new ListingDimensionInfo() { // All sibling nodes must have the same dimension type, even if they // don't contain a bid. ProductCondition = new ProductConditionInfo() } ); // Get the resource name that will be used for the condition other node. // This resource has not been created yet and will include the temporary ID as // part of the criterion ID. String adGroupCriterionResourceNameConditionOther = adGroupCriterionConditionOther.ResourceName; operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionConditionOther }); // 4) Construct the listing group unit nodes for CoolBrand, CheapBrand and other // Biddable Unit node: (Brand CoolBrand node) // * Brand: CoolBrand // * CPC bid: $0.90 AdGroupCriterion adGroupCriterionBrandCoolBrand = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameConditionOther, new ListingDimensionInfo() { ProductBrand = new ProductBrandInfo() { Value = "CoolBrand" } }, 900_000L); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionBrandCoolBrand }); // Biddable Unit node: (Brand CheapBrand node) // * Brand: CheapBrand // * CPC bid: $0.01 AdGroupCriterion adGroupCriterionBrandCheapBrand = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameConditionOther, new ListingDimensionInfo() { ProductBrand = new ProductBrandInfo() { Value = "CheapBrand" } }, 10_000L); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionBrandCheapBrand }); // Biddable Unit node: (Brand other node) // * Brand: CheapBrand // * CPC bid: $0.01 AdGroupCriterion adGroupCriterionBrandOther = CreateListingGroupUnitBiddable( customerId, adGroupId, adGroupCriterionResourceNameConditionOther, new ListingDimensionInfo() { ProductBrand = new ProductBrandInfo() }, 50_000L); operations.Add(new AdGroupCriterionOperation() { Create = adGroupCriterionBrandOther }); // Issues a mutate request to add the ad group criterion to the ad group. MutateAdGroupCriteriaResponse response = adGroupCriterionService.MutateAdGroupCriteria( customerId.ToString(), operations); // Display the results. foreach (MutateAdGroupCriterionResult mutateAdGroupCriterionResult in response.Results) { Console.WriteLine("Added ad group criterion for listing group with resource " + $"name: '{mutateAdGroupCriterionResult.ResourceName}."); } } catch (GoogleAdsException e) { Console.WriteLine("Failure:"); Console.WriteLine($"Message: {e.Message}"); Console.WriteLine($"Failure: {e.Failure}"); Console.WriteLine($"Request ID: {e.RequestId}"); throw; } }
/// <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.V5.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> /// Runs the code example. /// </summary> /// <param name="client">The Google Ads client.</param> /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> /// <param name="adGroupId">ID of the ad group to which targeting criteria are added. /// </param> public void Run(GoogleAdsClient client, long customerId, long adGroupId) { // Get the AdGroupCriterionService. AdGroupCriterionServiceClient adGroupCriterionService = client.GetService(Services.V10.AdGroupCriterionService); string adGroupResourceName = ResourceNames.AdGroup(customerId, adGroupId); // Creates a positive ad group criterion for gender. AdGroupCriterion genderAdGroupCriterion = new AdGroupCriterion() { AdGroup = adGroupResourceName, // Targets male. Gender = new GenderInfo() { Type = GenderType.Male } }; // Creates a negative ad group criterion for age range. AdGroupCriterion ageRangeNegativeAdGroupCriterion = new AdGroupCriterion() { AdGroup = adGroupResourceName, // Makes this ad group criterion negative. Negative = true, // Targets the age range of 18 to 24. AgeRange = new AgeRangeInfo() { Type = AgeRangeType.AgeRange1824 } }; // Creates ad group criterion operations for both ad group criteria. AdGroupCriterionOperation[] operations = new AdGroupCriterionOperation[] { new AdGroupCriterionOperation() { Create = genderAdGroupCriterion }, new AdGroupCriterionOperation() { Create = ageRangeNegativeAdGroupCriterion } }; try { // Issues a mutate request to add the ad group criteria and print out some // information. MutateAdGroupCriteriaResponse response = adGroupCriterionService.MutateAdGroupCriteria( customerId.ToString(), operations); Console.WriteLine($"Added {response.Results.Count} demographic ad group" + $" criteria:"); foreach (MutateAdGroupCriterionResult result in response.Results) { Console.WriteLine(result.ResourceName); } } catch (GoogleAdsException e) { Console.WriteLine("Failure:"); Console.WriteLine($"Message: {e.Message}"); Console.WriteLine($"Failure: {e.Failure}"); Console.WriteLine($"Request ID: {e.RequestId}"); throw; } }
/// <summary> /// Displays the result from the mutate operation. /// </summary> /// <param name="client">The Google Ads client.</param> /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> /// <param name="adGroupId">The ad group to which keywords are added.</param> /// <param name="threadIndex">The thread ID.</param> private async Task CreateKeyword(GoogleAdsClient client, int threadIndex, long customerId, long adGroupId) { await Task.Run(() => { // Get the AdGroupCriterionServiceClient. AdGroupCriterionServiceClient adGroupCriterionService = client.GetService(Services.V3.AdGroupCriterionService); List <AdGroupCriterionOperation> operations = new List <AdGroupCriterionOperation>(); for (int i = 0; i < NUM_KEYWORDS; i++) { AdGroupCriterion criterion = new AdGroupCriterion() { Keyword = new KeywordInfo() { Text = $"mars cruise thread {threadIndex} seed {i}", MatchType = KeywordMatchType.Exact }, AdGroup = ResourceNames.AdGroup(customerId, adGroupId), Status = AdGroupCriterionStatus.Paused }; // Creates the operation. operations.Add(new AdGroupCriterionOperation() { Create = criterion }); } int retryCount = 0; int retrySeconds = 30; const int NUM_RETRIES = 3; while (retryCount < NUM_RETRIES) { try { // Makes the validateOnly mutate request. MutateAdGroupCriteriaResponse response = adGroupCriterionService.MutateAdGroupCriteria( customerId.ToString(), operations, false, true); Console.WriteLine($"[{threadIndex}] Validated {operations.Count} " + $"ad group criteria:"); break; } catch (GoogleAdsException e) { // Checks if any of the errors are QuotaError.RESOURCE_EXHAUSTED or // QuotaError.RESOURCE_TEMPORARILY_EXHAUSTED. // Note: The code assumes that the developer token is approved for // Standard Access. if (e.Failure != null) { bool isRateExceededError = false; e.Failure.Errors .Where(err => err.ErrorCode.QuotaError == QuotaError.ResourceExhausted || err.ErrorCode.QuotaError == QuotaError.ResourceTemporarilyExhausted) .ToList() .ForEach(delegate(GoogleAdsError err) { Console.Error.WriteLine($"[{threadIndex}] Received rate " + $"exceeded error. Message says, \"{err.Message}\"."); isRateExceededError = true; } ); if (isRateExceededError) { Console.Error.WriteLine( $"[{threadIndex}] Will retry after {retrySeconds} seconds."); Thread.Sleep(retrySeconds * 1000); retryCount++; // Uses an exponential backoff policy to avoid polling too // aggressively. retrySeconds *= 2; } } else { Console.WriteLine("Failure:"); Console.WriteLine($"Message: {e.Message}"); Console.WriteLine($"Failure: {e.Failure}"); Console.WriteLine($"Request ID: {e.RequestId}"); break; } } finally { if (retryCount == NUM_RETRIES) { throw new Exception($"[{ threadIndex }] Could not recover after " + $"making {retryCount} attempts."); } } } }); }