Add Complete Campaigns Using Batch Job

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.campaignmanagement 
 ; 
 import static 
  
 com.google.ads.googleads.examples.utils.CodeSampleHelper.getPrintableDateTime 
 ; 
 import static 
  
 com.google.ads.googleads.v21.enums.EuPoliticalAdvertisingStatusEnum.EuPoliticalAdvertisingStatus.CONTAINS_EU_POLITICAL_ADVERTISING 
 ; 
 import static 
  
 com.google.ads.googleads.v21.enums.EuPoliticalAdvertisingStatusEnum.EuPoliticalAdvertisingStatus.DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING 
 ; 
 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.v21.common.ExpandedTextAdInfo 
 ; 
 import 
  
 com.google.ads.googleads.v21.common.KeywordInfo 
 ; 
 import 
  
 com.google.ads.googleads.v21.common.ManualCpc 
 ; 
 import 
  
 com.google.ads.googleads.v21.enums.AdGroupAdStatusEnum.AdGroupAdStatus 
 ; 
 import 
  
 com.google.ads.googleads.v21.enums.AdGroupCriterionStatusEnum.AdGroupCriterionStatus 
 ; 
 import 
  
 com.google.ads.googleads.v21.enums.AdGroupTypeEnum.AdGroupType 
 ; 
 import 
  
 com.google.ads.googleads.v21.enums.AdvertisingChannelTypeEnum.AdvertisingChannelType 
 ; 
 import 
  
 com.google.ads.googleads.v21.enums.BudgetDeliveryMethodEnum.BudgetDeliveryMethod 
 ; 
 import 
  
 com.google.ads.googleads.v21.enums.CampaignStatusEnum.CampaignStatus 
 ; 
 import 
  
 com.google.ads.googleads.v21.enums.KeywordMatchTypeEnum.KeywordMatchType 
 ; 
 import 
  
 com.google.ads.googleads.v21.errors.GoogleAdsError 
 ; 
 import 
  
 com.google.ads.googleads.v21.errors.GoogleAdsException 
 ; 
 import 
  
 com.google.ads.googleads.v21.resources.Ad 
 ; 
 import 
  
 com.google.ads.googleads.v21.resources.AdGroup 
 ; 
 import 
  
 com.google.ads.googleads.v21.resources.AdGroupAd 
 ; 
 import 
  
 com.google.ads.googleads.v21.resources.AdGroupCriterion 
 ; 
 import 
  
 com.google.ads.googleads.v21.resources.BatchJob 
 ; 
 import 
  
 com.google.ads.googleads.v21.resources.Campaign 
 ; 
 import 
  
 com.google.ads.googleads.v21.resources.CampaignBudget 
 ; 
 import 
  
 com.google.ads.googleads.v21.resources.CampaignCriterion 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.AdGroupAdOperation 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.AdGroupCriterionOperation 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.AdGroupOperation 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.AddBatchJobOperationsRequest 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.AddBatchJobOperationsResponse 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.BatchJobOperation 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.BatchJobResult 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.BatchJobServiceClient 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.BatchJobServiceClient.ListBatchJobResultsPagedResponse 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.CampaignBudgetOperation 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.CampaignCriterionOperation 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.CampaignOperation 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.ListBatchJobResultsRequest 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.MutateOperation 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.MutateOperationResponse.ResponseCase 
 ; 
 import 
  
 com.google.ads.googleads.v21.utils.ResourceNames 
 ; 
 import 
  
 com.google.api.gax.longrunning.OperationFuture 
 ; 
 import 
  
 java.io.FileNotFoundException 
 ; 
 import 
  
 java.io.IOException 
 ; 
 import 
  
 java.util.ArrayList 
 ; 
 import 
  
 java.util.List 
 ; 
 import 
  
 java.util.concurrent.ExecutionException 
 ; 
 import 
  
 java.util.concurrent.TimeUnit 
 ; 
 import 
  
 java.util.concurrent.TimeoutException 
 ; 
 /** 
 * This example adds complete campaigns including campaign budgets, campaigns, ad groups and 
 * keywords using BatchJobService. 
 */ 
 public 
  
 class 
 AddCompleteCampaignsUsingBatchJob 
  
 { 
  
 private 
  
 static 
  
 final 
  
 int 
  
 NUMBER_OF_CAMPAIGNS_TO_ADD 
  
 = 
  
 2 
 ; 
  
 private 
  
 static 
  
 final 
  
 int 
  
 NUMBER_OF_AD_GROUPS_TO_ADD 
  
 = 
  
 2 
 ; 
  
 private 
  
 static 
  
 final 
  
 int 
  
 NUMBER_OF_KEYWORDS_TO_ADD 
  
 = 
  
 4 
 ; 
  
 private 
  
 static 
  
 final 
  
 int 
  
 MAX_TOTAL_POLL_INTERVAL_SECONDS 
  
 = 
  
 60 
 ; 
  
 private 
  
 static 
  
 final 
  
 int 
  
 PAGE_SIZE 
  
 = 
  
 1000 
 ; 
  
 /** The negative temporary ID used in mutate job operations. */ 
  
 private 
  
 static 
  
 long 
  
 temporaryId 
  
 = 
  
 - 
 1 
 ; 
  
 private 
  
 static 
  
 class 
 AddCompleteCampaignsUsingBatchJobParams 
  
 extends 
  
 CodeSampleParams 
  
 { 
  
 @Parameter 
 ( 
 names 
  
 = 
  
 ArgumentNames 
 . 
 CUSTOMER_ID 
 , 
  
 required 
  
 = 
  
 true 
 ) 
  
 private 
  
 Long 
  
 customerId 
 ; 
  
 } 
  
 public 
  
 static 
  
 void 
  
 main 
 ( 
 String 
 [] 
  
 args 
 ) 
  
 throws 
  
 IOException 
  
 { 
  
 AddCompleteCampaignsUsingBatchJobParams 
  
 params 
  
 = 
  
 new 
  
 AddCompleteCampaignsUsingBatchJobParams 
 (); 
  
 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" 
 ); 
  
 } 
  
 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 
  
 AddCompleteCampaignsUsingBatchJob 
 (). 
 runExample 
 ( 
 googleAdsClient 
 , 
  
 params 
 . 
 customerId 
 ); 
  
 } 
  
 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 
 ); 
  
 } 
  
 } 
  
 } 
  
 /** 
 * Runs the example. 
 * 
 * @param googleAdsClient the Google Ads API client. 
 * @param customerId the client customer ID. 
 * @throws GoogleAdsException if an API request failed with one or more service errors. 
 */ 
  
 private 
  
 void 
  
 runExample 
 ( 
 GoogleAdsClient 
  
 googleAdsClient 
 , 
  
 long 
  
 customerId 
 ) 
  
 { 
  
 try 
  
 ( 
 BatchJobServiceClient 
  
 batchJobServiceClient 
  
 = 
  
 googleAdsClient 
 . 
 getLatestVersion 
 (). 
 createBatchJobServiceClient 
 ()) 
  
 { 
  
 String 
  
 batchJobResourceName 
  
 = 
  
 createBatchJob 
 ( 
 batchJobServiceClient 
 , 
  
 customerId 
 ); 
  
 addAllBatchJobOperations 
 ( 
 batchJobServiceClient 
 , 
  
 customerId 
 , 
  
 batchJobResourceName 
 ); 
  
 OperationFuture 
  
 operationResponse 
  
 = 
  
 runBatchJob 
 ( 
 batchJobServiceClient 
 , 
  
 batchJobResourceName 
 ); 
  
 pollBatchJob 
 ( 
 operationResponse 
 ); 
  
 fetchAndPrintResults 
 ( 
 batchJobServiceClient 
 , 
  
 batchJobResourceName 
 ); 
  
 } 
  
 } 
  
 /** 
 * Creates a new mutate job for the specified customer ID. 
 * 
 * @param batchJobServiceClient the mutate job service client. 
 * @param customerId the client customer ID. 
 * @return the resource name of the created mutate job. 
 */ 
  
 private 
  
 String 
  
 createBatchJob 
 ( 
 BatchJobServiceClient 
  
 batchJobServiceClient 
 , 
  
 long 
  
 customerId 
 ) 
  
 { 
  
 BatchJobOperation 
  
 operation 
  
 = 
  
 BatchJobOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 BatchJob 
 . 
 newBuilder 
 (). 
 build 
 ()). 
 build 
 (); 
  
 String 
  
 batchJobResourceName 
  
 = 
  
 batchJobServiceClient 
  
 . 
 mutateBatchJob 
 ( 
 Long 
 . 
 toString 
 ( 
 customerId 
 ), 
  
 operation 
 ) 
  
 . 
 getResult 
 () 
  
 . 
 getResourceName 
 (); 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
 "Created a mutate job with resource name: '%s'.%n" 
 , 
  
 batchJobResourceName 
 ); 
  
 return 
  
 batchJobResourceName 
 ; 
  
 } 
  
 /** 
 * Adds all mutate job operations to the mutate job. As this is the first time for this mutate 
 * job, the sequence token is not set. The response will contain the next sequence token that you 
 * can use to upload more operations in the future. 
 * 
 * @param batchJobServiceClient the mutate job service client. 
 * @param customerId the client customer ID. 
 * @param batchJobResourceName the resource name of mutate job to which the mutate job operations 
 *     will be added. 
 */ 
  
 private 
  
 void 
  
 addAllBatchJobOperations 
 ( 
  
 BatchJobServiceClient 
  
 batchJobServiceClient 
 , 
  
 long 
  
 customerId 
 , 
  
 String 
  
 batchJobResourceName 
 ) 
  
 { 
  
 AddBatchJobOperationsResponse 
  
 response 
  
 = 
  
 batchJobServiceClient 
 . 
 addBatchJobOperations 
 ( 
  
 AddBatchJobOperationsRequest 
 . 
 newBuilder 
 () 
  
 . 
 setResourceName 
 ( 
 batchJobResourceName 
 ) 
  
 . 
 addAllMutateOperations 
 ( 
 buildAllOperations 
 ( 
 customerId 
 )) 
  
 . 
 build 
 ()); 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "%d mutate operations have been added so far.%n" 
 , 
  
 response 
 . 
 getTotalOperations 
 ()); 
  
 // You can use this next sequence token for calling addBatchJobOperations() next time. 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "Next sequence token for adding next operations is '%s'.%n" 
 , 
  
 response 
 . 
 getNextSequenceToken 
 ()); 
  
 } 
  
 /** 
 * Requests the API to run the mutate job for executing all uploaded mutate job operations. 
 * 
 * @param batchJobServiceClient the mutate job service client. 
 * @param batchJobResourceName the resource name of mutate job to be run. 
 * @return the operation response from running mutate job. 
 */ 
  
 private 
  
 OperationFuture 
  
 runBatchJob 
 ( 
  
 BatchJobServiceClient 
  
 batchJobServiceClient 
 , 
  
 String 
  
 batchJobResourceName 
 ) 
  
 { 
  
 OperationFuture 
  
 operationResponse 
  
 = 
  
 batchJobServiceClient 
 . 
 runBatchJobAsync 
 ( 
 batchJobResourceName 
 ); 
  
 // BEWARE! The above call returns an OperationFuture. The execution of that future depends on 
  
 // the thread pool which is owned by batchJobServiceClient. If you use this future, you *must* 
  
 // keep the service client in scope too. 
  
 // See https://developers.google.com/google-ads/api/docs/client-libs/java/lro for more detail. 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "Mutate job with resource name '%s' has been executed.%n" 
 , 
  
 batchJobResourceName 
 ); 
  
 return 
  
 operationResponse 
 ; 
  
 } 
  
 /** 
 * Polls the server until the mutate job execution finishes by setting the total time to wait 
 * before time-out. 
 * 
 * @param operationResponse the operation response used to poll the server. 
 */ 
  
 private 
  
 void 
  
 pollBatchJob 
 ( 
 OperationFuture 
  
 operationResponse 
 ) 
  
 { 
  
 try 
  
 { 
  
 operationResponse 
 . 
 get 
 ( 
 MAX_TOTAL_POLL_INTERVAL_SECONDS 
 , 
  
 TimeUnit 
 . 
 SECONDS 
 ); 
  
 } 
  
 catch 
  
 ( 
 InterruptedException 
  
 | 
  
 ExecutionException 
  
 | 
  
 TimeoutException 
  
 e 
 ) 
  
 { 
  
 System 
 . 
 err 
 . 
 printf 
 ( 
 "Failed polling the mutate job. Exception: %s%n" 
 , 
  
 e 
 ); 
  
 System 
 . 
 exit 
 ( 
 1 
 ); 
  
 } 
  
 } 
  
 /** 
 * Prints all the results from running the mutate job. 
 * 
 * @param batchJobServiceClient the mutate job service client. 
 * @param batchJobResourceName the resource name of mutate job to get its results. 
 */ 
  
 private 
  
 void 
  
 fetchAndPrintResults 
 ( 
  
 BatchJobServiceClient 
  
 batchJobServiceClient 
 , 
  
 String 
  
 batchJobResourceName 
 ) 
  
 { 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "Mutate job with resource name '%s' has finished. Now, printing its results...%n" 
 , 
  
 batchJobResourceName 
 ); 
  
 // Gets all the results from running mutate job and prints their information. 
  
 ListBatchJobResultsPagedResponse 
  
 batchJobResults 
  
 = 
  
 batchJobServiceClient 
 . 
 listBatchJobResults 
 ( 
  
 ListBatchJobResultsRequest 
 . 
 newBuilder 
 () 
  
 . 
 setResourceName 
 ( 
 batchJobResourceName 
 ) 
  
 . 
 setPageSize 
 ( 
 PAGE_SIZE 
 ) 
  
 . 
 build 
 ()); 
  
 for 
  
 ( 
 BatchJobResult 
  
 batchJobResult 
  
 : 
  
 batchJobResults 
 . 
 iterateAll 
 ()) 
  
 { 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "Mutate job #%d has a status '%s' and response of type '%s'.%n" 
 , 
  
 batchJobResult 
 . 
 getOperationIndex 
 (), 
  
 batchJobResult 
 . 
 getStatus 
 (). 
 getMessage 
 (). 
 isEmpty 
 () 
  
 ? 
  
 "N/A" 
  
 : 
  
 batchJobResult 
 . 
 getStatus 
 (). 
 getMessage 
 (), 
  
 batchJobResult 
  
 . 
 getMutateOperationResponse 
 () 
  
 . 
 getResponseCase 
 () 
  
 . 
 equals 
 ( 
 ResponseCase 
 . 
 RESPONSE_NOT_SET 
 ) 
  
 ? 
  
 "N/A" 
  
 : 
  
 batchJobResult 
 . 
 getMutateOperationResponse 
 (). 
 getResponseCase 
 ()); 
  
 } 
  
 } 
  
 /** 
 * Builds all operations for creating a complete campaign and return an array of their 
 * corresponding mutate operations. 
 * 
 * @param customerId the client customer ID. 
 * @return the mutate operations to be added to a mutate job. 
 */ 
  
 private 
  
 List<MutateOperation> 
  
 buildAllOperations 
 ( 
 long 
  
 customerId 
 ) 
  
 { 
  
 List<MutateOperation> 
  
 mutateOperations 
  
 = 
  
 new 
  
 ArrayList 
<> (); 
  
 // Creates a new campaign budget operation and adds it to the array of mutate operations. 
  
 CampaignBudgetOperation 
  
 campaignBudgetOperation 
  
 = 
  
 buildCampaignBudgetOperation 
 ( 
 customerId 
 ); 
  
 mutateOperations 
 . 
 add 
 ( 
  
 MutateOperation 
 . 
 newBuilder 
 (). 
 setCampaignBudgetOperation 
 ( 
 campaignBudgetOperation 
 ). 
 build 
 ()); 
  
 // Creates new campaign operations and adds them to the array of mutate operations. 
  
 List<CampaignOperation> 
  
 campaignOperations 
  
 = 
  
 buildCampaignOperations 
 ( 
 customerId 
 , 
  
 campaignBudgetOperation 
 . 
 getCreate 
 (). 
 getResourceName 
 ()); 
  
 for 
  
 ( 
 CampaignOperation 
  
 campaignOperation 
  
 : 
  
 campaignOperations 
 ) 
  
 { 
  
 mutateOperations 
 . 
 add 
 ( 
  
 MutateOperation 
 . 
 newBuilder 
 (). 
 setCampaignOperation 
 ( 
 campaignOperation 
 ). 
 build 
 ()); 
  
 } 
  
 // Creates new campaign criterion operations and adds them to the array of mutate operations. 
  
 List<CampaignCriterionOperation> 
  
 campaignCriterionOperations 
  
 = 
  
 buildCampaignCriterionOperations 
 ( 
 campaignOperations 
 ); 
  
 for 
  
 ( 
 CampaignCriterionOperation 
  
 campaignCriterionOperation 
  
 : 
  
 campaignCriterionOperations 
 ) 
  
 { 
  
 mutateOperations 
 . 
 add 
 ( 
  
 MutateOperation 
 . 
 newBuilder 
 () 
  
 . 
 setCampaignCriterionOperation 
 ( 
 campaignCriterionOperation 
 ) 
  
 . 
 build 
 ()); 
  
 } 
  
 // Creates new ad group operations and adds them to the array of mutate operations. 
  
 List<AdGroupOperation> 
  
 adGroupOperations 
  
 = 
  
 buildAdGroupOperations 
 ( 
 customerId 
 , 
  
 campaignOperations 
 ); 
  
 for 
  
 ( 
 AdGroupOperation 
  
 adGroupOperation 
  
 : 
  
 adGroupOperations 
 ) 
  
 { 
  
 mutateOperations 
 . 
 add 
 ( 
  
 MutateOperation 
 . 
 newBuilder 
 (). 
 setAdGroupOperation 
 ( 
 adGroupOperation 
 ). 
 build 
 ()); 
  
 } 
  
 // Creates new ad group criterion operations and adds them to the array of mutate operations. 
  
 List<AdGroupCriterionOperation> 
  
 adGroupCriterionOperations 
  
 = 
  
 buildAdGroupCriterionOperations 
 ( 
 adGroupOperations 
 ); 
  
 for 
  
 ( 
 AdGroupCriterionOperation 
  
 adGroupCriterionOperation 
  
 : 
  
 adGroupCriterionOperations 
 ) 
  
 { 
  
 mutateOperations 
 . 
 add 
 ( 
  
 MutateOperation 
 . 
 newBuilder 
 () 
  
 . 
 setAdGroupCriterionOperation 
 ( 
 adGroupCriterionOperation 
 ) 
  
 . 
 build 
 ()); 
  
 } 
  
 // Creates new ad group ad operations and adds them to the array of mutate operations. 
  
 List<AdGroupAdOperation> 
  
 adGroupAdOperations 
  
 = 
  
 buildAdGroupAdOperations 
 ( 
 adGroupOperations 
 ); 
  
 for 
  
 ( 
 AdGroupAdOperation 
  
 adGroupAdOperation 
  
 : 
  
 adGroupAdOperations 
 ) 
  
 { 
  
 mutateOperations 
 . 
 add 
 ( 
  
 MutateOperation 
 . 
 newBuilder 
 (). 
 setAdGroupAdOperation 
 ( 
 adGroupAdOperation 
 ). 
 build 
 ()); 
  
 } 
  
 return 
  
 mutateOperations 
 ; 
  
 } 
  
 /** 
 * Builds a new campaign budget operation for the specified customer ID. 
 * 
 * @param customerId the client customer ID. 
 * @return the campaign budget operation. 
 */ 
  
 private 
  
 CampaignBudgetOperation 
  
 buildCampaignBudgetOperation 
 ( 
 long 
  
 customerId 
 ) 
  
 { 
  
 // Creates a campaign budget. 
  
 CampaignBudget 
  
 budget 
  
 = 
  
 CampaignBudget 
 . 
 newBuilder 
 () 
  
 // Creates a resource name using the temporary ID. 
  
 . 
 setResourceName 
 ( 
 ResourceNames 
 . 
 campaignBudget 
 ( 
 customerId 
 , 
  
 getNextTemporaryId 
 ())) 
  
 . 
 setName 
 ( 
 "Interplanetary Cruise Budget #" 
  
 + 
  
 getPrintableDateTime 
 ()) 
  
 . 
 setDeliveryMethod 
 ( 
 BudgetDeliveryMethod 
 . 
 STANDARD 
 ) 
  
 . 
 setAmountMicros 
 ( 
 5_000_000 
 ) 
  
 . 
 build 
 (); 
  
 // Creates a campaign budget operation. 
  
 return 
  
 CampaignBudgetOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 budget 
 ). 
 build 
 (); 
  
 } 
  
 /** 
 * Builds new campaign operations for the specified customer ID. 
 * 
 * @param customerId the client customer ID. 
 * @param campaignBudgetResourceName the resource name of campaign budget to be used to create 
 *     campaigns. 
 * @return the campaign operations. 
 */ 
  
 private 
  
 List<CampaignOperation> 
  
 buildCampaignOperations 
 ( 
  
 long 
  
 customerId 
 , 
  
 String 
  
 campaignBudgetResourceName 
 ) 
  
 { 
  
 List<CampaignOperation> 
  
 operations 
  
 = 
  
 new 
  
 ArrayList 
<> (); 
  
 for 
  
 ( 
 int 
  
 i 
  
 = 
  
 0 
 ; 
  
 i 
 < 
 NUMBER_OF_CAMPAIGNS_TO_ADD 
 ; 
  
 i 
 ++ 
 ) 
  
 { 
  
 // Creates a campaign. 
  
 long 
  
 campaignId 
  
 = 
  
 getNextTemporaryId 
 (); 
  
 Campaign 
  
 campaign 
  
 = 
  
 Campaign 
 . 
 newBuilder 
 () 
  
 // Creates a resource name using the temporary ID. 
  
 . 
 setResourceName 
 ( 
 ResourceNames 
 . 
 campaign 
 ( 
 customerId 
 , 
  
 campaignId 
 )) 
  
 . 
 setName 
 ( 
 "Mutate job campaign #" 
  
 + 
  
 getPrintableDateTime 
 () 
  
 + 
  
 "." 
  
 + 
  
 campaignId 
 ) 
  
 . 
 setAdvertisingChannelType 
 ( 
 AdvertisingChannelType 
 . 
 SEARCH 
 ) 
  
 // Recommendation: Set the campaign to PAUSED when creating it to prevent 
  
 // the ads from immediately serving. Set to ENABLED once you've added 
  
 // targeting and the ads are ready to serve. 
  
 . 
 setStatus 
 ( 
 CampaignStatus 
 . 
 PAUSED 
 ) 
  
 // Sets the bidding strategy and budget. 
  
 . 
 setManualCpc 
 ( 
 ManualCpc 
 . 
 newBuilder 
 (). 
 build 
 ()) 
  
 . 
 setCampaignBudget 
 ( 
 campaignBudgetResourceName 
 ) 
  
 // Declares whether this campaign serves political ads targeting the EU. 
  
 . 
 setContainsEuPoliticalAdvertising 
 ( 
 DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING 
 ) 
  
 . 
 build 
 (); 
  
 // Creates a campaign operation and adds it to the operations list. 
  
 CampaignOperation 
  
 op 
  
 = 
  
 CampaignOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 campaign 
 ). 
 build 
 (); 
  
 operations 
 . 
 add 
 ( 
 op 
 ); 
  
 } 
  
 return 
  
 operations 
 ; 
  
 } 
  
 /** 
 * Builds new campaign criterion operations for creating negative campaign criteria (as keywords). 
 * 
 * @param campaignOperations the campaign operations to be used to create campaign criteria. 
 * @return the campaign criterion operations. 
 */ 
  
 private 
  
 List<CampaignCriterionOperation> 
  
 buildCampaignCriterionOperations 
 ( 
  
 List<CampaignOperation> 
  
 campaignOperations 
 ) 
  
 { 
  
 List<CampaignCriterionOperation> 
  
 operations 
  
 = 
  
 new 
  
 ArrayList 
<> (); 
  
 for 
  
 ( 
 CampaignOperation 
  
 campaignOperation 
  
 : 
  
 campaignOperations 
 ) 
  
 { 
  
 // Creates a campaign criterion. 
  
 CampaignCriterion 
  
 campaignCriterion 
  
 = 
  
 CampaignCriterion 
 . 
 newBuilder 
 () 
  
 . 
 setKeyword 
 ( 
  
 KeywordInfo 
 . 
 newBuilder 
 () 
  
 . 
 setText 
 ( 
 "venus" 
 ) 
  
 . 
 setMatchType 
 ( 
 KeywordMatchType 
 . 
 BROAD 
 ) 
  
 . 
 build 
 ()) 
  
 // Sets the campaign criterion as a negative criterion. 
  
 . 
 setNegative 
 ( 
 Boolean 
 . 
 TRUE 
 ) 
  
 . 
 setCampaign 
 ( 
 campaignOperation 
 . 
 getCreate 
 (). 
 getResourceName 
 ()) 
  
 . 
 build 
 (); 
  
 // Creates a campaign criterion operation and adds it to the operations list. 
  
 CampaignCriterionOperation 
  
 op 
  
 = 
  
 CampaignCriterionOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 campaignCriterion 
 ). 
 build 
 (); 
  
 operations 
 . 
 add 
 ( 
 op 
 ); 
  
 } 
  
 return 
  
 operations 
 ; 
  
 } 
  
 /** 
 * Builds new ad group operations for the specified customer ID. 
 * 
 * @param customerId the client customer ID. 
 * @param campaignOperations the campaign operations to be used to create ad groups. 
 * @return the ad group operations. 
 */ 
  
 private 
  
 List<AdGroupOperation> 
  
 buildAdGroupOperations 
 ( 
  
 long 
  
 customerId 
 , 
  
 List<CampaignOperation> 
  
 campaignOperations 
 ) 
  
 { 
  
 List<AdGroupOperation> 
  
 operations 
  
 = 
  
 new 
  
 ArrayList 
<> (); 
  
 for 
  
 ( 
 CampaignOperation 
  
 campaignOperation 
  
 : 
  
 campaignOperations 
 ) 
  
 { 
  
 for 
  
 ( 
 int 
  
 i 
  
 = 
  
 0 
 ; 
  
 i 
 < 
 NUMBER_OF_AD_GROUPS_TO_ADD 
 ; 
  
 i 
 ++ 
 ) 
  
 { 
  
 // Creates an ad group. 
  
 long 
  
 adGroupId 
  
 = 
  
 getNextTemporaryId 
 (); 
  
 AdGroup 
  
 adGroup 
  
 = 
  
 AdGroup 
 . 
 newBuilder 
 () 
  
 // Creates a resource name using the temporary ID. 
  
 . 
 setResourceName 
 ( 
 ResourceNames 
 . 
 adGroup 
 ( 
 customerId 
 , 
  
 adGroupId 
 )) 
  
 . 
 setName 
 ( 
 "Mutate job ad group #" 
  
 + 
  
 getPrintableDateTime 
 () 
  
 + 
  
 "." 
  
 + 
  
 adGroupId 
 ) 
  
 . 
 setCampaign 
 ( 
 campaignOperation 
 . 
 getCreate 
 (). 
 getResourceName 
 ()) 
  
 . 
 setType 
 ( 
 AdGroupType 
 . 
 SEARCH_STANDARD 
 ) 
  
 . 
 setCpcBidMicros 
 ( 
 10_000_000 
 ) 
  
 . 
 build 
 (); 
  
 // Creates an ad group operation and adds it to the operations list. 
  
 AdGroupOperation 
  
 op 
  
 = 
  
 AdGroupOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 adGroup 
 ). 
 build 
 (); 
  
 operations 
 . 
 add 
 ( 
 op 
 ); 
  
 } 
  
 } 
  
 return 
  
 operations 
 ; 
  
 } 
  
 /** 
 * Builds new ad group criterion operations for creating keywords. 50% of keywords are created 
 * with some invalid characters to demonstrate how BatchJobService returns information about such 
 * errors. 
 * 
 * @param adGroupOperations the ad group operations to be used to create ad group criteria. 
 * @return the ad group criterion operations. 
 */ 
  
 private 
  
 List<AdGroupCriterionOperation> 
  
 buildAdGroupCriterionOperations 
 ( 
  
 List<AdGroupOperation> 
  
 adGroupOperations 
 ) 
  
 { 
  
 List<AdGroupCriterionOperation> 
  
 operations 
  
 = 
  
 new 
  
 ArrayList 
<> (); 
  
 for 
  
 ( 
 AdGroupOperation 
  
 adGroupOperation 
  
 : 
  
 adGroupOperations 
 ) 
  
 { 
  
 for 
  
 ( 
 int 
  
 i 
  
 = 
  
 0 
 ; 
  
 i 
 < 
 NUMBER_OF_KEYWORDS_TO_ADD 
 ; 
  
 i 
 ++ 
 ) 
  
 { 
  
 // Creates a keyword text by making 50% of keywords invalid to demonstrate error handling. 
  
 String 
  
 keywordText 
  
 = 
  
 "mars" 
  
 + 
  
 i 
 ; 
  
 if 
  
 ( 
 i 
  
 % 
  
 2 
  
 == 
  
 0 
 ) 
  
 { 
  
 keywordText 
  
 += 
  
 "!!!" 
 ; 
  
 } 
  
 // Creates an ad group criterion using the created keyword text. 
  
 AdGroupCriterion 
  
 adGroupCriterion 
  
 = 
  
 AdGroupCriterion 
 . 
 newBuilder 
 () 
  
 . 
 setKeyword 
 ( 
  
 KeywordInfo 
 . 
 newBuilder 
 () 
  
 . 
 setText 
 ( 
 keywordText 
 ) 
  
 . 
 setMatchType 
 ( 
 KeywordMatchType 
 . 
 BROAD 
 ) 
  
 . 
 build 
 ()) 
  
 . 
 setAdGroup 
 ( 
 adGroupOperation 
 . 
 getCreate 
 (). 
 getResourceName 
 ()) 
  
 . 
 setStatus 
 ( 
 AdGroupCriterionStatus 
 . 
 ENABLED 
 ) 
  
 . 
 build 
 (); 
  
 // Creates an ad group criterion operation and adds it to the operations list. 
  
 AdGroupCriterionOperation 
  
 op 
  
 = 
  
 AdGroupCriterionOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 adGroupCriterion 
 ). 
 build 
 (); 
  
 operations 
 . 
 add 
 ( 
 op 
 ); 
  
 } 
  
 } 
  
 return 
  
 operations 
 ; 
  
 } 
  
 /** 
 * Builds new ad group ad operations. 
 * 
 * @param adGroupOperations the ad group operations to be used to create ad group ads. 
 * @return the ad group ad operations. 
 */ 
  
 private 
  
 List<AdGroupAdOperation> 
  
 buildAdGroupAdOperations 
 ( 
  
 List<AdGroupOperation> 
  
 adGroupOperations 
 ) 
  
 { 
  
 List<AdGroupAdOperation> 
  
 operations 
  
 = 
  
 new 
  
 ArrayList 
<> (); 
  
 for 
  
 ( 
 AdGroupOperation 
  
 adGroupOperation 
  
 : 
  
 adGroupOperations 
 ) 
  
 { 
  
 // Creates an ad group ad. 
  
 AdGroupAd 
  
 adGroupAd 
  
 = 
  
 AdGroupAd 
 . 
 newBuilder 
 () 
  
 // Creates the expanded text ad info. 
  
 . 
 setAd 
 ( 
  
 Ad 
 . 
 newBuilder 
 () 
  
 // Sets the expanded text ad info on an ad. 
  
 . 
 setExpandedTextAd 
 ( 
  
 ExpandedTextAdInfo 
 . 
 newBuilder 
 () 
  
 . 
 setHeadlinePart1 
 ( 
 "Cruise to Mars #" 
  
 + 
  
 getPrintableDateTime 
 ()) 
  
 . 
 setHeadlinePart2 
 ( 
 "Best Space Cruise Line" 
 ) 
  
 . 
 setDescription 
 ( 
 "Buy your tickets now!" 
 ) 
  
 . 
 build 
 ()) 
  
 . 
 addFinalUrls 
 ( 
 "http://www.example.com" 
 ) 
  
 . 
 build 
 ()) 
  
 . 
 setAdGroup 
 ( 
 adGroupOperation 
 . 
 getCreate 
 (). 
 getResourceName 
 ()) 
  
 . 
 setStatus 
 ( 
 AdGroupAdStatus 
 . 
 PAUSED 
 ) 
  
 . 
 build 
 (); 
  
 // Creates an ad group ad operation and adds it to the operations list. 
  
 AdGroupAdOperation 
  
 op 
  
 = 
  
 AdGroupAdOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 adGroupAd 
 ). 
 build 
 (); 
  
 operations 
 . 
 add 
 ( 
 op 
 ); 
  
 } 
  
 return 
  
 operations 
 ; 
  
 } 
  
 /** 
 * Returns the next temporary ID and decreases it by one. 
 * 
 * @return the next temporary ID. 
 */ 
  
 private 
  
 long 
  
 getNextTemporaryId 
 () 
  
 { 
  
 return 
  
 temporaryId 
 -- 
 ; 
  
 } 
 } 
  
  

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.V21.Common 
 ; 
 using 
  
 Google.Ads.GoogleAds.V21.Errors 
 ; 
 using 
  
 Google.Ads.GoogleAds.V21.Resources 
 ; 
 using 
  
 Google.Ads.GoogleAds.V21.Services 
 ; 
 using 
  
 Google.Api.Gax 
 ; 
 using 
  
 Google.LongRunning 
 ; 
 using 
  
 Google.Protobuf.WellKnownTypes 
 ; 
 using 
  
 System 
 ; 
 using 
  
 System.Collections.Generic 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Enums 
 . 
 AdGroupAdStatusEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Enums 
 . 
 AdGroupCriterionStatusEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Enums 
 . 
 AdGroupTypeEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Enums 
 . 
 AdvertisingChannelTypeEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Enums 
 . 
 BudgetDeliveryMethodEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Enums 
 . 
 CampaignStatusEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Enums 
 . 
 EuPoliticalAdvertisingStatusEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Enums 
 . 
 KeywordMatchTypeEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Resources 
 . 
 BatchJob 
 . 
 Types 
 ; 
 namespace 
  
 Google.Ads.GoogleAds.Examples.V21 
 { 
  
 /// <summary> 
  
 /// This code example adds complete campaigns including campaign budgets, campaigns, ad groups 
  
 /// and keywords using BatchJobService. 
  
 /// </summary> 
  
 public 
  
 class 
  
 AddCompleteCampaignsUsingBatchJob 
  
 : 
  
 ExampleBase 
  
 { 
  
 /// <summary> 
  
 /// Command line options for running the <see cref="AddCompleteCampaignsUsingBatchJob"/> 
  
 /// example. 
  
 /// </summary> 
  
 public 
  
 class 
  
 Options 
  
 : 
  
 OptionsBase 
  
 { 
  
 /// <summary> 
  
 /// The Google Ads customer ID for which the call is made. 
  
 /// </summary> 
  
 [Option("customerId", Required = true, HelpText = 
 "The Google Ads customer ID for which the call is made.")] 
  
 public 
  
 long 
  
 CustomerId 
  
 { 
  
 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 
 ); 
  
 AddCompleteCampaignsUsingBatchJob 
  
 codeExample 
  
 = 
  
 new 
  
 AddCompleteCampaignsUsingBatchJob 
 (); 
  
 Console 
 . 
 WriteLine 
 ( 
 codeExample 
 . 
 Description 
 ); 
  
 codeExample 
 . 
 Run 
 ( 
 new 
  
 GoogleAdsClient 
 (), 
  
 options 
 . 
 CustomerId 
 ); 
  
 } 
  
 /// <summary> 
  
 /// The number of campaigns to add. 
  
 /// </summary> 
  
 private 
  
 const 
  
 int 
  
 NUMBER_OF_CAMPAIGNS_TO_ADD 
  
 = 
  
 2 
 ; 
  
 /// <summary> 
  
 /// The number of ad groups per campaign to add. 
  
 /// </summary> 
  
 private 
  
 const 
  
 int 
  
 NUMBER_OF_AD_GROUPS_TO_ADD 
  
 = 
  
 2 
 ; 
  
 /// <summary> 
  
 /// The number of keywords per ad group to add. 
  
 /// </summary> 
  
 private 
  
 const 
  
 int 
  
 NUMBER_OF_KEYWORDS_TO_ADD 
  
 = 
  
 4 
 ; 
  
 /// <summary> 
  
 /// The maximum total poll interval in seconds. 
  
 /// </summary> 
  
 private 
  
 const 
  
 int 
  
 MAX_TOTAL_POLL_INTERVAL_SECONDS 
  
 = 
  
 60 
 ; 
  
 /// <summary> 
  
 /// The page size for retrieving results. 
  
 /// </summary> 
  
 private 
  
 const 
  
 int 
  
 PAGE_SIZE 
  
 = 
  
 1000 
 ; 
  
 /// <summary> 
  
 /// The negative temporary ID used in batch job operations. 
  
 /// </summary> 
  
 private 
  
 static 
  
 long 
  
 temporaryId 
  
 = 
  
 - 
 1 
 ; 
  
 /// <summary> 
  
 /// Returns a description about the code example. 
  
 /// </summary> 
  
 public 
  
 override 
  
 string 
  
 Description 
  
 = 
>  
 "This code example adds complete campaigns including campaign budgets, campaigns, " 
  
 + 
  
 "ad groups and keywords using BatchJobService." 
 ; 
  
 /// <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> 
  
 public 
  
 void 
  
 Run 
 ( 
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 ) 
  
 { 
  
 // Gets the BatchJobService. 
  
 BatchJobServiceClient 
  
 batchJobService 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V21 
 . 
 BatchJobService 
 ); 
  
 try 
  
 { 
  
 string 
  
 batchJobResourceName 
  
 = 
  
 CreateBatchJob 
 ( 
 batchJobService 
 , 
  
 customerId 
 ); 
  
 AddAllBatchJobOperations 
 ( 
 batchJobService 
 , 
  
 customerId 
 , 
  
 batchJobResourceName 
 ); 
  
 Operation<Empty 
 , 
  
 BatchJobMetadata 
>  
 operationResponse 
  
 = 
  
 RunBatchJob 
 ( 
 batchJobService 
 , 
  
 batchJobResourceName 
 ); 
  
 PollBatchJob 
 ( 
 operationResponse 
 ); 
  
 FetchAndPrintResults 
 ( 
 batchJobService 
 , 
  
 batchJobResourceName 
 ); 
  
 } 
  
 catch 
  
 ( 
 GoogleAdsException 
  
 e 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 "Failure:" 
 ); 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Message: {e.Message}" 
 ); 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Failure: {e.Failure}" 
 ); 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Request ID: {e.RequestId}" 
 ); 
  
 throw 
 ; 
  
 } 
  
 } 
  
 /// <summary> 
  
 /// Creates the batch job. 
  
 /// </summary> 
  
 /// <param name="batchJobService">The batch job service.</param> 
  
 /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> 
  
 /// <returns>The resource name of the created batch job.</returns> 
  
 private 
  
 static 
  
 string 
  
 CreateBatchJob 
 ( 
 BatchJobServiceClient 
  
 batchJobService 
 , 
  
 long 
  
 customerId 
 ) 
  
 { 
  
 BatchJobOperation 
  
 operation 
  
 = 
  
 new 
  
 BatchJobOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 new 
  
 BatchJob 
 () 
  
 { 
  
 } 
  
 }; 
  
 string 
  
 batchJobResourceName 
  
 = 
  
 batchJobService 
 . 
 MutateBatchJob 
 ( 
 customerId 
 . 
 ToString 
 (), 
  
 operation 
 ) 
  
 . 
 Result 
 . 
 ResourceName 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Created a batch job with resource name: " 
  
 + 
  
 $"'{batchJobResourceName}'." 
 ); 
  
 return 
  
 batchJobResourceName 
 ; 
  
 } 
  
 /// <summary> 
  
 /// Adds all batch job operations to the batch job. As this is the first time for this 
  
 /// batch job, the sequence token is not set. The response will contain the next sequence 
  
 /// token that you can use to upload more operations in the future. 
  
 /// </summary> 
  
 /// <param name="batchJobService">The batch job service.</param> 
  
 /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> 
  
 /// <param name="batchJobResourceName">The resource name of batch job to which the batch 
  
 /// job operations will be added. 
  
 /// </param> 
  
 private 
  
 static 
  
 void 
  
 AddAllBatchJobOperations 
 ( 
 BatchJobServiceClient 
  
 batchJobService 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 batchJobResourceName 
 ) 
  
 { 
  
 AddBatchJobOperationsResponse 
  
 response 
  
 = 
  
 batchJobService 
 . 
 AddBatchJobOperations 
 ( 
  
 new 
  
 AddBatchJobOperationsRequest 
 () 
  
 { 
  
 ResourceName 
  
 = 
  
 batchJobResourceName 
 , 
  
 MutateOperations 
  
 = 
  
 { 
  
 BuildAllOperations 
 ( 
 customerId 
 ) 
  
 } 
  
 }); 
  
 Console 
 . 
 WriteLine 
 ( 
 $"{response.TotalOperations} mutate operations have been added" 
  
 + 
  
 $" so far." 
 ); 
  
 // You can use this next sequence token for calling AddBatchJobOperations() next time. 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Next sequence token for adding next operations is " 
  
 + 
  
 $"'{response.NextSequenceToken}'." 
 ); 
  
 } 
  
 /// <summary> 
  
 /// Requests the API to run the batch job for executing all uploaded batch job 
  
 /// operations. 
  
 /// </summary> 
  
 /// <param name="batchJobService">The batch job service client.</param> 
  
 /// <param name="batchJobResourceName">The resource name of batch job to be run.</param> 
  
 /// <returns>The operation response from running batch job.</returns> 
  
 private 
  
 Operation<Empty 
 , 
  
 BatchJobMetadata 
>  
 RunBatchJob 
 ( 
  
 BatchJobServiceClient 
  
 batchJobService 
 , 
  
 string 
  
 batchJobResourceName 
 ) 
  
 { 
  
 Operation<Empty 
 , 
  
 BatchJobMetadata 
>  
 operationResponse 
  
 = 
  
 batchJobService 
 . 
 RunBatchJob 
 ( 
 batchJobResourceName 
 ); 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Batch job with resource name '{batchJobResourceName}' has been " 
  
 + 
  
 $"executed." 
 ); 
  
 return 
  
 operationResponse 
 ; 
  
 } 
  
 /// <summary> 
  
 /// Polls the server until the batch job execution finishes by setting the total 
  
 /// time to wait before time-out. 
  
 /// </summary> 
  
 /// <param name="operationResponse">The operation response used to poll the server.</param> 
  
 private 
  
 static 
  
 void 
  
 PollBatchJob 
 ( 
 Operation<Empty 
 , 
  
 BatchJobMetadata 
>  
 operationResponse 
 ) 
  
 { 
  
 PollSettings 
  
 pollSettings 
  
 = 
  
 new 
  
 PollSettings 
 ( 
  
 Expiration 
 . 
 FromTimeout 
 ( 
 TimeSpan 
 . 
 FromSeconds 
 ( 
 MAX_TOTAL_POLL_INTERVAL_SECONDS 
 )), 
  
 TimeSpan 
 . 
 FromSeconds 
 ( 
 1 
 )); 
  
 operationResponse 
 . 
 PollUntilCompleted 
 ( 
 pollSettings 
 ); 
  
 } 
  
 /// <summary> 
  
 /// Fetches and prints all the results from running the batch job. 
  
 /// </summary> 
  
 /// <param name="batchJobService">The batch job service.</param> 
  
 /// <param name="batchJobResourceName">The resource name of batch job to get its results. 
  
 /// </param> 
  
 private 
  
 static 
  
 void 
  
 FetchAndPrintResults 
 ( 
 BatchJobServiceClient 
  
 batchJobService 
 , 
  
 string 
  
 batchJobResourceName 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 $"batch job with resource name '{batchJobResourceName}' has " 
  
 + 
  
 $"finished. Now, printing its results..." 
 ); 
  
 ListBatchJobResultsRequest 
  
 request 
  
 = 
  
 new 
  
 ListBatchJobResultsRequest 
 () 
  
 { 
  
 ResourceName 
  
 = 
  
 batchJobResourceName 
 , 
  
 PageSize 
  
 = 
  
 PAGE_SIZE 
 , 
  
 }; 
  
 ListBatchJobResultsResponse 
  
 resp 
  
 = 
  
 new 
  
 ListBatchJobResultsResponse 
 (); 
  
 // Gets all the results from running batch job and prints their information. 
  
 foreach 
  
 ( 
 BatchJobResult 
  
 batchJobResult 
  
 in 
  
 batchJobService 
 . 
 ListBatchJobResults 
 ( 
 request 
 )) 
  
 { 
  
 if 
  
 ( 
 ! 
 batchJobResult 
 . 
 IsFailed 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 $"batch job result #{batchJobResult.OperationIndex} is " 
  
 + 
  
 $"successful and response is of type " 
  
 + 
  
 $"'{batchJobResult.MutateOperationResponse.ResponseCase}'." 
 ); 
  
 } 
  
 else 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 $"batch job result #{batchJobResult.OperationIndex} " 
  
 + 
  
 $"failed with error message {batchJobResult.Status.Message}." 
 ); 
  
 foreach 
  
 ( 
 GoogleAdsError 
  
 error 
  
 in 
  
 batchJobResult 
 . 
 Failure 
 . 
 Errors 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Error found: {error}." 
 ); 
  
 } 
  
 } 
  
 } 
  
 } 
  
 /// <summary> 
  
 /// Builds all operations for creating a complete campaign and return an array of 
  
 /// their corresponding mutate operations. 
  
 /// </summary> 
  
 /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> 
  
 /// <returns>The mutate operations to be added to a batch job.</returns> 
  
 private 
  
 static 
  
 List<MutateOperation> 
  
 BuildAllOperations 
 ( 
 long 
  
 customerId 
 ) 
  
 { 
  
 List<MutateOperation> 
  
 mutateOperations 
  
 = 
  
 new 
  
 List<MutateOperation> 
 (); 
  
 // Creates a new campaign budget operation and adds it to the array of mutate operations. 
  
 CampaignBudgetOperation 
  
 campaignBudgetOperation 
  
 = 
  
 BuildCampaignBudgetOperation 
 ( 
 customerId 
 ); 
  
 mutateOperations 
 . 
 Add 
 ( 
  
 new 
  
 MutateOperation 
 () 
  
 { 
  
 CampaignBudgetOperation 
  
 = 
  
 campaignBudgetOperation 
  
 } 
  
 ); 
  
 // Creates new campaign operations and adds them to the array of mutate operations. 
  
 List<CampaignOperation> 
  
 campaignOperations 
  
 = 
  
 BuildCampaignOperations 
 ( 
 customerId 
 , 
  
 campaignBudgetOperation 
 . 
 Create 
 . 
 ResourceName 
 ); 
  
 foreach 
  
 ( 
 CampaignOperation 
  
 campaignOperation 
  
 in 
  
 campaignOperations 
 ) 
  
 { 
  
 mutateOperations 
 . 
 Add 
 ( 
  
 new 
  
 MutateOperation 
 () 
  
 { 
  
 CampaignOperation 
  
 = 
  
 campaignOperation 
  
 } 
  
 ); 
  
 } 
  
 // Creates new campaign criterion operations and adds them to the array of mutate 
  
 // operations. 
  
 List<CampaignCriterionOperation> 
  
 campaignCriterionOperations 
  
 = 
  
 BuildCampaignCriterionOperations 
 ( 
 campaignOperations 
 ); 
  
 foreach 
  
 ( 
 CampaignCriterionOperation 
  
 campaignCriterionOperation 
  
 in 
  
 campaignCriterionOperations 
 ) 
  
 { 
  
 mutateOperations 
 . 
 Add 
 ( 
  
 new 
  
 MutateOperation 
 () 
  
 { 
  
 CampaignCriterionOperation 
  
 = 
  
 campaignCriterionOperation 
  
 } 
  
 ); 
  
 } 
  
 // Creates new ad group operations and adds them to the array of mutate operations. 
  
 List<AdGroupOperation> 
  
 adGroupOperations 
  
 = 
  
 BuildAdGroupOperations 
 ( 
 customerId 
 , 
  
 campaignOperations 
 ); 
  
 foreach 
  
 ( 
 AdGroupOperation 
  
 adGroupOperation 
  
 in 
  
 adGroupOperations 
 ) 
  
 { 
  
 mutateOperations 
 . 
 Add 
 ( 
  
 new 
  
 MutateOperation 
 () 
  
 { 
  
 AdGroupOperation 
  
 = 
  
 adGroupOperation 
  
 } 
  
 ); 
  
 } 
  
 // Creates new ad group criterion operations and adds them to the array of mutate 
  
 // operations. 
  
 List<AdGroupCriterionOperation> 
  
 adGroupCriterionOperations 
  
 = 
  
 BuildAdGroupCriterionOperations 
 ( 
 adGroupOperations 
 ); 
  
 foreach 
  
 ( 
 AdGroupCriterionOperation 
  
 adGroupCriterionOperation 
  
 in 
  
 adGroupCriterionOperations 
 ) 
  
 { 
  
 mutateOperations 
 . 
 Add 
 ( 
  
 new 
  
 MutateOperation 
 () 
  
 { 
  
 AdGroupCriterionOperation 
  
 = 
  
 adGroupCriterionOperation 
  
 } 
  
 ); 
  
 } 
  
 // Creates new ad group ad operations and adds them to the array of mutate operations. 
  
 List<AdGroupAdOperation> 
  
 adGroupAdOperations 
  
 = 
  
 BuildAdGroupAdOperations 
 ( 
 adGroupOperations 
 ); 
  
 foreach 
  
 ( 
 AdGroupAdOperation 
  
 adGroupAdOperation 
  
 in 
  
 adGroupAdOperations 
 ) 
  
 { 
  
 mutateOperations 
 . 
 Add 
 ( 
  
 new 
  
 MutateOperation 
 () 
  
 { 
  
 AdGroupAdOperation 
  
 = 
  
 adGroupAdOperation 
  
 } 
  
 ); 
  
 } 
  
 return 
  
 mutateOperations 
 ; 
  
 } 
  
 /// <summary> 
  
 /// Builds a new campaign budget operation for the specified customer ID. 
  
 /// </summary> 
  
 /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> 
  
 /// <returns>The campaign budget operation.</returns> 
  
 private 
  
 static 
  
 CampaignBudgetOperation 
  
 BuildCampaignBudgetOperation 
 ( 
 long 
  
 customerId 
 ) 
  
 { 
  
 // Creates a campaign budget. 
  
 CampaignBudget 
  
 budget 
  
 = 
  
 new 
  
 CampaignBudget 
 () 
  
 { 
  
 ResourceName 
  
 = 
  
 ResourceNames 
 . 
 CampaignBudget 
 ( 
 customerId 
 , 
  
 GetNextTemporaryId 
 ()), 
  
 Name 
  
 = 
  
 "batch job Budget #" 
  
 + 
  
 ExampleUtilities 
 . 
 GetRandomString 
 (), 
  
 DeliveryMethod 
  
 = 
  
 BudgetDeliveryMethod 
 . 
 Standard 
 , 
  
 AmountMicros 
  
 = 
  
 5 
 _000_000 
  
 }; 
  
 // Creates a campaign budget operation. 
  
 return 
  
 new 
  
 CampaignBudgetOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 budget 
  
 }; 
  
 } 
  
 /// <summary> 
  
 /// Builds new campaign operations for the specified customer ID. 
  
 /// </summary> 
  
 /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> 
  
 /// <param name="campaignBudgetResourceName">The resource name of campaign budget to be 
  
 /// used to create campaigns.</param> 
  
 /// <returns>The campaign operations.</returns> 
  
 private 
  
 static 
  
 List<CampaignOperation> 
  
 BuildCampaignOperations 
 ( 
 long 
  
 customerId 
 , 
  
 string 
  
 campaignBudgetResourceName 
 ) 
  
 { 
  
 List<CampaignOperation> 
  
 operations 
  
 = 
  
 new 
  
 List<CampaignOperation> 
 (); 
  
 for 
  
 ( 
 int 
  
 i 
  
 = 
  
 0 
 ; 
  
 i 
 < 
 NUMBER_OF_CAMPAIGNS_TO_ADD 
 ; 
  
 i 
 ++ 
 ) 
  
 { 
  
 // Creates a campaign. 
  
 long 
  
 campaignId 
  
 = 
  
 GetNextTemporaryId 
 (); 
  
 Campaign 
  
 campaign 
  
 = 
  
 new 
  
 Campaign 
 () 
  
 { 
  
 ResourceName 
  
 = 
  
 ResourceNames 
 . 
 Campaign 
 ( 
 customerId 
 , 
  
 campaignId 
 ), 
  
 Name 
  
 = 
  
 "batch job campaign #" 
  
 + 
  
 ExampleUtilities 
 . 
 GetRandomString 
 (), 
  
 AdvertisingChannelType 
  
 = 
  
 AdvertisingChannelType 
 . 
 Search 
 , 
  
 // Recommendation: Set the campaign to PAUSED when creating it to prevent 
  
 // the ads from immediately serving. Set to ENABLED once you've added 
  
 // targeting and the ads are ready to serve. 
  
 Status 
  
 = 
  
 CampaignStatus 
 . 
 Paused 
 , 
  
 // Sets the bidding strategy and budget. 
  
 ManualCpc 
  
 = 
  
 new 
  
 ManualCpc 
 (), 
  
 CampaignBudget 
  
 = 
  
 campaignBudgetResourceName 
 , 
  
 // Declare whether or not this campaign contains political ads targeting the EU. 
  
 ContainsEuPoliticalAdvertising 
  
 = 
  
 EuPoliticalAdvertisingStatus 
 . 
 DoesNotContainEuPoliticalAdvertising 
 , 
  
 }; 
  
 // Creates a campaign operation and adds it to the operations list. 
  
 CampaignOperation 
  
 op 
  
 = 
  
 new 
  
 CampaignOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 campaign 
  
 }; 
  
 operations 
 . 
 Add 
 ( 
 op 
 ); 
  
 } 
  
 return 
  
 operations 
 ; 
  
 } 
  
 /// <summary> 
  
 /// Builds new campaign criterion operations for creating negative campaign criteria 
  
 /// (as keywords). 
  
 /// </summary> 
  
 /// <param name="campaignOperations">The campaign operations to be used to create 
  
 /// campaign criteria.</param> 
  
 /// <returns>The campaign criterion operations.</returns> 
  
 private 
  
 static 
  
 List<CampaignCriterionOperation> 
  
 BuildCampaignCriterionOperations 
 ( 
  
 List<CampaignOperation> 
  
 campaignOperations 
 ) 
  
 { 
  
 List<CampaignCriterionOperation> 
  
 operations 
  
 = 
  
 new 
  
 List<CampaignCriterionOperation> 
 (); 
  
 foreach 
  
 ( 
 CampaignOperation 
  
 campaignOperation 
  
 in 
  
 campaignOperations 
 ) 
  
 { 
  
 // Creates a campaign criterion. 
  
 CampaignCriterion 
  
 campaignCriterion 
  
 = 
  
 new 
  
 CampaignCriterion 
 () 
  
 { 
  
 Keyword 
  
 = 
  
 new 
  
 KeywordInfo 
 () 
  
 { 
  
 Text 
  
 = 
  
 "venus" 
 , 
  
 MatchType 
  
 = 
  
 KeywordMatchType 
 . 
 Broad 
  
 }, 
  
 // Sets the campaign criterion as a negative criterion. 
  
 Negative 
  
 = 
  
 true 
 , 
  
 Campaign 
  
 = 
  
 campaignOperation 
 . 
 Create 
 . 
 ResourceName 
  
 }; 
  
 // Creates a campaign criterion operation and adds it to the operations list. 
  
 CampaignCriterionOperation 
  
 op 
  
 = 
  
 new 
  
 CampaignCriterionOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 campaignCriterion 
  
 }; 
  
 operations 
 . 
 Add 
 ( 
 op 
 ); 
  
 } 
  
 return 
  
 operations 
 ; 
  
 } 
  
 /// <summary> 
  
 /// Builds new ad group operations for the specified customer ID. 
  
 /// </summary> 
  
 /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> 
  
 /// <param name="campaignOperations">The campaign operations to be used to create ad 
  
 /// groups.</param> 
  
 /// <returns>The ad group operations.</returns> 
  
 private 
  
 static 
  
 List<AdGroupOperation> 
  
 BuildAdGroupOperations 
 ( 
  
 long 
  
 customerId 
 , 
  
 List<CampaignOperation> 
  
 campaignOperations 
 ) 
  
 { 
  
 List<AdGroupOperation> 
  
 operations 
  
 = 
  
 new 
  
 List<AdGroupOperation> 
 (); 
  
 foreach 
  
 ( 
 CampaignOperation 
  
 campaignOperation 
  
 in 
  
 campaignOperations 
 ) 
  
 { 
  
 for 
  
 ( 
 int 
  
 i 
  
 = 
  
 0 
 ; 
  
 i 
 < 
 NUMBER_OF_AD_GROUPS_TO_ADD 
 ; 
  
 i 
 ++ 
 ) 
  
 { 
  
 // Creates an ad group. 
  
 long 
  
 adGroupId 
  
 = 
  
 GetNextTemporaryId 
 (); 
  
 AdGroup 
  
 adGroup 
  
 = 
  
 new 
  
 AdGroup 
 () 
  
 { 
  
 ResourceName 
  
 = 
  
 ResourceNames 
 . 
 AdGroup 
 ( 
 customerId 
 , 
  
 adGroupId 
 ), 
  
 Name 
  
 = 
  
 "batch job ad group #" 
  
 + 
  
 ExampleUtilities 
 . 
 GetShortRandomString 
 (), 
  
 Campaign 
  
 = 
  
 campaignOperation 
 . 
 Create 
 . 
 ResourceName 
 , 
  
 Type 
  
 = 
  
 AdGroupType 
 . 
 SearchStandard 
 , 
  
 CpcBidMicros 
  
 = 
  
 10 
 _000_000 
  
 }; 
  
 // Creates an ad group operation and adds it to the operations list. 
  
 AdGroupOperation 
  
 op 
  
 = 
  
 new 
  
 AdGroupOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 adGroup 
  
 }; 
  
 operations 
 . 
 Add 
 ( 
 op 
 ); 
  
 } 
  
 } 
  
 return 
  
 operations 
 ; 
  
 } 
  
 /// <summary> 
  
 /// Builds new ad group criterion operations for creating keywords. 50% of keywords are 
  
 /// created some invalid characters to demonstrate how BatchJobService returns information 
  
 /// about such errors. 
  
 /// </summary> 
  
 /// <param name="adGroupOperations">The ad group operations to be used to create ad group 
  
 /// criteria.</param> 
  
 /// <returns>The ad group criterion operations.</returns> 
  
 private 
  
 static 
  
 List<AdGroupCriterionOperation> 
  
 BuildAdGroupCriterionOperations 
 ( 
  
 List<AdGroupOperation> 
  
 adGroupOperations 
 ) 
  
 { 
  
 List<AdGroupCriterionOperation> 
  
 operations 
  
 = 
  
 new 
  
 List<AdGroupCriterionOperation> 
 (); 
  
 foreach 
  
 ( 
 AdGroupOperation 
  
 adGroupOperation 
  
 in 
  
 adGroupOperations 
 ) 
  
 { 
  
 for 
  
 ( 
 int 
  
 i 
  
 = 
  
 0 
 ; 
  
 i 
 < 
 NUMBER_OF_KEYWORDS_TO_ADD 
 ; 
  
 i 
 ++ 
 ) 
  
 { 
  
 // Creates a keyword text by making 50% of keywords invalid to demonstrate 
  
 // error handling. 
  
 string 
  
 keywordText 
  
 = 
  
 "mars" 
  
 + 
  
 i 
 ; 
  
 if 
  
 ( 
 i 
  
 % 
  
 2 
  
 == 
  
 0 
 ) 
  
 { 
  
 keywordText 
  
 += 
  
 "!!!" 
 ; 
  
 } 
  
 // Creates an ad group criterion using the created keyword text. 
  
 AdGroupCriterion 
  
 adGroupCriterion 
  
 = 
  
 new 
  
 AdGroupCriterion 
 () 
  
 { 
  
 Keyword 
  
 = 
  
 new 
  
 KeywordInfo 
 () 
  
 { 
  
 Text 
  
 = 
  
 keywordText 
 , 
  
 MatchType 
  
 = 
  
 KeywordMatchType 
 . 
 Broad 
 , 
  
 }, 
  
 AdGroup 
  
 = 
  
 adGroupOperation 
 . 
 Create 
 . 
 ResourceName 
 , 
  
 Status 
  
 = 
  
 AdGroupCriterionStatus 
 . 
 Paused 
  
 }; 
  
 // Creates an ad group criterion operation and adds it to the operations list. 
  
 AdGroupCriterionOperation 
  
 op 
  
 = 
  
 new 
  
 AdGroupCriterionOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 adGroupCriterion 
  
 }; 
  
 operations 
 . 
 Add 
 ( 
 op 
 ); 
  
 } 
  
 } 
  
 return 
  
 operations 
 ; 
  
 } 
  
 /// <summary> 
  
 /// Builds the ad group ad operations. 
  
 /// </summary> 
  
 /// <param name="adGroupOperations">The ad group operations to be used to create ad 
  
 /// group ads.</param> 
  
 /// <returns>The ad group ad operations.</returns> 
  
 private 
  
 static 
  
 List<AdGroupAdOperation> 
  
 BuildAdGroupAdOperations 
 ( 
  
 List<AdGroupOperation> 
  
 adGroupOperations 
 ) 
  
 { 
  
 List<AdGroupAdOperation> 
  
 operations 
  
 = 
  
 new 
  
 List<AdGroupAdOperation> 
 (); 
  
 foreach 
  
 ( 
 AdGroupOperation 
  
 adGroupOperation 
  
 in 
  
 adGroupOperations 
 ) 
  
 { 
  
 // Creates an ad group ad. 
  
 AdGroupAd 
  
 adGroupAd 
  
 = 
  
 new 
  
 AdGroupAd 
 () 
  
 { 
  
 Ad 
  
 = 
  
 new 
  
 Ad 
  
 { 
  
 FinalUrls 
  
 = 
  
 { 
  
 "http://www.example.com/" 
  
 }, 
  
 // Sets the expanded text ad info on an ad. 
  
 ExpandedTextAd 
  
 = 
  
 new 
  
 ExpandedTextAdInfo 
  
 { 
  
 HeadlinePart1 
  
 = 
  
 "Cruise #" 
  
 + 
  
 ExampleUtilities 
 . 
 GetShortRandomString 
 () 
  
 + 
  
 " to Mars" 
 , 
  
 HeadlinePart2 
  
 = 
  
 "Best Space Cruise Line" 
 , 
  
 Description 
  
 = 
  
 "Buy your tickets now!" 
 , 
  
 }, 
  
 }, 
  
 AdGroup 
  
 = 
  
 adGroupOperation 
 . 
 Create 
 . 
 ResourceName 
 , 
  
 // Optional: Set the status. 
  
 Status 
  
 = 
  
 AdGroupAdStatus 
 . 
 Paused 
 , 
  
 }; 
  
 // Creates an ad group ad operation and adds it to the operations list. 
  
 AdGroupAdOperation 
  
 op 
  
 = 
  
 new 
  
 AdGroupAdOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 adGroupAd 
  
 }; 
  
 operations 
 . 
 Add 
 ( 
 op 
 ); 
  
 } 
  
 return 
  
 operations 
 ; 
  
 } 
  
 /// <summary> 
  
 /// Returns the next temporary ID and decreases it by one. 
  
 /// </summary> 
  
 /// <returns>The next temporary ID.</returns> 
  
 private 
  
 static 
  
 long 
  
 GetNextTemporaryId 
 () 
  
 { 
  
 return 
  
 temporaryId 
 -- 
 ; 
  
 } 
  
 } 
 } 
  
  

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\CampaignManagement; 
 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\Examples\Utils\Helper; 
 use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder; 
 use Google\Ads\GoogleAds\Lib\V21\GoogleAdsClient; 
 use Google\Ads\GoogleAds\Lib\V21\GoogleAdsClientBuilder; 
 use Google\Ads\GoogleAds\Lib\V21\GoogleAdsException; 
 use Google\Ads\GoogleAds\Util\V21\ResourceNames; 
 use Google\Ads\GoogleAds\V21\Common\ExpandedTextAdInfo; 
 use Google\Ads\GoogleAds\V21\Common\KeywordInfo; 
 use Google\Ads\GoogleAds\V21\Common\ManualCpc; 
 use Google\Ads\GoogleAds\V21\Enums\AdGroupAdStatusEnum\AdGroupAdStatus; 
 use Google\Ads\GoogleAds\V21\Enums\AdGroupCriterionStatusEnum\AdGroupCriterionStatus; 
 use Google\Ads\GoogleAds\V21\Enums\AdGroupTypeEnum\AdGroupType; 
 use Google\Ads\GoogleAds\V21\Enums\AdvertisingChannelTypeEnum\AdvertisingChannelType; 
 use Google\Ads\GoogleAds\V21\Enums\BudgetDeliveryMethodEnum\BudgetDeliveryMethod; 
 use Google\Ads\GoogleAds\V21\Enums\CampaignStatusEnum\CampaignStatus; 
 use Google\Ads\GoogleAds\V21\Enums\EuPoliticalAdvertisingStatusEnum\EuPoliticalAdvertisingStatus; 
 use Google\Ads\GoogleAds\V21\Enums\KeywordMatchTypeEnum\KeywordMatchType; 
 use Google\Ads\GoogleAds\V21\Errors\GoogleAdsError; 
 use Google\Ads\GoogleAds\V21\Resources\Ad; 
 use Google\Ads\GoogleAds\V21\Resources\AdGroup; 
 use Google\Ads\GoogleAds\V21\Resources\AdGroupAd; 
 use Google\Ads\GoogleAds\V21\Resources\AdGroupCriterion; 
 use Google\Ads\GoogleAds\V21\Resources\BatchJob; 
 use Google\Ads\GoogleAds\V21\Resources\Campaign; 
 use Google\Ads\GoogleAds\V21\Resources\CampaignBudget; 
 use Google\Ads\GoogleAds\V21\Resources\CampaignCriterion; 
 use Google\Ads\GoogleAds\V21\Services\AddBatchJobOperationsRequest; 
 use Google\Ads\GoogleAds\V21\Services\AdGroupAdOperation; 
 use Google\Ads\GoogleAds\V21\Services\AdGroupCriterionOperation; 
 use Google\Ads\GoogleAds\V21\Services\AdGroupOperation; 
 use Google\Ads\GoogleAds\V21\Services\BatchJobOperation; 
 use Google\Ads\GoogleAds\V21\Services\BatchJobResult; 
 use Google\Ads\GoogleAds\V21\Services\CampaignBudgetOperation; 
 use Google\Ads\GoogleAds\V21\Services\CampaignCriterionOperation; 
 use Google\Ads\GoogleAds\V21\Services\CampaignOperation; 
 use Google\Ads\GoogleAds\V21\Services\Client\BatchJobServiceClient; 
 use Google\Ads\GoogleAds\V21\Services\ListBatchJobResultsRequest; 
 use Google\Ads\GoogleAds\V21\Services\MutateBatchJobRequest; 
 use Google\Ads\GoogleAds\V21\Services\MutateOperation; 
 use Google\Ads\GoogleAds\V21\Services\RunBatchJobRequest; 
 use Google\ApiCore\ApiException; 
 use Google\ApiCore\OperationResponse; 
 /** 
 * This example adds complete campaigns including campaign budgets, campaigns, ad groups and 
 * keywords using BatchJobService. 
 */ 
 class AddCompleteCampaignsUsingBatchJob 
 { 
 private const CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE'; 
 private const NUMBER_OF_CAMPAIGNS_TO_ADD = 2; 
 private const NUMBER_OF_AD_GROUPS_TO_ADD = 2; 
 private const NUMBER_OF_KEYWORDS_TO_ADD = 4; 
 private const POLL_FREQUENCY_SECONDS = 1; 
 private const MAX_TOTAL_POLL_INTERVAL_SECONDS = 60; 
 private const PAGE_SIZE = 1000; 
 /** @var int the negative temporary ID used in batch job operations. */ 
 private static $temporaryId = -1; 
 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, 
 ]); 
 // 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) 
 ->build(); 
 try { 
 self::runExample( 
 $googleAdsClient, 
 $options[ArgumentNames::CUSTOMER_ID] ?: self::CUSTOMER_ID 
 ); 
 } 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 
 */ 
 public static function runExample(GoogleAdsClient $googleAdsClient, int $customerId) 
 { 
 $batchJobServiceClient = $googleAdsClient->getBatchJobServiceClient(); 
 $batchJobResourceName = self::createBatchJob($batchJobServiceClient, $customerId); 
 self::addAllBatchJobOperations( 
 $batchJobServiceClient, 
 $customerId, 
 $batchJobResourceName 
 ); 
 $operationResponse = self::runBatchJob($batchJobServiceClient, $batchJobResourceName); 
 self::pollBatchJob($operationResponse); 
 self::fetchAndPrintResults($batchJobServiceClient, $batchJobResourceName); 
 } 
 /** 
 * Creates a new batch job for the specified customer ID. 
 * 
 * @param BatchJobServiceClient $batchJobServiceClient the batch job service client 
 * @param int $customerId the customer ID 
 * @return string the resource name of the created batch job 
 */ 
 private static function createBatchJob( 
 BatchJobServiceClient $batchJobServiceClient, 
 int $customerId 
 ): string { 
 // Creates a batch job operation to create a new batch job. 
 $batchJobOperation = new BatchJobOperation(); 
 $batchJobOperation->setCreate(new BatchJob()); 
 // Issues a request to the API and get the batch job's resource name. 
 $batchJobResourceName = $batchJobServiceClient->mutateBatchJob( 
 MutateBatchJobRequest::build($customerId, $batchJobOperation) 
 )->getResult()->getResourceName(); 
 printf( 
 "Created a batch job with resource name: '%s'.%s", 
 $batchJobResourceName, 
 PHP_EOL 
 ); 
 return $batchJobResourceName; 
 } 
 /** 
 * Adds all batch job operations to the batch job. As this is the first time for this 
 * batch job, pass null as a sequence token. The response will contain the next sequence token 
 * that you can use to upload more operations in the future. 
 * 
 * @param BatchJobServiceClient $batchJobServiceClient the batch job service client 
 * @param int $customerId the customer ID 
 * @param string $batchJobResourceName the resource name of batch job to which the batch job 
 *     operations will be added 
 */ 
 private static function addAllBatchJobOperations( 
 BatchJobServiceClient $batchJobServiceClient, 
 int $customerId, 
 string $batchJobResourceName 
 ): void { 
 $response = $batchJobServiceClient->addBatchJobOperations( 
 AddBatchJobOperationsRequest::build( 
 $batchJobResourceName, 
 '', 
 self::buildAllOperations($customerId) 
 ) 
 ); 
 printf( 
 "%d mutate operations have been added so far.%s", 
 $response->getTotalOperations(), 
 PHP_EOL 
 ); 
 // You can use this next sequence token for calling addBatchJobOperations() next time. 
 printf( 
 "Next sequence token for adding next operations is '%s'.%s", 
 $response->getNextSequenceToken(), 
 PHP_EOL 
 ); 
 } 
 /** 
 * Requests the API to run the batch job for executing all uploaded batch job operations. 
 * 
 * @param BatchJobServiceClient $batchJobServiceClient the batch job service client 
 * @param string $batchJobResourceName the resource name of batch job to be run 
 * @return OperationResponse the operation response from running batch job 
 */ 
 private static function runBatchJob( 
 BatchJobServiceClient $batchJobServiceClient, 
 string $batchJobResourceName 
 ): OperationResponse { 
 $operationResponse = 
 $batchJobServiceClient->runBatchJob(RunBatchJobRequest::build($batchJobResourceName)); 
 printf( 
 "Batch job with resource name '%s' has been executed.%s", 
 $batchJobResourceName, 
 PHP_EOL 
 ); 
 return $operationResponse; 
 } 
 /** 
 * Polls the server until the batch job execution finishes by setting the initial poll 
 * delay time and the total time to wait before time-out. 
 * 
 * @param OperationResponse $operationResponse the operation response used to poll the server 
 */ 
 private static function pollBatchJob(OperationResponse $operationResponse): void 
 { 
 $operationResponse->pollUntilComplete([ 
 'initialPollDelayMillis' => self::POLL_FREQUENCY_SECONDS * 1000, 
 'totalPollTimeoutMillis' => self::MAX_TOTAL_POLL_INTERVAL_SECONDS * 1000 
 ]); 
 } 
 /** 
 * Prints all the results from running the batch job. 
 * 
 * @param BatchJobServiceClient $batchJobServiceClient the batch job service client 
 * @param string $batchJobResourceName the resource name of batch job to get its results 
 */ 
 private static function fetchAndPrintResults( 
 BatchJobServiceClient $batchJobServiceClient, 
 string $batchJobResourceName 
 ): void { 
 printf( 
 "Batch job with resource name '%s' has finished. Now, printing its results...%s", 
 $batchJobResourceName, 
 PHP_EOL 
 ); 
 // Gets all the results from running batch job and print their information. 
 $batchJobResults = $batchJobServiceClient->listBatchJobResults( 
 ListBatchJobResultsRequest::build($batchJobResourceName)->setPageSize(self::PAGE_SIZE) 
 ); 
 foreach ($batchJobResults->iterateAllElements() as $batchJobResult) { 
 /** @var BatchJobResult $batchJobResult */ 
 printf( 
 "Batch job #%d has a status '%s' and response of type '%s'.%s", 
 $batchJobResult->getOperationIndex(), 
 $batchJobResult->getStatus() 
 ? $batchJobResult->getStatus()->getMessage() : 'N/A', 
 $batchJobResult->getMutateOperationResponse() 
 ? $batchJobResult->getMutateOperationResponse()->getResponse() 
 : 'N/A', 
 PHP_EOL 
 ); 
 } 
 } 
 /** 
 * Builds all operations for creating a complete campaign and return an array of their 
 * corresponding mutate operations. 
 * 
 * @param int $customerId the customer ID 
 * @return MutateOperation[] the mutate operations to be added to a batch job 
 */ 
 private static function buildAllOperations(int $customerId): array 
 { 
 $mutateOperations = []; 
 // Creates a new campaign budget operation and add it to the array of mutate operations. 
 $campaignBudgetOperation = self::buildCampaignBudgetOperation($customerId); 
 $mutateOperations[] = 
 new MutateOperation(['campaign_budget_operation' => $campaignBudgetOperation]); 
 // Creates new campaign operations and adds them to the array of mutate operations. 
 $campaignOperations = self::buildCampaignOperations( 
 $customerId, 
 $campaignBudgetOperation->getCreate()->getResourceName() 
 ); 
 $mutateOperations = array_merge($mutateOperations, array_map( 
 function (CampaignOperation $campaignOperation) { 
 return new MutateOperation(['campaign_operation' => $campaignOperation]); 
 }, 
 $campaignOperations 
 )); 
 // Creates new campaign criterion operations and adds them to the array of mutate 
 // operations. 
 $mutateOperations = array_merge($mutateOperations, array_map( 
 function (CampaignCriterionOperation $campaignCriterionOperation) { 
 return new MutateOperation( 
 ['campaign_criterion_operation' => $campaignCriterionOperation] 
 ); 
 }, 
 self::buildCampaignCriterionOperations($campaignOperations) 
 )); 
 // Creates new ad group operations and adds them to the array of mutate operations. 
 $adGroupOperations = self::buildAdGroupOperations($customerId, $campaignOperations); 
 $mutateOperations = array_merge($mutateOperations, array_map( 
 function (AdGroupOperation $adGroupOperation) { 
 return new MutateOperation(['ad_group_operation' => $adGroupOperation]); 
 }, 
 $adGroupOperations 
 )); 
 // Creates new ad group criterion operations and adds them to the array of mutate 
 // operations. 
 $mutateOperations = array_merge($mutateOperations, array_map( 
 function (AdGroupCriterionOperation $adGroupCriterionOperation) { 
 return new MutateOperation( 
 ['ad_group_criterion_operation' => $adGroupCriterionOperation] 
 ); 
 }, 
 self::buildAdGroupCriterionOperations($adGroupOperations) 
 )); 
 // Creates new ad group ad operations and adds them to the array of mutate operations. 
 $mutateOperations = array_merge($mutateOperations, array_map( 
 function (AdGroupAdOperation $adGroupAdOperation) { 
 return new MutateOperation(['ad_group_ad_operation' => $adGroupAdOperation]); 
 }, 
 self::buildAdGroupAdOperations($adGroupOperations) 
 )); 
 return $mutateOperations; 
 } 
 /** 
 * Builds a new campaign budget operation for the specified customer ID. 
 * 
 * @param int $customerId the customer ID 
 * @return CampaignBudgetOperation the campaign budget operation 
 */ 
 private static function buildCampaignBudgetOperation(int $customerId): CampaignBudgetOperation 
 { 
 // Creates a campaign budget operation. 
 return new CampaignBudgetOperation([ 
 'create' => new CampaignBudget([ 
 // Creates a resource name using the temporary ID. 
 'resource_name' => ResourceNames::forCampaignBudget( 
 $customerId, 
 self::getNextTemporaryId() 
 ), 
 'name' => 'Interplanetary Cruise Budget #' . Helper::getPrintableDatetime(), 
 'delivery_method' => BudgetDeliveryMethod::STANDARD, 
 'amount_micros' => 5000000 
 ]) 
 ]); 
 } 
 /** 
 * Builds new campaign operations for the specified customer ID. 
 * 
 * @param int $customerId the customer ID 
 * @param string $campaignBudgetResourceName the resource name of campaign budget to be used 
 *     to create campaigns 
 * @return CampaignOperation[] the campaign operations 
 */ 
 private static function buildCampaignOperations( 
 int $customerId, 
 string $campaignBudgetResourceName 
 ): array { 
 $operations = []; 
 for ($i = 0; $i < self::NUMBER_OF_CAMPAIGNS_TO_ADD; $i++) { 
 // Creates a campaign. 
 $campaignId = self::getNextTemporaryId(); 
 $campaign = new Campaign([ 
 // Creates a resource name using the temporary ID. 
 'resource_name' => ResourceNames::forCampaign($customerId, $campaignId), 
 'name' => sprintf( 
 'Mutate job campaign #%s.%d', 
 Helper::getPrintableDatetime(), 
 $campaignId 
 ), 
 'advertising_channel_type' => AdvertisingChannelType::SEARCH, 
 // Recommendation: Set the campaign to PAUSED when creating it to prevent 
 // the ads from immediately serving. Set to ENABLED once you've added 
 // targeting and the ads are ready to serve. 
 'status' => CampaignStatus::PAUSED, 
 // Sets the bidding strategy and budget. 
 'manual_cpc' => new ManualCpc(), 
 'campaign_budget' => $campaignBudgetResourceName, 
 // Declare whether or not this campaign serves political ads targeting the EU. 
 'contains_eu_political_advertising' = 
> EuPoliticalAdvertisingStatus::DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING 
 ]); 
 // Creates a campaign operation and add it to the operations list. 
 $operations[] = new CampaignOperation(['create' => $campaign]); 
 } 
 return $operations; 
 } 
 /** 
 * Builds new campaign criterion operations for creating negative campaign criteria 
 * (as keywords). 
 * 
 * @param CampaignOperation[] $campaignOperations the campaign operations to be used to create 
 *     campaign criteria 
 * @return CampaignCriterionOperation[] the campaign criterion operations 
 */ 
 private static function buildCampaignCriterionOperations(array $campaignOperations): array 
 { 
 $operations = []; 
 foreach ($campaignOperations as $campaignOperation) { 
 // Creates a campaign criterion. 
 $campaignCriterion = new CampaignCriterion([ 
 'keyword' => new KeywordInfo([ 
 'text' => 'venus', 
 'match_type' => KeywordMatchType::BROAD 
 ]), 
 // Sets the campaign criterion as a negative criterion. 
 'negative' => true, 
 'campaign' => $campaignOperation->getCreate()->getResourceName() 
 ]); 
 // Creates a campaign criterion operation and add it to the operations list. 
 $operations[] = new CampaignCriterionOperation(['create' => $campaignCriterion]); 
 } 
 return $operations; 
 } 
 /** 
 * Builds new ad group operations for the specified customer ID. 
 * 
 * @param int $customerId the customer ID 
 * @param CampaignOperation[] $campaignOperations the campaign operations to be used to create 
 *     ad groups 
 * @return AdGroupOperation[] the ad group operations 
 */ 
 private static function buildAdGroupOperations( 
 int $customerId, 
 array $campaignOperations 
 ): array { 
 $operations = []; 
 foreach ($campaignOperations as $campaignOperation) { 
 for ($i = 0; $i < self::NUMBER_OF_AD_GROUPS_TO_ADD; $i++) { 
 // Creates an ad group. 
 $adGroupId = self::getNextTemporaryId(); 
 $adGroup = new AdGroup([ 
 // Creates a resource name using the temporary ID. 
 'resource_name' => ResourceNames::forAdGroup($customerId, $adGroupId), 
 'name' => sprintf( 
 'Mutate job ad group #%s.%d', 
 Helper::getPrintableDatetime(), 
 $adGroupId 
 ), 
 'campaign' => $campaignOperation->getCreate()->getResourceName(), 
 'type' => AdGroupType::SEARCH_STANDARD, 
 'cpc_bid_micros' => 10000000 
 ]); 
 // Creates an ad group operation and add it to the operations list. 
 $operations[] = new AdGroupOperation(['create' => $adGroup]); 
 } 
 } 
 return $operations; 
 } 
 /** 
 * Builds new ad group criterion operations for creating keywords. 50% of keywords are created 
 * with some invalid characters to demonstrate how BatchJobService returns information about 
 * such errors. 
 * 
 * @param AdGroupOperation[] $adGroupOperations the ad group operations to be used to create 
 *     ad group criteria 
 * @return AdGroupCriterionOperation[] the ad group criterion operations 
 */ 
 private static function buildAdGroupCriterionOperations(array $adGroupOperations): array 
 { 
 $operations = []; 
 foreach ($adGroupOperations as $adGroupOperation) { 
 for ($i = 0; $i < self::NUMBER_OF_KEYWORDS_TO_ADD; $i++) { 
 // Create a keyword text by making 50% of keywords invalid to demonstrate error 
 // handling. 
 $keywordText = sprintf('mars%d', $i); 
 if ($i % 2 == 0) { 
 $keywordText = $keywordText . '!!!'; 
 } 
 // Creates an ad group criterion using the created keyword text. 
 $adGroupCriterion = new AdGroupCriterion([ 
 'keyword' => new KeywordInfo([ 
 'text' => $keywordText, 
 'match_type' => KeywordMatchType::BROAD 
 ]), 
 'ad_group' => $adGroupOperation->getCreate()->getResourceName(), 
 'status' => AdGroupCriterionStatus::ENABLED, 
 ]); 
 // Creates an ad group criterion operation and add it to the operations list. 
 $operations[] = new AdGroupCriterionOperation(['create' => $adGroupCriterion]); 
 } 
 } 
 return $operations; 
 } 
 /** 
 * Builds new ad group ad operations. 
 * 
 * @param AdGroupOperation[] $adGroupOperations the ad group operations to be used to create 
 *     ad group ads 
 * @return AdGroupAdOperation[] the ad group ad operations 
 */ 
 private static function buildAdGroupAdOperations(array $adGroupOperations): array 
 { 
 $operations = []; 
 foreach ($adGroupOperations as $adGroupOperation) { 
 // Creates an ad group ad. 
 $adGroupAd = new AdGroupAd([ 
 // Creates the expanded text ad info. 
 'ad' => new Ad([ 
 // Sets the expanded text ad info on an ad. 
 'expanded_text_ad' => new ExpandedTextAdInfo([ 
 'headline_part1' => 'Cruise to Mars #' . Helper::getPrintableDatetime(), 
 'headline_part2' => 'Best Space Cruise Line', 
 'description' => 'Buy your tickets now!' 
 ]), 
 'final_urls' => ['http://www.example.com'] 
 ]), 
 'ad_group' => $adGroupOperation->getCreate()->getResourceName(), 
 'status' => AdGroupAdStatus::PAUSED, 
 ]); 
 // Creates an ad group ad operation and add it to the operations list. 
 $operations[] = new AdGroupAdOperation(['create' => $adGroupAd]); 
 } 
 return $operations; 
 } 
 /** 
 * Returns the next temporary ID and decrease it by one. 
 * 
 * @return int the next temporary ID 
 */ 
 private static function getNextTemporaryId(): int 
 { 
 return self::$temporaryId--; 
 } 
 } 
 AddCompleteCampaignsUsingBatchJob::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. 
 """Adds complete campaigns using BatchJobService. 
 Complete campaigns include campaign budgets, campaigns, ad groups and keywords. 
 """ 
 import 
  
 argparse 
 import 
  
 asyncio 
 import 
  
 sys 
 from 
  
 uuid 
  
 import 
 uuid4 
 from 
  
 typing 
  
 import 
 Any 
 , 
 List 
 , 
 Coroutine 
 from 
  
 google.api_core.operation 
  
 import 
 Operation 
 from 
  
 google.ads.googleads.client 
  
 import 
 GoogleAdsClient 
 from 
  
 google.ads.googleads.errors 
  
 import 
 GoogleAdsException 
 from 
  
 google.ads.googleads.v21.services.services.batch_job_service 
  
 import 
 ( 
 BatchJobServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.types.batch_job_service 
  
 import 
 ( 
 MutateBatchJobResponse 
 , 
 AddBatchJobOperationsResponse 
 , 
 ListBatchJobResultsRequest 
 , 
 ListBatchJobResultsResponse 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.types.google_ads_service 
  
 import 
 ( 
 MutateOperation 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.resources.types.batch_job 
  
 import 
 BatchJob 
 from 
  
 google.ads.googleads.v21.services.types.campaign_budget_service 
  
 import 
 ( 
 CampaignBudgetOperation 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.types.campaign_service 
  
 import 
 ( 
 CampaignOperation 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.types.campaign_criterion_service 
  
 import 
 ( 
 CampaignCriterionOperation 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.types.ad_group_service 
  
 import 
 ( 
 AdGroupOperation 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.types.ad_group_criterion_service 
  
 import 
 ( 
 AdGroupCriterionOperation 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.types.ad_group_ad_service 
  
 import 
 ( 
 AdGroupAdOperation 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.types.batch_job_service 
  
 import 
 ( 
 BatchJobOperation 
 , 
 ) 
 NUMBER_OF_CAMPAIGNS_TO_ADD 
 : 
 int 
 = 
 2 
 NUMBER_OF_AD_GROUPS_TO_ADD 
 : 
 int 
 = 
 2 
 NUMBER_OF_KEYWORDS_TO_ADD 
 : 
 int 
 = 
 4 
 _temporary_id 
 : 
 int 
 = 
 0 
 def 
  
 get_next_temporary_id 
 () 
 - 
> int 
 : 
  
 """Returns the next temporary ID to use in batch job operations. 
 Decrements the temporary ID by one before returning it. The first value 
 returned for the ID is -1. 
 Returns: an int of the next temporary ID. 
 """ 
 global 
 _temporary_id 
 _temporary_id 
 -= 
 1 
 return 
 _temporary_id 
 def 
  
 build_mutate_operation 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 operation_type 
 : 
 str 
 , 
 operation 
 : 
 Any 
 ) 
 - 
> MutateOperation 
 : 
  
 """Builds a mutate operation with the given operation type and operation. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 operation_type: a str of the operation type corresponding to a field on 
 the MutateOperation message class. 
 operation: an operation instance. 
 Returns: a MutateOperation instance 
 """ 
 mutate_operation 
 : 
 MutateOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "MutateOperation" 
 ) 
 # Retrieve the nested operation message instance using getattr then copy the 
 # contents of the given operation into it using the client.copy_from method. 
 client 
 . 
 copy_from 
 ( 
 getattr 
 ( 
 mutate_operation 
 , 
 operation_type 
 ), 
 operation 
 ) 
 return 
 mutate_operation 
 async 
 def 
  
 main 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 ) 
 - 
> None 
 : 
  
 """Main function that runs the example. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a str of a customer ID. 
 """ 
 batch_job_service 
 : 
 BatchJobServiceClient 
 = 
 client 
 . 
 get_service 
 ( 
 "BatchJobService" 
 ) 
 batch_job_operation 
 : 
 BatchJobOperation 
 = 
 create_batch_job_operation 
 ( 
 client 
 ) 
 resource_name 
 : 
 str 
 = 
 create_batch_job 
 ( 
 batch_job_service 
 , 
 customer_id 
 , 
 batch_job_operation 
 ) 
 operations 
 : 
 List 
 [ 
 MutateOperation 
 ] 
 = 
 build_all_operations 
 ( 
 client 
 , 
 customer_id 
 ) 
 add_all_batch_job_operations 
 ( 
 batch_job_service 
 , 
 operations 
 , 
 resource_name 
 ) 
 operations_response 
 : 
 Operation 
 = 
 run_batch_job 
 ( 
 batch_job_service 
 , 
 resource_name 
 ) 
 # Create an asyncio.Event instance to control execution during the 
 # asynchronous steps in _poll_batch_job. Note that this is not important 
 # for polling asynchronously, it simply helps with execution control, so we 
 # can run _fetch_and_print_results after the asynchronous operations have 
 # completed. 
 done_event 
 : 
 asyncio 
 . 
 Event 
 = 
 asyncio 
 . 
 Event 
 () 
 poll_batch_job 
 ( 
 operations_response 
 , 
 done_event 
 ) 
 # Execution will stop here and wait for the asynchronous steps in 
 # _poll_batch_job to complete before proceeding. 
 await 
 done_event 
 . 
 wait 
 () 
 fetch_and_print_results 
 ( 
 client 
 , 
 batch_job_service 
 , 
 resource_name 
 ) 
 def 
  
 create_batch_job_operation 
 ( 
 client 
 : 
 GoogleAdsClient 
 ) 
 - 
> BatchJobOperation 
 : 
  
 """Created a BatchJobOperation and sets an empty BatchJob instance to 
 the "create" property in order to tell the Google Ads API that we're 
 creating a new BatchJob. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 Returns: a BatchJobOperation with a BatchJob instance set in the "create" 
 property. 
 """ 
 batch_job_operation 
 : 
 BatchJobOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "BatchJobOperation" 
 ) 
 batch_job 
 : 
 BatchJob 
 = 
 client 
 . 
 get_type 
 ( 
 "BatchJob" 
 ) 
 client 
 . 
 copy_from 
 ( 
 batch_job_operation 
 . 
 create 
 , 
 batch_job 
 ) 
 return 
 batch_job_operation 
 def 
  
 create_batch_job 
 ( 
 batch_job_service 
 : 
 BatchJobServiceClient 
 , 
 customer_id 
 : 
 str 
 , 
 batch_job_operation 
 : 
 BatchJobOperation 
 , 
 ) 
 - 
> str 
 : 
  
 """Creates a batch job for the specified customer ID. 
 Args: 
 batch_job_service: an instance of the BatchJobService message class. 
 customer_id: a str of a customer ID. 
 batch_job_operation: a BatchJobOperation instance set to "create" 
 Returns: a str of a resource name for a batch job. 
 """ 
 try 
 : 
 response 
 : 
 MutateBatchJobResponse 
 = 
 batch_job_service 
 . 
 mutate_batch_job 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operation 
 = 
 batch_job_operation 
 ) 
 resource_name 
 : 
 str 
 = 
 response 
 . 
 result 
 . 
 resource_name 
 print 
 ( 
 f 
 'Created a batch job with resource name " 
 { 
 resource_name 
 } 
 "' 
 ) 
 return 
 resource_name 
 except 
 GoogleAdsException 
 as 
 exception 
 : 
 handle_googleads_exception 
 ( 
 exception 
 ) 
 # This line will likely not be reached due to sys.exit(1) in handle_googleads_exception 
 # but to satisfy the type checker, we add a return statement. 
 return 
 "" 
 # Or raise an exception 
 def 
  
 add_all_batch_job_operations 
 ( 
 batch_job_service 
 : 
 BatchJobServiceClient 
 , 
 operations 
 : 
 List 
 [ 
 MutateOperation 
 ], 
 resource_name 
 : 
 str 
 , 
 ) 
 - 
> None 
 : 
  
 """Adds all mutate operations to the batch job. 
 As this is the first time for this batch job, we pass null as a sequence 
 token. The response will contain the next sequence token that we can use 
 to upload more operations in the future. 
 Args: 
 batch_job_service: an instance of the BatchJobService message class. 
 operations: a list of a mutate operations. 
 resource_name: a str of a resource name for a batch job. 
 """ 
 try 
 : 
 response 
 : 
 AddBatchJobOperationsResponse 
 = 
 ( 
 batch_job_service 
 . 
 add_batch_job_operations 
 ( 
 resource_name 
 = 
 resource_name 
 , 
 sequence_token 
 = 
 None 
 , 
 # type: ignore 
 mutate_operations 
 = 
 operations 
 , 
 ) 
 ) 
 print 
 ( 
 f 
 " 
 { 
 response 
 . 
 total_operations 
 } 
 mutate operations have been " 
 "added so far." 
 ) 
 # You can use this next sequence token for calling 
 # add_batch_job_operations() next time. 
 print 
 ( 
 "Next sequence token for adding next operations is " 
 f 
 " 
 { 
 response 
 . 
 next_sequence_token 
 } 
 " 
 ) 
 except 
 GoogleAdsException 
 as 
 exception 
 : 
 handle_googleads_exception 
 ( 
 exception 
 ) 
 def 
  
 build_all_operations 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 ) 
 - 
> List 
 [ 
 MutateOperation 
 ]: 
  
 """Builds all operations for creating a complete campaign. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a str of a customer ID. 
 Returns: a list of operations of various types. 
 """ 
 operations 
 : 
 List 
 [ 
 MutateOperation 
 ] 
 = 
 [] 
 # Creates a new campaign budget operation and adds it to the list of 
 # mutate operations. 
 campaign_budget_op 
 : 
 CampaignBudgetOperation 
 = 
 ( 
 build_campaign_budget_operation 
 ( 
 client 
 , 
 customer_id 
 ) 
 ) 
 operations 
 . 
 append 
 ( 
 build_mutate_operation 
 ( 
 client 
 , 
 "campaign_budget_operation" 
 , 
 campaign_budget_op 
 ) 
 ) 
 # Creates new campaign operations and adds them to the list of 
 # mutate operations. 
 campaign_operations 
 : 
 List 
 [ 
 CampaignOperation 
 ] 
 = 
 build_campaign_operations 
 ( 
 client 
 , 
 customer_id 
 , 
 campaign_budget_op 
 . 
 create 
 . 
 resource_name 
 ) 
 operations 
 . 
 extend 
 ( 
 build_mutate_operation 
 ( 
 client 
 , 
 "campaign_operation" 
 , 
 operation 
 ) 
 for 
 operation 
 in 
 campaign_operations 
 ) 
 # Creates new campaign criterion operations and adds them to the list of 
 # mutate operations. 
 campaign_criterion_operations 
 : 
 List 
 [ 
 CampaignCriterionOperation 
 ] 
 = 
 ( 
 build_campaign_criterion_operations 
 ( 
 client 
 , 
 campaign_operations 
 ) 
 ) 
 operations 
 . 
 extend 
 ( 
 build_mutate_operation 
 ( 
 client 
 , 
 "campaign_criterion_operation" 
 , 
 operation 
 ) 
 for 
 operation 
 in 
 campaign_criterion_operations 
 ) 
 # Creates new ad group operations and adds them to the list of 
 # mutate operations. 
 ad_group_operations 
 : 
 List 
 [ 
 AdGroupOperation 
 ] 
 = 
 build_ad_group_operations 
 ( 
 client 
 , 
 customer_id 
 , 
 campaign_operations 
 ) 
 operations 
 . 
 extend 
 ( 
 build_mutate_operation 
 ( 
 client 
 , 
 "ad_group_operation" 
 , 
 operation 
 ) 
 for 
 operation 
 in 
 ad_group_operations 
 ) 
 # Creates new ad group criterion operations and add them to the list of 
 # mutate operations. 
 ad_group_criterion_operations 
 : 
 List 
 [ 
 AdGroupCriterionOperation 
 ] 
 = 
 ( 
 build_ad_group_criterion_operations 
 ( 
 client 
 , 
 ad_group_operations 
 ) 
 ) 
 operations 
 . 
 extend 
 ( 
 build_mutate_operation 
 ( 
 client 
 , 
 "ad_group_criterion_operation" 
 , 
 operation 
 ) 
 for 
 operation 
 in 
 ad_group_criterion_operations 
 ) 
 # Creates new ad group ad operations and adds them to the list of 
 # mutate operations. 
 ad_group_ad_operations 
 : 
 List 
 [ 
 AdGroupAdOperation 
 ] 
 = 
 ( 
 build_ad_group_ad_operations 
 ( 
 client 
 , 
 ad_group_operations 
 ) 
 ) 
 operations 
 . 
 extend 
 ( 
 build_mutate_operation 
 ( 
 client 
 , 
 "ad_group_ad_operation" 
 , 
 operation 
 ) 
 for 
 operation 
 in 
 ad_group_ad_operations 
 ) 
 return 
 operations 
 def 
  
 build_campaign_budget_operation 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 ) 
 - 
> CampaignBudgetOperation 
 : 
  
 """Builds a new campaign budget operation for the given customer ID. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a str of a customer ID. 
 Returns: a CampaignBudgetOperation instance. 
 """ 
 campaign_budget_service 
 = 
 client 
 . 
 get_service 
 ( 
 "CampaignBudgetService" 
 ) 
 campaign_budget_operation 
 : 
 CampaignBudgetOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "CampaignBudgetOperation" 
 ) 
 campaign_budget 
 = 
 campaign_budget_operation 
 . 
 create 
 resource_name 
 : 
 str 
 = 
 campaign_budget_service 
 . 
 campaign_budget_path 
 ( 
 customer_id 
 , 
 get_next_temporary_id 
 () 
 ) 
 campaign_budget 
 . 
 resource_name 
 = 
 resource_name 
 campaign_budget 
 . 
 name 
 = 
 f 
 "Interplanetary Cruise Budget # 
 { 
 uuid4 
 () 
 } 
 " 
 campaign_budget 
 . 
 delivery_method 
 = 
 ( 
 client 
 . 
 enums 
 . 
 BudgetDeliveryMethodEnum 
 . 
 STANDARD 
 ) 
 campaign_budget 
 . 
 amount_micros 
 = 
 5000000 
 return 
 campaign_budget_operation 
 def 
  
 build_campaign_operations 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 campaign_budget_resource_name 
 : 
 str 
 , 
 ) 
 - 
> List 
 [ 
 CampaignOperation 
 ]: 
  
 """Builds new campaign operations for the specified customer ID. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a str of a customer ID. 
 campaign_budget_resource_name: a str resource name for a campaign 
 budget. 
 Returns: a list of CampaignOperation instances. 
 """ 
 return 
 [ 
 build_campaign_operation 
 ( 
 client 
 , 
 customer_id 
 , 
 campaign_budget_resource_name 
 ) 
 for 
 _ 
 in 
 range 
 ( 
 NUMBER_OF_CAMPAIGNS_TO_ADD 
 ) 
 ] 
 def 
  
 build_campaign_operation 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 campaign_budget_resource_name 
 : 
 str 
 , 
 ) 
 - 
> CampaignOperation 
 : 
  
 """Builds new campaign operation for the specified customer ID. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a str of a customer ID. 
 campaign_budget_resource_name: a str resource name for a campaign 
 budget. 
 Returns: a CampaignOperation instance. 
 """ 
 campaign_operation 
 : 
 CampaignOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "CampaignOperation" 
 ) 
 campaign_service 
 = 
 client 
 . 
 get_service 
 ( 
 "CampaignService" 
 ) 
 # Creates a campaign. 
 campaign 
 = 
 campaign_operation 
 . 
 create 
 campaign_id 
 : 
 int 
 = 
 get_next_temporary_id 
 () 
 # Creates a resource name using the temporary ID. 
 campaign 
 . 
 resource_name 
 = 
 campaign_service 
 . 
 campaign_path 
 ( 
 customer_id 
 , 
 campaign_id 
 ) 
 campaign 
 . 
 name 
 = 
 f 
 "Batch job campaign # 
 { 
 customer_id 
 } 
 . 
 { 
 campaign_id 
 } 
 " 
 campaign 
 . 
 advertising_channel_type 
 = 
 ( 
 client 
 . 
 enums 
 . 
 AdvertisingChannelTypeEnum 
 . 
 SEARCH 
 ) 
 # Recommendation: Set the campaign to PAUSED when creating it to prevent 
 # the ads from immediately serving. Set to ENABLED once you've added 
 # targeting and the ads are ready to serve. 
 campaign 
 . 
 status 
 = 
 client 
 . 
 enums 
 . 
 CampaignStatusEnum 
 . 
 PAUSED 
 # Set the bidding strategy and type by setting manual_cpc equal to an empty 
 # ManualCpc instance. 
 client 
 . 
 copy_from 
 ( 
 campaign 
 . 
 manual_cpc 
 , 
 client 
 . 
 get_type 
 ( 
 "ManualCpc" 
 )) 
 campaign 
 . 
 campaign_budget 
 = 
 campaign_budget_resource_name 
 # Declare whether or not this campaign serves political ads targeting the 
 # EU. Valid values are: 
 #   CONTAINS_EU_POLITICAL_ADVERTISING 
 #   DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING 
 campaign 
 . 
 contains_eu_political_advertising 
 = 
 ( 
 client 
 . 
 enums 
 . 
 EuPoliticalAdvertisingStatusEnum 
 . 
 DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING 
 ) 
 return 
 campaign_operation 
 def 
  
 build_campaign_criterion_operations 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 campaign_operations 
 : 
 List 
 [ 
 CampaignOperation 
 ] 
 ) 
 - 
> List 
 [ 
 CampaignCriterionOperation 
 ]: 
  
 """Builds new campaign criterion operations for negative keyword criteria. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 campaign_operations: a list of CampaignOperation instances. 
 Returns: a list of CampaignCriterionOperation instances. 
 """ 
 return 
 [ 
 build_campaign_criterion_operation 
 ( 
 client 
 , 
 campaign_operation 
 ) 
 for 
 campaign_operation 
 in 
 campaign_operations 
 ] 
 def 
  
 build_campaign_criterion_operation 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 campaign_operation 
 : 
 CampaignOperation 
 ) 
 - 
> CampaignCriterionOperation 
 : 
  
 """Builds a new campaign criterion operation for negative keyword criterion. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 campaign_operation: a CampaignOperation instance. 
 Returns: a CampaignCriterionOperation instance. 
 """ 
 campaign_criterion_operation 
 : 
 CampaignCriterionOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "CampaignCriterionOperation" 
 ) 
 # Creates a campaign criterion. 
 campaign_criterion 
 = 
 campaign_criterion_operation 
 . 
 create 
 campaign_criterion 
 . 
 keyword 
 . 
 text 
 = 
 "venus" 
 campaign_criterion 
 . 
 keyword 
 . 
 match_type 
 = 
 ( 
 client 
 . 
 enums 
 . 
 KeywordMatchTypeEnum 
 . 
 BROAD 
 ) 
 # Sets the campaign criterion as a negative criterion. 
 campaign_criterion 
 . 
 negative 
 = 
 True 
 campaign_criterion 
 . 
 campaign 
 = 
 campaign_operation 
 . 
 create 
 . 
 resource_name 
 return 
 campaign_criterion_operation 
 def 
  
 build_ad_group_operations 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 campaign_operations 
 : 
 List 
 [ 
 CampaignOperation 
 ], 
 ) 
 - 
> List 
 [ 
 AdGroupOperation 
 ]: 
  
 """Builds new ad group operations for the specified customer ID. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a str of a customer ID. 
 campaign_operations: a list of CampaignOperation instances. 
 Return: a list of AdGroupOperation instances. 
 """ 
 operations 
 : 
 List 
 [ 
 AdGroupOperation 
 ] 
 = 
 [] 
 for 
 campaign_operation 
 in 
 campaign_operations 
 : 
 for 
 _ 
 in 
 range 
 ( 
 NUMBER_OF_AD_GROUPS_TO_ADD 
 ): 
 operations 
 . 
 append 
 ( 
 build_ad_group_operation 
 ( 
 client 
 , 
 customer_id 
 , 
 campaign_operation 
 ) 
 ) 
 return 
 operations 
 def 
  
 build_ad_group_operation 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 campaign_operation 
 : 
 CampaignOperation 
 , 
 ) 
 - 
> AdGroupOperation 
 : 
  
 """Builds a new ad group operation for the specified customer ID. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a str of a customer ID. 
 campaign_operation: a CampaignOperation instance. 
 Return: an AdGroupOperation instance. 
 """ 
 ad_group_operation 
 : 
 AdGroupOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "AdGroupOperation" 
 ) 
 ad_group_service 
 = 
 client 
 . 
 get_service 
 ( 
 "AdGroupService" 
 ) 
 # Creates an ad group. 
 ad_group 
 = 
 ad_group_operation 
 . 
 create 
 ad_group_id 
 : 
 int 
 = 
 get_next_temporary_id 
 () 
 # Creates a resource name using the temporary ID. 
 ad_group 
 . 
 resource_name 
 = 
 ad_group_service 
 . 
 ad_group_path 
 ( 
 customer_id 
 , 
 ad_group_id 
 ) 
 ad_group 
 . 
 name 
 = 
 f 
 "Batch job ad group # 
 { 
 uuid4 
 () 
 } 
 . 
 { 
 ad_group_id 
 } 
 " 
 ad_group 
 . 
 campaign 
 = 
 campaign_operation 
 . 
 create 
 . 
 resource_name 
 ad_group 
 . 
 type_ 
 = 
 client 
 . 
 enums 
 . 
 AdGroupTypeEnum 
 . 
 SEARCH_STANDARD 
 ad_group 
 . 
 cpc_bid_micros 
 = 
 10000000 
 return 
 ad_group_operation 
 def 
  
 build_ad_group_criterion_operations 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 ad_group_operations 
 : 
 List 
 [ 
 AdGroupOperation 
 ] 
 ) 
 - 
> List 
 [ 
 AdGroupCriterionOperation 
 ]: 
  
 """Builds new ad group criterion operations for creating keywords. 
 50% of keywords are created with some invalid characters to demonstrate 
 how BatchJobService returns information about such errors. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 ad_group_operations: a list of AdGroupOperation instances. 
 Returns a list of AdGroupCriterionOperation instances. 
 """ 
 operations 
 : 
 List 
 [ 
 AdGroupCriterionOperation 
 ] 
 = 
 [] 
 for 
 i 
 , 
 ad_group_operation 
 in 
 enumerate 
 ( 
 ad_group_operations 
 ): 
 for 
 j 
 in 
 range 
 ( 
 NUMBER_OF_KEYWORDS_TO_ADD 
 ): 
 operations 
 . 
 append 
 ( 
 build_ad_group_criterion_operation 
 ( 
 # Create a keyword text by making 50% of keywords invalid 
 # to demonstrate error handling. 
 client 
 , 
 ad_group_operation 
 , 
 j 
 , 
 # Pass j as the number for keyword text 
 ( 
 i 
 * 
 NUMBER_OF_KEYWORDS_TO_ADD 
 + 
 j 
 ) 
 % 
 2 
 == 
 0 
 , 
 ) 
 ) 
 return 
 operations 
 def 
  
 build_ad_group_criterion_operation 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 ad_group_operation 
 : 
 AdGroupOperation 
 , 
 number 
 : 
 int 
 , 
 is_valid 
 : 
 bool 
 = 
 True 
 , 
 ) 
 - 
> AdGroupCriterionOperation 
 : 
  
 """Builds new ad group criterion operation for creating keywords. 
 Takes an optional param that dictates whether the keyword text should 
 intentionally generate an error with invalid characters. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 ad_group_operation: an AdGroupOperation instance. 
 number: an int of the number to assign to the name of the criterion. 
 is_valid: a bool of whether the keyword text should be invalid. 
 Returns: an AdGroupCriterionOperation instance. 
 """ 
 ad_group_criterion_operation 
 : 
 AdGroupCriterionOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "AdGroupCriterionOperation" 
 ) 
 # Creates an ad group criterion. 
 ad_group_criterion 
 = 
 ad_group_criterion_operation 
 . 
 create 
 ad_group_criterion 
 . 
 keyword 
 . 
 text 
 = 
 f 
 "mars 
 { 
 number 
 } 
 " 
 # If keyword should be invalid we add exclamation points, which will 
 # generate errors when sent to the API. 
 if 
 not 
 is_valid 
 : 
 ad_group_criterion 
 . 
 keyword 
 . 
 text 
 += 
 "!!!" 
 ad_group_criterion 
 . 
 keyword 
 . 
 match_type 
 = 
 ( 
 client 
 . 
 enums 
 . 
 KeywordMatchTypeEnum 
 . 
 BROAD 
 ) 
 ad_group_criterion 
 . 
 ad_group 
 = 
 ad_group_operation 
 . 
 create 
 . 
 resource_name 
 # Keyword criteria do not have a status field. 
 # ad_group_criterion.status = client.enums.AdGroupCriterionStatusEnum.ENABLED 
 return 
 ad_group_criterion_operation 
 def 
  
 build_ad_group_ad_operations 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 ad_group_operations 
 : 
 List 
 [ 
 AdGroupOperation 
 ] 
 ) 
 - 
> List 
 [ 
 AdGroupAdOperation 
 ]: 
  
 """Builds new ad group ad operations. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 ad_group_operations: a list of AdGroupOperation instances. 
 Returns: a list of AdGroupAdOperation instances. 
 """ 
 return 
 [ 
 build_ad_group_ad_operation 
 ( 
 client 
 , 
 ad_group_operation 
 ) 
 for 
 ad_group_operation 
 in 
 ad_group_operations 
 ] 
 def 
  
 build_ad_group_ad_operation 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 ad_group_operation 
 : 
 AdGroupOperation 
 ) 
 - 
> AdGroupAdOperation 
 : 
  
 """Builds a new ad group ad operation. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 ad_group_operation: an AdGroupOperation instance. 
 Returns: an AdGroupAdOperation instance. 
 """ 
 ad_group_ad_operation 
 : 
 AdGroupAdOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "AdGroupAdOperation" 
 ) 
 # Creates an ad group ad. 
 ad_group_ad 
 = 
 ad_group_ad_operation 
 . 
 create 
 # Creates the expanded text ad info. 
 text_ad 
 = 
 ad_group_ad 
 . 
 ad 
 . 
 expanded_text_ad 
 text_ad 
 . 
 headline_part1 
 = 
 f 
 "Cruise to Mars # 
 { 
 uuid4 
 () 
 } 
 " 
 text_ad 
 . 
 headline_part2 
 = 
 "Best Space Cruise Line" 
 text_ad 
 . 
 description 
 = 
 "Buy your tickets now!" 
 ad_group_ad 
 . 
 ad 
 . 
 final_urls 
 . 
 append 
 ( 
 "http://www.example.com" 
 ) 
 ad_group_ad 
 . 
 ad_group 
 = 
 ad_group_operation 
 . 
 create 
 . 
 resource_name 
 ad_group_ad 
 . 
 status 
 = 
 client 
 . 
 enums 
 . 
 AdGroupAdStatusEnum 
 . 
 PAUSED 
 return 
 ad_group_ad_operation 
 def 
  
 run_batch_job 
 ( 
 batch_job_service 
 : 
 BatchJobServiceClient 
 , 
 resource_name 
 : 
 str 
 ) 
 - 
> Operation 
 : 
  
 """Runs the batch job for executing all uploaded mutate operations. 
 Args: 
 batch_job_service: an instance of the BatchJobService message class. 
 resource_name: a str of a resource name for a batch job. 
 Returns: a google.api_core.operation.Operation instance. 
 """ 
 try 
 : 
 response 
 : 
 Operation 
 = 
 batch_job_service 
 . 
 run_batch_job 
 ( 
 resource_name 
 = 
 resource_name 
 ) 
 print 
 ( 
 f 
 'Batch job with resource name " 
 { 
 resource_name 
 } 
 " has been ' 
 "executed." 
 ) 
 return 
 response 
 except 
 GoogleAdsException 
 as 
 exception 
 : 
 handle_googleads_exception 
 ( 
 exception 
 ) 
 # This line will likely not be reached due to sys.exit(1) in handle_googleads_exception 
 # but to satisfy the type checker, we add a return statement. 
 # In a real application, you might want to return a dummy Operation or raise an error. 
 return 
 Operation 
 ( 
 op_type_name 
 = 
 "type.googleapis.com/google.protobuf.Empty" 
 , 
 complete 
 = 
 True 
 , 
 done_callbacks 
 = 
 [], 
 metadata_type 
 = 
 None 
 , 
 result_type 
 = 
 None 
 , 
 ) 
 # type: ignore 
 def 
  
 poll_batch_job 
 ( 
 operations_response 
 : 
 Operation 
 , 
 event 
 : 
 asyncio 
 . 
 Event 
 ) 
 - 
> None 
 : 
  
 """Polls the server until the batch job execution finishes. 
 Sets the initial poll delay time and the total time to wait before time-out. 
 Args: 
 operations_response: a google.api_core.operation.Operation instance. 
 event: an instance of asyncio.Event to invoke once the operations have 
 completed, alerting the awaiting calling code that it can proceed. 
 """ 
 loop 
 : 
 asyncio 
 . 
 AbstractEventLoop 
 = 
 asyncio 
 . 
 get_event_loop 
 () 
 def 
  
 done_callback 
 ( 
 future 
 : 
 Coroutine 
 [ 
 Any 
 , 
 Any 
 , 
 Any 
 ]) 
 - 
> None 
 : 
 # The operations_response object will call callbacks from a daemon 
 # thread so we must use a threadsafe method of setting the event here 
 # otherwise it will not trigger the awaiting code. 
 loop 
 . 
 call_soon_threadsafe 
 ( 
 event 
 . 
 set 
 ) 
 # operations_response represents a Long-Running Operation or LRO. The class 
 # provides an interface for polling the API to check when the operation is 
 # complete. Below we use the asynchronous interface, but there's also a 
 # synchronous interface that uses the Operation.result method. 
 # See: https://googleapis.dev/python/google-api-core/latest/operation.html 
 operations_response 
 . 
 add_done_callback 
 ( 
 done_callback 
 ) 
 # type: ignore 
 def 
  
 fetch_and_print_results 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 batch_job_service 
 : 
 BatchJobServiceClient 
 , 
 resource_name 
 : 
 str 
 , 
 ) 
 - 
> None 
 : 
  
 """Prints all the results from running the batch job. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 batch_job_service: an instance of the BatchJobService message class. 
 resource_name: a str of a resource name for a batch job. 
 """ 
 print 
 ( 
 f 
 'Batch job with resource name " 
 { 
 resource_name 
 } 
 " has finished. ' 
 "Now, printing its results..." 
 ) 
 list_results_request 
 : 
 ListBatchJobResultsRequest 
 = 
 client 
 . 
 get_type 
 ( 
 "ListBatchJobResultsRequest" 
 ) 
 list_results_request 
 . 
 resource_name 
 = 
 resource_name 
 list_results_request 
 . 
 page_size 
 = 
 1000 
 # Gets all the results from running batch job and prints their information. 
 batch_job_results 
 : 
 ListBatchJobResultsResponse 
 = 
 ( 
 batch_job_service 
 . 
 list_batch_job_results 
 ( 
 request 
 = 
 list_results_request 
 ) 
 ) 
 for 
 batch_job_result 
 in 
 batch_job_results 
 : 
 status 
 : 
 str 
 = 
 batch_job_result 
 . 
 status 
 . 
 message 
 status 
 = 
 status 
 if 
 status 
 else 
 "N/A" 
 result 
 : 
 Any 
 = 
 batch_job_result 
 . 
 mutate_operation_response 
 result 
 = 
 result 
 or 
 "N/A" 
 print 
 ( 
 f 
 "Batch job # 
 { 
 batch_job_result 
 . 
 operation_index 
 } 
 " 
 f 
 'has a status " 
 { 
 status 
 } 
 " and response type " 
 { 
 result 
 } 
 "' 
 ) 
 def 
  
 handle_googleads_exception 
 ( 
 exception 
 : 
 GoogleAdsException 
 ) 
 - 
> None 
 : 
  
 """Prints the details of a GoogleAdsException object. 
 Args: 
 exception: an instance of GoogleAdsException. 
 """ 
 print 
 ( 
 f 
 'Request with ID " 
 { 
 exception 
 . 
 request_id 
 } 
 " failed with status ' 
 f 
 '" 
 { 
 exception 
 . 
 error 
 . 
 code 
 () 
 . 
 name 
 } 
 " and includes the following errors:' 
 ) 
 for 
 error 
 in 
 exception 
 . 
 failure 
 . 
 errors 
 : 
 print 
 ( 
 f 
 ' 
 \t 
 Error with message " 
 { 
 error 
 . 
 message 
 } 
 ".' 
 ) 
 if 
 error 
 . 
 location 
 : 
 for 
 field_path_element 
 in 
 error 
 . 
 location 
 . 
 field_path_elements 
 : 
 print 
 ( 
 f 
 " 
 \t\t 
 On field: 
 { 
 field_path_element 
 . 
 field_name 
 } 
 " 
 ) 
 sys 
 . 
 exit 
 ( 
 1 
 ) 
 if 
 __name__ 
 == 
 "__main__" 
 : 
 parser 
 : 
 argparse 
 . 
 ArgumentParser 
 = 
 argparse 
 . 
 ArgumentParser 
 ( 
 description 
 = 
 ( 
 "Adds complete campaigns, including campaign budgets, " 
 "campaigns, ad groups and keywords for the given " 
 "customer ID using BatchJobService." 
 ) 
 ) 
 # 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." 
 , 
 ) 
 args 
 : 
 argparse 
 . 
 Namespace 
 = 
 parser 
 . 
 parse_args 
 () 
 # GoogleAdsClient will read the google-ads.yaml configuration file in the 
 # home directory if none is specified. 
 googleads_client 
 : 
 GoogleAdsClient 
 = 
 GoogleAdsClient 
 . 
 load_from_storage 
 ( 
 version 
 = 
 "v21" 
 ) 
 asyncio 
 . 
 run 
 ( 
 main 
 ( 
 googleads_client 
 , 
 args 
 . 
 customer_id 
 )) 
  

Ruby

 #!/usr/bin/env 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. 
 # 
 # This example adds complete campaigns including campaign budgets, campaigns, 
 # ad groups and keywords using BatchJobService. 
 require 
  
 'optparse' 
 require 
  
 'google/ads/google_ads' 
 def 
  
 add_complete_campaigns_using_batch_job 
 ( 
 customer_id 
 ) 
  
 # GoogleAdsClient will read a config file from 
  
 # ENV['HOME']/google_ads_config.rb when called without parameters 
  
 client 
  
 = 
  
 Google 
 :: 
 Ads 
 :: 
 GoogleAds 
 :: 
 GoogleAdsClient 
 . 
 new 
  
 batch_job_service 
  
 = 
  
 client 
 . 
 service 
 . 
 batch_job 
  
 batch_job_resource_name 
  
 = 
  
 create_batch_job 
 ( 
  
 client 
 , 
  
 batch_job_service 
 , 
  
 customer_id 
 , 
  
 ) 
  
 add_all_batch_job_operations 
 ( 
  
 client 
 , 
  
 batch_job_service 
 , 
  
 customer_id 
 , 
  
 batch_job_resource_name 
 , 
  
 ) 
  
 operation_response 
  
 = 
  
 run_batch_job 
 ( 
  
 batch_job_service 
 , 
  
 batch_job_resource_name 
 , 
  
 ) 
  
 poll_batch_job 
 ( 
 operation_response 
 ) 
  
 fetch_and_print_results 
 ( 
 batch_job_service 
 , 
  
 batch_job_resource_name 
 ) 
 end 
 # Creates a new batch job for the specified customer ID. 
 def 
  
 create_batch_job 
 ( 
 client 
 , 
  
 batch_job_service 
 , 
  
 customer_id 
 ) 
  
 # Creates a batch job operation to create a new batch job. 
  
 operation 
  
 = 
  
 client 
 . 
 operation 
 . 
 create_resource 
 . 
 batch_job 
  
 # Issues a request to the API and get the batch job's resource name. 
  
 response 
  
 = 
  
 batch_job_service 
 . 
 mutate_batch_job 
 ( 
  
 customer_id 
 : 
  
 customer_id 
 , 
  
 operation 
 : 
  
 operation 
  
 ) 
  
 batch_job_resource_name 
  
 = 
  
 response 
 . 
 result 
 . 
 resource_name 
  
 puts 
  
 "Created a batch job with resource name: ' 
 #{ 
 batch_job_resource_name 
 } 
 '" 
  
 batch_job_resource_name 
 end 
 # Adds all batch job operations to the batch job. As this is the first time 
 # for this batch job, pass null as a sequence token. The response will contain 
 # the next sequence token that you can use to upload more operations in the 
 # future. 
 def 
  
 add_all_batch_job_operations 
 ( 
  
 client 
 , 
  
 batch_job_service 
 , 
  
 customer_id 
 , 
  
 batch_job_resource_name 
 ) 
  
 response 
  
 = 
  
 batch_job_service 
 . 
 add_batch_job_operations 
 ( 
  
 resource_name 
 : 
  
 batch_job_resource_name 
 , 
  
 mutate_operations 
 : 
  
 build_all_operations 
 ( 
 client 
 , 
  
 customer_id 
 ), 
  
 ) 
  
 puts 
  
 " 
 #{ 
 response 
 . 
 total_operations 
 } 
 mutate operations have been added so far." 
  
 # You can use this next sequence token for calling 
  
 # add_all_batch_job_operations() next time 
  
 puts 
  
 "Next sequence token for adding next operations is " 
  
 \ 
  
 "' 
 #{ 
 response 
 . 
 next_sequence_token 
 } 
 '" 
 end 
 # Requests the API to run the batch job for executing all uploaded batch job 
 # operations. 
 def 
  
 run_batch_job 
 ( 
 batch_job_service 
 , 
  
 batch_job_resource_name 
 ) 
  
 operation_response 
  
 = 
  
 batch_job_service 
 . 
 run_batch_job 
 ( 
  
 resource_name 
 : 
  
 batch_job_resource_name 
 , 
  
 ) 
  
 puts 
  
 "Batch job with resource name ' 
 #{ 
 batch_job_resource_name 
 } 
 ' " 
  
 \ 
  
 "has been executed." 
  
 operation_response 
 end 
 # Polls the server until the batch job execution finishes by setting the initial 
 # poll delay time and the total time to wait before time-out. 
 def 
  
 poll_batch_job 
 ( 
 operation_response 
 ) 
  
 operation_response 
 . 
 wait_until_done! 
 end 
 # Prints all the results from running the batch job. 
 def 
  
 fetch_and_print_results 
 ( 
 batch_job_service 
 , 
  
 batch_job_resource_name 
 ) 
  
 puts 
  
 "Batch job with resource name ' 
 #{ 
 batch_job_resource_name 
 } 
 ' has " 
  
 \ 
  
 "finished. Now, printing its results..." 
  
 \ 
  
 # Gets all the results from running batch job and print their information. 
  
 batch_job_results 
  
 = 
  
 batch_job_service 
 . 
 list_batch_job_results 
 ( 
  
 resource_name 
 : 
  
 batch_job_resource_name 
 , 
  
 page_size 
 : 
  
 PAGE_SIZE 
 , 
  
 ) 
  
 batch_job_results 
 . 
 each 
  
 do 
  
 | 
 result 
 | 
  
 puts 
  
 "Batch job # 
 #{ 
 result 
 . 
 operation_index 
 } 
 has a status " 
  
 \ 
  
 " 
 #{ 
 result 
 . 
 status 
  
 ? 
  
 result 
 . 
 status 
 . 
 message 
  
 : 
  
 'N/A' 
 } 
 and response of type " 
  
 \ 
  
 " 
 #{ 
 result 
 . 
 mutate_operation_response 
  
 ? 
  
 result 
 . 
 mutate_operation_response 
 . 
 response 
  
 : 
  
 'N/A' 
 } 
 " 
  
 end 
 end 
 # Builds all operations for creating a complete campaign and return an array of 
 # their corresponding mutate operations. 
 def 
  
 build_all_operations 
 ( 
 client 
 , 
  
 customer_id 
 ) 
  
 mutate_operations 
  
 = 
  
 [] 
  
 # Creates a new campaign budget operation and add it to the array of mutate 
  
 # operations. 
  
 campaign_budget_operation 
  
 = 
  
 build_campaign_budget_operation 
 ( 
 client 
 , 
  
 customer_id 
 ) 
  
 mutate_operations 
 << 
 client 
 . 
 operation 
 . 
 mutate 
  
 do 
  
 | 
 mutate_op 
 | 
  
 mutate_op 
 . 
 campaign_budget_operation 
  
 = 
  
 campaign_budget_operation 
  
 end 
  
 # Creates new campaign operations and adds them to the array of mutate 
  
 # operations. 
  
 campaign_operations 
  
 = 
  
 build_campaign_operations 
 ( 
  
 client 
 , 
  
 customer_id 
 , 
  
 campaign_budget_operation 
 . 
 create 
 . 
 resource_name 
 ) 
  
 campaign_operations 
 . 
 each 
  
 do 
  
 | 
 op 
 | 
  
 mutate_operations 
 << 
 client 
 . 
 operation 
 . 
 mutate 
  
 do 
  
 | 
 mutate_op 
 | 
  
 mutate_op 
 . 
 campaign_operation 
  
 = 
  
 op 
  
 end 
  
 end 
  
 # Creates new campaign criterion operations and adds them to the array of 
  
 # mutate operations. 
  
 campaign_criterion_operations 
  
 = 
  
 build_campaign_criterion_operations 
 ( 
  
 client 
 , 
  
 campaign_operations 
 ) 
  
 campaign_criterion_operations 
 . 
 each 
  
 do 
  
 | 
 op 
 | 
  
 mutate_operations 
 << 
 client 
 . 
 operation 
 . 
 mutate 
  
 do 
  
 | 
 mutate_op 
 | 
  
 mutate_op 
 . 
 campaign_criterion_operation 
  
 = 
  
 op 
  
 end 
  
 end 
  
 # Creates new ad group operations and adds them to the array of mutate 
  
 # operations. 
  
 ad_group_operations 
  
 = 
  
 build_ad_group_operations 
 ( 
  
 client 
 , 
  
 customer_id 
 , 
  
 campaign_operations 
 ) 
  
 ad_group_operations 
 . 
 each 
  
 do 
  
 | 
 op 
 | 
  
 mutate_operations 
 << 
 client 
 . 
 operation 
 . 
 mutate 
  
 do 
  
 | 
 mutate_op 
 | 
  
 mutate_op 
 . 
 ad_group_operation 
  
 = 
  
 op 
  
 end 
  
 end 
  
 # Creates new ad group criterion operations and adds them to the array of 
  
 # mutate operations. 
  
 ad_group_criterion_operations 
  
 = 
  
 build_ad_group_criterion_operations 
 ( 
  
 client 
 , 
  
 ad_group_operations 
 ) 
  
 ad_group_criterion_operations 
 . 
 each 
  
 do 
  
 | 
 op 
 | 
  
 mutate_operations 
 << 
 client 
 . 
 operation 
 . 
 mutate 
  
 do 
  
 | 
 mutate_op 
 | 
  
 mutate_op 
 . 
 ad_group_criterion_operation 
  
 = 
  
 op 
  
 end 
  
 end 
  
 # Creates new ad group ad operations and adds them to the array of mutate 
  
 # operations. 
  
 ad_group_ad_operations 
  
 = 
  
 build_ad_group_ad_operations 
 ( 
  
 client 
 , 
  
 ad_group_operations 
 ) 
  
 ad_group_ad_operations 
 . 
 each 
  
 do 
  
 | 
 op 
 | 
  
 mutate_operations 
 << 
 client 
 . 
 operation 
 . 
 mutate 
  
 do 
  
 | 
 mutate_op 
 | 
  
 mutate_op 
 . 
 ad_group_ad_operation 
  
 = 
  
 op 
  
 end 
  
 end 
  
 mutate_operations 
 end 
 # Builds a new campaign budget operation for the specified customer ID. 
 def 
  
 build_campaign_budget_operation 
 ( 
 client 
 , 
  
 customer_id 
 ) 
  
 # Creates a campaign budget operation. 
  
 operation 
  
 = 
  
 client 
 . 
 operation 
 . 
 create_resource 
 . 
 campaign_budget 
  
 do 
  
 | 
 b 
 | 
  
 # Creates a resource name using the temporary ID. 
  
 b 
 . 
 resource_name 
  
 = 
  
 client 
 . 
 path 
 . 
 campaign_budget 
 ( 
  
 customer_id 
 , 
  
 get_next_temporary_id 
 ) 
  
 b 
 . 
 name 
  
 = 
  
 "Interplanetary Cruise Budget # 
 #{ 
 ( 
 Time 
 . 
 new 
 . 
 to_f 
  
 * 
  
 1000 
 ) 
 . 
 to_i 
 } 
 " 
  
 b 
 . 
 delivery_method 
  
 = 
  
 :STANDARD 
  
 b 
 . 
 amount_micros 
  
 = 
  
 5_000_000 
  
 end 
  
 operation 
 end 
 # Builds new campaign operations for the specified customer ID. 
 def 
  
 build_campaign_operations 
 ( 
 client 
 , 
  
 customer_id 
 , 
  
 campaign_budget_resource_name 
 ) 
  
 operations 
  
 = 
  
 [] 
  
 for 
  
 i 
  
 in 
  
 0 
 .. 
 NUMBER_OF_CAMPAIGNS_TO_ADD 
 - 
 1 
  
 # Creates a campaign. 
  
 campaign_id 
  
 = 
  
 get_next_temporary_id 
  
 operations 
 << 
 client 
 . 
 operation 
 . 
 create_resource 
 . 
 campaign 
  
 do 
  
 | 
 c 
 | 
  
 c 
 . 
 resource_name 
  
 = 
  
 client 
 . 
 path 
 . 
 campaign 
 ( 
 customer_id 
 , 
  
 campaign_id 
 ) 
  
 c 
 . 
 name 
  
 = 
  
 "Mutate job campaign # 
 #{ 
 ( 
 Time 
 . 
 new 
 . 
 to_f 
  
 * 
  
 1000 
 ) 
 . 
 to_i 
 } 
 . 
 #{ 
 campaign_id 
 } 
 " 
  
 c 
 . 
 advertising_channel_type 
  
 = 
  
 :SEARCH 
  
 # Recommendation: Set the campaign to PAUSED when creating it to prevent 
  
 # the ads from immediately serving. Set to ENABLED once you've added 
  
 # targeting and the ads are ready to serve. 
  
 c 
 . 
 status 
  
 = 
  
 :PAUSED 
  
 # Sets the bidding strategy and budget. 
  
 c 
 . 
 manual_cpc 
  
 = 
  
 client 
 . 
 resource 
 . 
 manual_cpc 
  
 c 
 . 
 campaign_budget 
  
 = 
  
 campaign_budget_resource_name 
  
 # Declare whether or not this campaign serves political ads targeting the EU. 
  
 # Valid values are CONTAINS_EU_POLITICAL_ADVERTISING and 
  
 # DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING. 
  
 c 
 . 
 contains_eu_political_advertising 
  
 = 
  
 :DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING 
  
 end 
  
 end 
  
 operations 
 end 
 # Builds new campaign criterion operations for creating negative campaign 
 # criteria (as keywords). 
 def 
  
 build_campaign_criterion_operations 
 ( 
 client 
 , 
  
 campaign_operations 
 ) 
  
 operations 
  
 = 
  
 [] 
  
 campaign_operations 
 . 
 each 
  
 do 
  
 | 
 op 
 | 
  
 operations 
 << 
 client 
 . 
 operation 
 . 
 create_resource 
 . 
 campaign_criterion 
  
 do 
  
 | 
 cc 
 | 
  
 cc 
 . 
 keyword 
  
 = 
  
 client 
 . 
 resource 
 . 
 keyword_info 
  
 do 
  
 | 
 k 
 | 
  
 k 
 . 
 text 
  
 = 
  
 "venus" 
  
 k 
 . 
 match_type 
  
 = 
  
 :BROAD 
  
 end 
  
 cc 
 . 
 negative 
  
 = 
  
 true 
  
 cc 
 . 
 campaign 
  
 = 
  
 op 
 . 
 create 
 . 
 resource_name 
  
 end 
  
 end 
  
 operations 
 end 
 # Builds new ad group operations for the specified customer ID. 
 def 
  
 build_ad_group_operations 
 ( 
 client 
 , 
  
 customer_id 
 , 
  
 campaign_operations 
 ) 
  
 operations 
  
 = 
  
 [] 
  
 campaign_operations 
 . 
 each 
  
 do 
  
 | 
 op 
 | 
  
 for 
  
 i 
  
 in 
  
 0 
 .. 
 NUMBER_OF_AD_GROUPS_TO_ADD 
 - 
 1 
  
 # Creates an ad group. 
  
 ad_group_id 
  
 = 
  
 get_next_temporary_id 
  
 operations 
 << 
 client 
 . 
 operation 
 . 
 create_resource 
 . 
 ad_group 
  
 do 
  
 | 
 ag 
 | 
  
 # Creates a resource name using the temporary ID. 
  
 ag 
 . 
 resource_name 
  
 = 
  
 client 
 . 
 path 
 . 
 ad_group 
 ( 
 customer_id 
 , 
  
 ad_group_id 
 ) 
  
 ag 
 . 
 name 
  
 = 
  
 "Mutate job ad group # 
 #{ 
 ( 
 Time 
 . 
 new 
 . 
 to_f 
  
 * 
  
 1000 
 ) 
 . 
 to_i 
 } 
 . 
 #{ 
 ad_group_id 
 } 
 " 
  
 ag 
 . 
 campaign 
  
 = 
  
 op 
 . 
 create 
 . 
 resource_name 
  
 ag 
 . 
 type 
  
 = 
  
 :SEARCH_STANDARD 
  
 ag 
 . 
 cpc_bid_micros 
  
 = 
  
 10_000_000 
  
 end 
  
 end 
  
 end 
  
 operations 
 end 
 # Builds new ad group criterion operations for creating keywords. 50% of 
 # keywords are created with some invalid characters to demonstrate how 
 # BatchJobService returns information about such errors. 
 def 
  
 build_ad_group_criterion_operations 
 ( 
 client 
 , 
  
 ad_group_operations 
 ) 
  
 operations 
  
 = 
  
 [] 
  
 ad_group_operations 
 . 
 each 
  
 do 
  
 | 
 op 
 | 
  
 for 
  
 i 
  
 in 
  
 0 
 .. 
 NUMBER_OF_KEYWORDS_TO_ADD 
 - 
 1 
  
 # Create a keyword text by making 50% of keywords invalid to demonstrate 
  
 # error handling. 
  
 keyword_text 
  
 = 
  
 "mars 
 #{ 
 i 
 } 
 " 
  
 if 
  
 i 
  
 % 
  
 2 
  
 == 
  
 0 
  
 keyword_text 
  
 += 
  
 "!!!" 
  
 end 
  
 # Creates an ad group criterion using the created keyword text. 
  
 operations 
 << 
 client 
 . 
 operation 
 . 
 create_resource 
 . 
 ad_group_criterion 
  
 do 
  
 | 
 agc 
 | 
  
 agc 
 . 
 keyword 
  
 = 
  
 client 
 . 
 resource 
 . 
 keyword_info 
  
 do 
  
 | 
 k 
 | 
  
 k 
 . 
 text 
  
 = 
  
 keyword_text 
  
 k 
 . 
 match_type 
  
 = 
  
 :BROAD 
  
 end 
  
 agc 
 . 
 ad_group 
  
 = 
  
 op 
 . 
 create 
 . 
 resource_name 
  
 agc 
 . 
 status 
  
 = 
  
 :ENABLED 
  
 end 
  
 end 
  
 end 
  
 operations 
 end 
 # Builds new ad group ad operations. 
 def 
  
 build_ad_group_ad_operations 
 ( 
 client 
 , 
  
 ad_group_operations 
 ) 
  
 operations 
  
 = 
  
 [] 
  
 ad_group_operations 
 . 
 each 
  
 do 
  
 | 
 op 
 | 
  
 operations 
 << 
 client 
 . 
 operation 
 . 
 create_resource 
 . 
 ad_group_ad 
  
 do 
  
 | 
 aga 
 | 
  
 aga 
 . 
 ad 
  
 = 
  
 client 
 . 
 resource 
 . 
 ad 
  
 do 
  
 | 
 ad 
 | 
  
 ad 
 . 
 expanded_text_ad 
  
 = 
  
 client 
 . 
 resource 
 . 
 expanded_text_ad_info 
  
 do 
  
 | 
 eta 
 | 
  
 eta 
 . 
 headline_part1 
  
 = 
  
 "Cruise to Mars # 
 #{ 
 ( 
 Time 
 . 
 new 
 . 
 to_f 
  
 * 
  
 1000 
 ) 
 . 
 to_i 
 } 
 " 
  
 eta 
 . 
 headline_part2 
  
 = 
  
 "Best Space Cruise Line" 
  
 eta 
 . 
 description 
  
 = 
  
 "Buy your tickets now!" 
  
 end 
  
 ad 
 . 
 final_urls 
 << 
 "http://www.example.com" 
  
 end 
  
 aga 
 . 
 ad_group 
  
 = 
  
 op 
 . 
 create 
 . 
 resource_name 
  
 aga 
 . 
 status 
  
 = 
  
 :PAUSED 
  
 end 
  
 end 
  
 operations 
 end 
 # Returns the next temporary ID and decrease it by one. 
 def 
  
 get_next_temporary_id 
  
 @temporary_id 
  
 ||= 
  
 0 
  
 @temporary_id 
  
 -= 
  
 1 
 end 
 if 
  
 __FILE__ 
  
 == 
  
 $0 
  
 NUMBER_OF_CAMPAIGNS_TO_ADD 
  
 = 
  
 2 
 ; 
  
 NUMBER_OF_AD_GROUPS_TO_ADD 
  
 = 
  
 2 
 ; 
  
 NUMBER_OF_KEYWORDS_TO_ADD 
  
 = 
  
 4 
 ; 
  
 PAGE_SIZE 
  
 = 
  
 1000 
  
 options 
  
 = 
  
 {} 
  
 OptionParser 
 . 
 new 
  
 do 
  
 | 
 opts 
 | 
  
 opts 
 . 
 banner 
  
 = 
  
 sprintf 
 ( 
 'Usage: %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 
 . 
 separator 
  
 '' 
  
 opts 
 . 
 separator 
  
 'Help:' 
  
 opts 
 . 
 on_tail 
 ( 
 '-h' 
 , 
  
 '--help' 
 , 
  
 'Show this message' 
 ) 
  
 do 
  
 puts 
  
 opts 
  
 exit 
  
 end 
  
 end 
 . 
 parse! 
  
 begin 
  
 add_complete_campaigns_using_batch_job 
 ( 
  
 options 
 . 
 fetch 
 ( 
 :customer_id 
 ) 
 . 
 tr 
 ( 
 "-" 
 , 
  
 "" 
 )) 
  
 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 
 ( 
 " 
 \t 
 On 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 
 ( 
 " 
 \t 
 Type: %s 
 \n\t 
 Code: %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 adds complete campaigns including campaign budgets, campaigns, 
 # ad groups and keywords using BatchJobService. 
 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::V21::Resources::BatchJob 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::CampaignBudget 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::Campaign 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::CampaignCriterion 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::AdGroup 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::AdGroupCriterion 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::AdGroupAd 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::Ad 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Common::ManualCpc 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Common::KeywordInfo 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Common::ExpandedTextAdInfo 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::BudgetDeliveryMethodEnum 
  
 qw(STANDARD) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::AdvertisingChannelTypeEnum 
  
 qw(SEARCH) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::CampaignStatusEnum 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::KeywordMatchTypeEnum 
  
 qw(BROAD) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::AdGroupTypeEnum 
  
 qw(SEARCH_STANDARD) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::AdGroupCriterionStatusEnum 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::AdGroupAdStatusEnum 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::EuPoliticalAdvertisingStatusEnum 
  
 qw(DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::BatchJobService::BatchJobOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::GoogleAdsService::MutateOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::CampaignBudgetService::CampaignBudgetOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::CampaignService::CampaignOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::CampaignCriterionService::CampaignCriterionOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::AdGroupService::AdGroupOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::AdGroupCriterionService::AdGroupCriterionOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::AdGroupAdService::AdGroupAdOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Utils::ResourceNames 
 ; 
 use 
  
 Getopt::Long 
  
 qw(:config auto_help) 
 ; 
 use 
  
 Pod::Usage 
 ; 
 use 
  
 Cwd 
  
 qw(abs_path) 
 ; 
 use 
  
 Data::Uniqid 
  
 qw(uniqid) 
 ; 
 use 
  
 constant 
  
 NUMBER_OF_CAMPAIGNS_TO_ADD 
  
 = 
>  
 2 
 ; 
 use 
  
 constant 
  
 NUMBER_OF_AD_GROUPS_TO_ADD 
  
 = 
>  
 2 
 ; 
 use 
  
 constant 
  
 NUMBER_OF_KEYWORDS_TO_ADD 
  
 = 
>  
 4 
 ; 
 use 
  
 constant 
  
 POLL_FREQUENCY_SECONDS 
  
 = 
>  
 1 
 ; 
 use 
  
 constant 
  
 POLL_TIMEOUT_SECONDS 
  
 = 
>  
 60 
 ; 
 use 
  
 constant 
  
 PAGE_SIZE 
  
 = 
>  
 1000 
 ; 
 # 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" 
 ; 
 sub 
  
 add_complete_campaigns_using_batch_job 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $batch_job_service 
  
 = 
  
 $api_client 
 - 
> BatchJobService 
 (); 
  
 my 
  
 $operation_service 
  
 = 
  
 $api_client 
 - 
> OperationService 
 (); 
  
 my 
  
 $batch_job_resource_name 
  
 = 
  
 create_batch_job 
 ( 
 $batch_job_service 
 , 
  
 $customer_id 
 ); 
  
 add_all_batch_job_operations 
 ( 
 $batch_job_service 
 , 
  
 $customer_id 
 , 
  
 $batch_job_resource_name 
 ); 
  
 my 
  
 $batch_job_lro 
  
 = 
  
 run_batch_job 
 ( 
 $batch_job_service 
 , 
  
 $batch_job_resource_name 
 ); 
  
 poll_batch_job 
 ( 
 $operation_service 
 , 
  
 $batch_job_lro 
 ); 
  
 fetch_and_print_results 
 ( 
 $batch_job_service 
 , 
  
 $batch_job_resource_name 
 ); 
  
 return 
  
 1 
 ; 
 } 
 # Creates a new batch job for the specified customer ID. 
 sub 
  
 create_batch_job 
  
 { 
  
 my 
  
 ( 
 $batch_job_service 
 , 
  
 $customer_id 
 ) 
  
 = 
  
 @_ 
 ; 
  
 # Create a batch job operation. 
  
 my 
  
 $batch_job_operation 
  
 = 
  
 Google::Ads::GoogleAds::V21::Services::BatchJobService:: 
 BatchJobOperation 
 - 
>  
 new 
 ({ 
 create 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Resources:: 
 BatchJob 
 - 
> new 
 ({})}); 
  
 my 
  
 $batch_job_resource_name 
  
 = 
  
 $batch_job_service 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operation 
  
 = 
>  
 $batch_job_operation 
  
 }) 
 - 
> { 
 result 
 }{ 
 resourceName 
 }; 
  
 printf 
  
 "Created a batch job with resource name: '%s'.\n" 
 , 
  
 $batch_job_resource_name 
 ; 
  
 return 
  
 $batch_job_resource_name 
 ; 
 } 
 # Adds all batch job operations to the batch job. As this is the first time for 
 # this batch job, pass null as a sequence token. The response will contain the 
 # next sequence token that you can use to upload more operations in the future. 
 sub 
  
 add_all_batch_job_operations 
  
 { 
  
 my 
  
 ( 
 $batch_job_service 
 , 
  
 $customer_id 
 , 
  
 $batch_job_resource_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $add_batch_job_operations_response 
  
 = 
  
 $batch_job_service 
 - 
> add_operations 
 ({ 
  
 resourceName 
  
 = 
>  
 $batch_job_resource_name 
 , 
  
 sequenceToken 
  
 = 
>  
 undef 
 , 
  
 mutateOperations 
  
 = 
>  
 build_all_operations 
 ( 
 $customer_id 
 )}); 
  
 printf 
  
 "%d batch operations have been added so far.\n" 
 , 
  
 $add_batch_job_operations_response 
 - 
> { 
 totalOperations 
 }; 
  
 # You can use this next sequence token for calling add_operations() next time. 
  
 printf 
  
 "Next sequence token for adding next operations is '%s'.\n" 
 , 
  
 $add_batch_job_operations_response 
 - 
> { 
 nextSequenceToken 
 }; 
 } 
 # Requests the API to run the batch job for executing all uploaded batch job 
 # operations. 
 sub 
  
 run_batch_job 
  
 { 
  
 my 
  
 ( 
 $batch_job_service 
 , 
  
 $batch_job_resource_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $batch_job_lro 
  
 = 
  
 $batch_job_service 
 - 
> run 
 ({ 
 resourceName 
  
 = 
>  
 $batch_job_resource_name 
 }); 
  
 printf 
  
 "Batch job with resource name '%s' has been executed.\n" 
 , 
  
 $batch_job_resource_name 
 ; 
  
 return 
  
 $batch_job_lro 
 ; 
 } 
 # Polls the server until the batch job execution finishes by setting the initial 
 # poll delay time and the total time to wait before time-out. 
 sub 
  
 poll_batch_job 
  
 { 
  
 my 
  
 ( 
 $operation_service 
 , 
  
 $batch_job_lro 
 ) 
  
 = 
  
 @_ 
 ; 
  
 $operation_service 
 - 
> poll_until_done 
 ({ 
  
 name 
  
 = 
>  
 $batch_job_lro 
 - 
> { 
 name 
 }, 
  
 pollFrequencySeconds 
  
 = 
>  
 POLL_FREQUENCY_SECONDS 
 , 
  
 pollTimeoutSeconds 
  
 = 
>  
 POLL_TIMEOUT_SECONDS 
  
 }); 
 } 
 # Prints all the results from running the batch job. 
 sub 
  
 fetch_and_print_results 
  
 { 
  
 my 
  
 ( 
 $batch_job_service 
 , 
  
 $batch_job_resource_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 printf 
  
 "Batch job with resource name '%s' has finished. " 
  
 . 
  
 "Now, printing its results...\n" 
 , 
  
 $batch_job_resource_name 
 ; 
  
 # Get all the results from running batch job and print their information. 
  
 my 
  
 $list_batch_job_results_response 
  
 = 
  
 $batch_job_service 
 - 
> list_results 
 ({ 
  
 resourceName 
  
 = 
>  
 $batch_job_resource_name 
 , 
  
 pageSize 
  
 = 
>  
 PAGE_SIZE 
  
 }); 
  
 foreach 
  
 my 
  
 $batch_job_result 
  
 ( 
 @ 
 { 
 $list_batch_job_results_response 
 - 
> { 
 results 
 }}) 
  
 { 
  
 printf 
  
 "Batch job #%d has a status '%s' and response of type '%s'.\n" 
 , 
  
 $batch_job_result 
 - 
> { 
 operationIndex 
 }, 
  
 $batch_job_result 
 - 
> { 
 status 
 } 
  
 ? 
  
 $batch_job_result 
 - 
> { 
 status 
 }{ 
 message 
 } 
  
 : 
  
 "N/A" 
 , 
  
 $batch_job_result 
 - 
> { 
 mutateOperationResponse 
 } 
  
 ? 
  
 [ 
 keys 
  
 % 
 { 
 $batch_job_result 
 - 
> { 
 mutateOperationResponse 
 }}] 
 - 
> [ 
 0 
 ] 
  
 : 
  
 "N/A" 
 ; 
  
 } 
 } 
 # Builds all operations for creating a complete campaign and return an array of 
 # their corresponding mutate operations. 
 sub 
  
 build_all_operations 
  
 { 
  
 my 
  
 $customer_id 
  
 = 
  
 shift 
 ; 
  
 my 
  
 $mutate_operations 
  
 = 
  
 [] 
 ; 
  
 # Create a new campaign budget operation and add it to the array of mutate operations. 
  
 my 
  
 $campaign_budget_operation 
  
 = 
  
 build_campaign_budget_operation 
 ( 
 $customer_id 
 ); 
  
 push 
  
 @$mutate_operations 
 , 
  
 Google::Ads::GoogleAds::V21::Services::GoogleAdsService:: 
 MutateOperation 
 - 
>  
 new 
 ({ 
  
 campaignBudgetOperation 
  
 = 
>  
 $campaign_budget_operation 
  
 }); 
  
 # Create new campaign operations and add them to the array of mutate operations. 
  
 my 
  
 $campaign_operations 
  
 = 
  
 build_campaign_operations 
 ( 
 $customer_id 
 , 
  
 $campaign_budget_operation 
 - 
> { 
 create 
 }{ 
 resourceName 
 }); 
  
 push 
  
 @$mutate_operations 
 , 
  
 map 
  
 { 
  
 Google::Ads::GoogleAds::V21::Services::GoogleAdsService:: 
 MutateOperation 
 - 
>  
 new 
 ({ 
  
 campaignOperation 
  
 = 
>  
 $_ 
  
 }) 
  
 } 
  
 @$campaign_operations 
 ; 
  
 # Create new campaign criterion operations and add them to the array of mutate 
  
 # operations. 
  
 my 
  
 $campaign_criterion_operations 
  
 = 
  
 build_campaign_criterion_operations 
 ( 
 $campaign_operations 
 ); 
  
 push 
  
 @$mutate_operations 
 , 
  
 map 
  
 { 
  
 Google::Ads::GoogleAds::V21::Services::GoogleAdsService:: 
 MutateOperation 
 - 
>  
 new 
 ({ 
  
 campaignCriterionOperation 
  
 = 
>  
 $_ 
  
 }) 
  
 } 
  
 @$campaign_criterion_operations 
 ; 
  
 # Create new ad group operations and add them to the array of mutate operations. 
  
 my 
  
 $ad_group_operations 
  
 = 
  
 build_ad_group_operations 
 ( 
 $customer_id 
 , 
  
 $campaign_operations 
 ); 
  
 push 
  
 @$mutate_operations 
 , 
  
 map 
  
 { 
  
 Google::Ads::GoogleAds::V21::Services::GoogleAdsService:: 
 MutateOperation 
 - 
>  
 new 
 ({ 
  
 adGroupOperation 
  
 = 
>  
 $_ 
  
 }) 
  
 } 
  
 @$ad_group_operations 
 ; 
  
 # Create new ad group criterion operations and add them to the array of mutate 
  
 # operations. 
  
 my 
  
 $ad_group_criterion_operations 
  
 = 
  
 build_ad_group_criterion_operations 
 ( 
 $ad_group_operations 
 ); 
  
 push 
  
 @$mutate_operations 
 , 
  
 map 
  
 { 
  
 Google::Ads::GoogleAds::V21::Services::GoogleAdsService:: 
 MutateOperation 
 - 
>  
 new 
 ({ 
  
 adGroupCriterionOperation 
  
 = 
>  
 $_ 
  
 }) 
  
 } 
  
 @$ad_group_criterion_operations 
 ; 
  
 # Create new ad group ad operations and add them to the array of mutate operations. 
  
 my 
  
 $ad_group_ad_operations 
  
 = 
  
 build_ad_group_ad_operations 
 ( 
 $ad_group_operations 
 ); 
  
 push 
  
 @$mutate_operations 
 , 
  
 map 
  
 { 
  
 Google::Ads::GoogleAds::V21::Services::GoogleAdsService:: 
 MutateOperation 
 - 
>  
 new 
 ({ 
  
 adGroupAdOperation 
  
 = 
>  
 $_ 
  
 }) 
  
 } 
  
 @$ad_group_ad_operations 
 ; 
  
 return 
  
 $mutate_operations 
 ; 
 } 
 # Builds a new campaign budget operation for the specified customer ID. 
 sub 
  
 build_campaign_budget_operation 
  
 { 
  
 my 
  
 $customer_id 
  
 = 
  
 shift 
 ; 
  
 # Create a campaign budget operation. 
  
 return 
  
 Google::Ads::GoogleAds::V21::Services::CampaignBudgetService:: 
 CampaignBudgetOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Resources:: 
 CampaignBudget 
 - 
> new 
 ({ 
  
 # Create a resource name using the temporary ID. 
  
 resourceName 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Utils::ResourceNames:: 
 campaign_budget 
 ( 
  
 $customer_id 
 , 
  
 next_temporary_id 
 () 
  
 ), 
  
 name 
  
 = 
>  
 "Interplanetary Cruise Budget #" 
  
 . 
  
 uniqid 
 (), 
  
 deliveryMethod 
  
 = 
>  
 STANDARD 
 , 
  
 amountMicros 
  
 = 
>  
 5000000 
  
 })}); 
 } 
 # Builds new campaign operations for the specified customer ID. 
 sub 
  
 build_campaign_operations 
  
 { 
  
 my 
  
 ( 
 $customer_id 
 , 
  
 $campaign_budget_resource_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $campaign_operations 
  
 = 
  
 [] 
 ; 
  
 for 
  
 ( 
 my 
  
 $i 
  
 = 
  
 0 
  
 ; 
  
 $i 
 < 
 NUMBER_OF_CAMPAIGNS_TO_ADD 
  
 ; 
  
 $i 
 ++ 
 ) 
  
 { 
  
 # Create a campaign. 
  
 my 
  
 $campaign_id 
  
 = 
  
 next_temporary_id 
 (); 
  
 my 
  
 $campaign 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 Campaign 
 - 
> new 
 ({ 
  
 # Create a resource name using the temporary ID. 
  
 resourceName 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Utils::ResourceNames:: 
 campaign 
 ( 
  
 $customer_id 
 , 
  
 $campaign_id 
  
 ), 
  
 name 
  
 = 
>  
 sprintf 
 ( 
 "Batch job campaign #%s.%d" 
 , 
  
 uniqid 
 (), 
  
 $campaign_id 
 ), 
  
 advertisingChannelType 
  
 = 
>  
 SEARCH 
 , 
  
 # Recommendation: Set the campaign to PAUSED when creating it to prevent 
  
 # the ads from immediately serving. Set to ENABLED once you've added 
  
 # targeting and the ads are ready to serve. 
  
 status 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Enums::CampaignStatusEnum:: 
 PAUSED 
 , 
  
 # Set the bidding strategy and budget. 
  
 manualCpc 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Common:: 
 ManualCpc 
 - 
> new 
 (), 
  
 campaignBudget 
  
 = 
>  
 $campaign_budget_resource_name 
 , 
  
 # Declare whether or not this campaign serves political ads targeting the EU. 
  
 # Valid values are CONTAINS_EU_POLITICAL_ADVERTISING and 
  
 # DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING. 
  
 containsEuPoliticalAdvertising 
  
 = 
>  
 DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING 
  
 }); 
  
 # Create a campaign operation and add it to the operations list. 
  
 push 
  
 @$campaign_operations 
 , 
  
 Google::Ads::GoogleAds::V21::Services::CampaignService:: 
 CampaignOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $campaign 
  
 }); 
  
 } 
  
 return 
  
 $campaign_operations 
 ; 
 } 
 # Builds new campaign criterion operations for creating negative campaign criteria 
 # (as keywords). 
 sub 
  
 build_campaign_criterion_operations 
  
 { 
  
 my 
  
 $campaign_operations 
  
 = 
  
 shift 
 ; 
  
 my 
  
 $campaign_criterion_operations 
  
 = 
  
 [] 
 ; 
  
 foreach 
  
 my 
  
 $campaign_operation 
  
 ( 
 @$campaign_operations 
 ) 
  
 { 
  
 # Create a campaign criterion. 
  
 my 
  
 $campaign_criterion 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 CampaignCriterion 
 - 
> new 
 ({ 
  
 keyword 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Common:: 
 KeywordInfo 
 - 
> new 
 ({ 
  
 text 
  
 = 
>  
 "venus" 
 , 
  
 matchType 
  
 = 
>  
 BROAD 
  
 } 
  
 ), 
  
 # Set the campaign criterion as a negative criterion. 
  
 negative 
  
 = 
>  
 "true" 
 , 
  
 campaign 
  
 = 
>  
 $campaign_operation 
 - 
> { 
 create 
 }{ 
 resourceName 
 }}); 
  
 # Create a campaign criterion operation and add it to the operations list. 
  
 push 
  
 @$campaign_criterion_operations 
 , 
  
 Google::Ads::GoogleAds::V21::Services::CampaignCriterionService:: 
 CampaignCriterionOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $campaign_criterion 
  
 }); 
  
 } 
  
 return 
  
 $campaign_criterion_operations 
 ; 
 } 
 # Builds new ad group operations for the specified customer ID. 
 sub 
  
 build_ad_group_operations 
  
 { 
  
 my 
  
 ( 
 $customer_id 
 , 
  
 $campaign_operations 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $ad_group_operations 
  
 = 
  
 [] 
 ; 
  
 foreach 
  
 my 
  
 $campaign_operation 
  
 ( 
 @$campaign_operations 
 ) 
  
 { 
  
 for 
  
 ( 
 my 
  
 $i 
  
 = 
  
 0 
  
 ; 
  
 $i 
 < 
 NUMBER_OF_AD_GROUPS_TO_ADD 
  
 ; 
  
 $i 
 ++ 
 ) 
  
 { 
  
 # Create an ad group. 
  
 my 
  
 $ad_group_id 
  
 = 
  
 next_temporary_id 
 (); 
  
 my 
  
 $ad_group 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 AdGroup 
 - 
> new 
 ({ 
  
 # Create a resource name using the temporary ID. 
  
 resourceName 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Utils::ResourceNames:: 
 ad_group 
 ( 
  
 $customer_id 
 , 
  
 $ad_group_id 
  
 ), 
  
 name 
  
 = 
>  
 sprintf 
 ( 
 "Batch job ad group #%s.%d" 
 , 
  
 uniqid 
 (), 
  
 $ad_group_id 
 ), 
  
 campaign 
  
 = 
>  
 $campaign_operation 
 - 
> { 
 create 
 }{ 
 resourceName 
 }, 
  
 type 
  
 = 
>  
 SEARCH_STANDARD 
 , 
  
 cpcBidMicros 
  
 = 
>  
 10000000 
  
 }); 
  
 # Create an ad group operation and add it to the operations list. 
  
 push 
  
 @$ad_group_operations 
 , 
  
 Google::Ads::GoogleAds::V21::Services::AdGroupService:: 
 AdGroupOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $ad_group 
  
 }); 
  
 } 
  
 } 
  
 return 
  
 $ad_group_operations 
 ; 
 } 
 # Builds new ad group criterion operations for creating keywords. 50% of keywords 
 # are created with some invalid characters to demonstrate how BatchJobService 
 # returns information about such errors. 
 sub 
  
 build_ad_group_criterion_operations 
  
 { 
  
 my 
  
 $ad_group_operations 
  
 = 
  
 shift 
 ; 
  
 my 
  
 $ad_group_criterion_operations 
  
 = 
  
 [] 
 ; 
  
 foreach 
  
 my 
  
 $ad_group_operation 
  
 ( 
 @$ad_group_operations 
 ) 
  
 { 
  
 for 
  
 ( 
 my 
  
 $i 
  
 = 
  
 0 
  
 ; 
  
 $i 
 < 
 NUMBER_OF_KEYWORDS_TO_ADD 
  
 ; 
  
 $i 
 ++ 
 ) 
  
 { 
  
 # Create a keyword text by making 50% of keywords invalid to demonstrate 
  
 # error handling. 
  
 my 
  
 $keyword_text 
  
 = 
  
 "mars$i" 
 ; 
  
 if 
  
 ( 
 $i 
  
 % 
  
 2 
  
 == 
  
 0 
 ) 
  
 { 
  
 $keyword_text 
  
 = 
  
 $keyword_text 
  
 . 
  
 '!!!' 
 ; 
  
 } 
  
 # Create an ad group criterion using the created keyword text. 
  
 my 
  
 $ad_group_criterion 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 AdGroupCriterion 
 - 
> new 
 ({ 
  
 keyword 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Common:: 
 KeywordInfo 
 - 
> new 
 ({ 
  
 text 
  
 = 
>  
 $keyword_text 
 , 
  
 matchType 
  
 = 
>  
 BROAD 
  
 } 
  
 ), 
  
 adGroup 
  
 = 
>  
 $ad_group_operation 
 - 
> { 
 create 
 }{ 
 resourceName 
 }, 
  
 status 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Enums::AdGroupCriterionStatusEnum:: 
 ENABLED 
  
 }); 
  
 # Create an ad group criterion operation and add it to the operations list. 
  
 push 
  
 @$ad_group_criterion_operations 
 , 
  
 Google::Ads::GoogleAds::V21::Services::AdGroupCriterionService:: 
 AdGroupCriterionOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $ad_group_criterion 
  
 }); 
  
 } 
  
 } 
  
 return 
  
 $ad_group_criterion_operations 
 ; 
 } 
 # Builds new ad group ad operations. 
 sub 
  
 build_ad_group_ad_operations 
  
 { 
  
 my 
  
 $ad_group_operations 
  
 = 
  
 shift 
 ; 
  
 my 
  
 $ad_group_ad_operations 
  
 = 
  
 [] 
 ; 
  
 foreach 
  
 my 
  
 $ad_group_operation 
  
 ( 
 @$ad_group_operations 
 ) 
  
 { 
  
 # Create an ad group ad. 
  
 my 
  
 $ad_group_ad 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 AdGroupAd 
 - 
> new 
 ({ 
  
 # Create the expanded text ad info. 
  
 ad 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Resources:: 
 Ad 
 - 
> new 
 ({ 
  
 # Set the expanded text ad info on an ad. 
  
 expandedTextAd 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Common:: 
 ExpandedTextAdInfo 
 - 
> new 
 ({ 
  
 headlinePart1 
  
 = 
>  
 "Cruise to Mars #" 
  
 . 
  
 uniqid 
 (), 
  
 headlinePart2 
  
 = 
>  
 "Best Space Cruise Line" 
 , 
  
 description 
  
 = 
>  
 "Buy your tickets now!" 
  
 } 
  
 ), 
  
 finalUrls 
  
 = 
>  
 "http://www.example.com" 
 , 
  
 } 
  
 ), 
  
 adGroup 
  
 = 
>  
 $ad_group_operation 
 - 
> { 
 create 
 }{ 
 resourceName 
 }, 
  
 status 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Enums::AdGroupAdStatusEnum:: 
 PAUSED 
  
 }); 
  
 # Create an ad group ad operation and add it to the operations list. 
  
 push 
  
 @$ad_group_ad_operations 
 , 
  
 Google::Ads::GoogleAds::V21::Services::AdGroupAdService:: 
 AdGroupAdOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $ad_group_ad 
  
 }); 
  
 } 
  
 return 
  
 $ad_group_ad_operations 
 ; 
 } 
 # Specifies a decreasing negative number for temporary IDs. 
 # Returns -1, -2, -3, etc. on subsequent calls. 
 sub 
  
 next_temporary_id 
  
 { 
  
 our 
  
 $temporary_id 
  
 ||= 
  
 0 
 ; 
  
 $temporary_id 
  
 -= 
  
 1 
 ; 
 } 
 # 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 
 ( 
 1 
 ); 
 # Parameters passed on the command line will override any parameters set in code. 
 GetOptions 
 ( 
 "customer_id=s" 
  
 = 
>  
 \ 
 $customer_id 
 ); 
 # 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 
 ); 
 # Call the example. 
 add_complete_campaigns_using_batch_job 
 ( 
 $api_client 
 , 
  
 $customer_id 
  
 =~ 
  
 s/-//g 
 r 
 ); 
 =pod 
 =head1 NAME 
 add_complete_campaigns_using_batch_job 
 =head1 DESCRIPTION 
 This example adds complete campaigns including campaign budgets, campaigns, ad groups 
 and keywords using BatchJobService. 
 =head1 SYNOPSIS 
 add_complete_campaigns_using_batch_job.pl [options] 
 -help                       Show the help message. 
 -customer_id                The Google Ads customer ID. 
 =cut 
  
  
Design a Mobile Site
View Site in Mobile | Classic
Share by: