Add Ad Customizer

Java

 // 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. 
 package 
  
 com.google.ads.googleads.examples.advancedoperations 
 ; 
 import static 
  
 com.google.ads.googleads.examples.utils.CodeSampleHelper.getShortPrintableDateTime 
 ; 
 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.AdTextAsset 
 ; 
 import 
  
 com.google.ads.googleads.v21.common.CustomizerValue 
 ; 
 import 
  
 com.google.ads.googleads.v21.common.ResponsiveSearchAdInfo 
 ; 
 import 
  
 com.google.ads.googleads.v21.enums.CustomizerAttributeTypeEnum.CustomizerAttributeType 
 ; 
 import 
  
 com.google.ads.googleads.v21.enums.ServedAssetFieldTypeEnum.ServedAssetFieldType 
 ; 
 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.AdGroupAd 
 ; 
 import 
  
 com.google.ads.googleads.v21.resources.AdGroupCustomizer 
 ; 
 import 
  
 com.google.ads.googleads.v21.resources.CustomizerAttribute 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.AdGroupAdOperation 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.AdGroupAdServiceClient 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.AdGroupCustomizerOperation 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.AdGroupCustomizerServiceClient 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.CustomizerAttributeOperation 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.CustomizerAttributeServiceClient 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.MutateAdGroupAdResult 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.MutateAdGroupAdsResponse 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.MutateAdGroupCustomizerResult 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.MutateAdGroupCustomizersResponse 
 ; 
 import 
  
 com.google.ads.googleads.v21.services.MutateCustomizerAttributesResponse 
 ; 
 import 
  
 com.google.ads.googleads.v21.utils.ResourceNames 
 ; 
 import 
  
 com.google.common.collect.ImmutableList 
 ; 
 import 
  
 java.io.FileNotFoundException 
 ; 
 import 
  
 java.io.IOException 
 ; 
 import 
  
 java.util.ArrayList 
 ; 
 import 
  
 java.util.List 
 ; 
 /** 
 * This code example adds two ad customizer attributes and associates them with the ad group. Then 
 * it adds an ad that uses the ad customizer attributes to populate dynamic data. 
 */ 
 public 
  
 class 
 AddAdCustomizer 
  
 { 
  
 // We're doing only searches by resource_name in this example, we can set page size = 1. 
  
 private 
  
 static 
  
 class 
 AddAdCustomizerParams 
  
 extends 
  
 CodeSampleParams 
  
 { 
  
 @Parameter 
 ( 
 names 
  
 = 
  
 ArgumentNames 
 . 
 CUSTOMER_ID 
 , 
  
 required 
  
 = 
  
 true 
 ) 
  
 private 
  
 Long 
  
 customerId 
 ; 
  
 @Parameter 
 ( 
 names 
  
 = 
  
 ArgumentNames 
 . 
 AD_GROUP_ID 
 , 
  
 required 
  
 = 
  
 true 
 ) 
  
 private 
  
 Long 
  
 adGroupId 
 ; 
  
 } 
  
 public 
  
 static 
  
 void 
  
 main 
 ( 
 String 
 [] 
  
 args 
 ) 
  
 throws 
  
 IOException 
  
 { 
  
 AddAdCustomizerParams 
  
 params 
  
 = 
  
 new 
  
 AddAdCustomizerParams 
 (); 
  
 if 
  
 ( 
 ! 
 params 
 . 
 parseArguments 
 ( 
 args 
 )) 
  
 { 
  
 // Either pass the required parameters for this example on the command line, or insert them 
  
 // into the code here. See the parameter class definition above for descriptions. 
  
 params 
 . 
 customerId 
  
 = 
  
 Long 
 . 
 parseLong 
 ( 
 "INSERT_CUSTOMER_ID_HERE" 
 ); 
  
 params 
 . 
 adGroupId 
  
 = 
  
 Long 
 . 
 parseLong 
 ( 
 "INSERT_AD_GROUP_ID_HERE" 
 ); 
  
 } 
  
 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 
  
 AddAdCustomizer 
 (). 
 runExample 
 ( 
 googleAdsClient 
 , 
  
 params 
 . 
 customerId 
 , 
  
 params 
 . 
 adGroupId 
 ); 
  
 } 
  
 catch 
  
 ( 
 GoogleAdsException 
  
 gae 
 ) 
  
 { 
  
 // GoogleAdsException is the base class for most exceptions thrown by an API request. 
  
 // Instances of this exception have a message and a GoogleAdsFailure that contains a 
  
 // collection of GoogleAdsErrors that indicate the underlying causes of the 
  
 // GoogleAdsException. 
  
 System 
 . 
 err 
 . 
 printf 
 ( 
  
 "Request ID %s failed due to GoogleAdsException. Underlying errors:%n" 
 , 
  
 gae 
 . 
 getRequestId 
 ()); 
  
 int 
  
 i 
  
 = 
  
 0 
 ; 
  
 for 
  
 ( 
 GoogleAdsError 
  
 googleAdsError 
  
 : 
  
 gae 
 . 
 getGoogleAdsFailure 
 (). 
 getErrorsList 
 ()) 
  
 { 
  
 System 
 . 
 err 
 . 
 printf 
 ( 
 "  Error %d: %s%n" 
 , 
  
 i 
 ++ 
 , 
  
 googleAdsError 
 ); 
  
 } 
  
 System 
 . 
 exit 
 ( 
 1 
 ); 
  
 } 
  
 } 
  
 /** 
 * Runs the example. 
 * 
 * @param googleAdsClient the Google Ads API client. 
 * @param customerId the ID of the customer. 
 * @param adGroupId the ID of the adGroup to associate the customizers with. 
 * @throws GoogleAdsException if an API request failed with one or more service errors. 
 */ 
  
 private 
  
 void 
  
 runExample 
 ( 
 GoogleAdsClient 
  
 googleAdsClient 
 , 
  
 long 
  
 customerId 
 , 
  
 long 
  
 adGroupId 
 ) 
  
 { 
  
 String 
  
 stringCustomizerName 
  
 = 
  
 "Planet_" 
  
 + 
  
 getShortPrintableDateTime 
 (); 
  
 String 
  
 priceCustomizerName 
  
 = 
  
 "Price_" 
  
 + 
  
 getShortPrintableDateTime 
 (); 
  
 // Creates ad customizer attributes. 
  
 String 
  
 textCustomizerAttributeResourceName 
  
 = 
  
 createTextCustomizerAttribute 
 ( 
 googleAdsClient 
 , 
  
 customerId 
 , 
  
 stringCustomizerName 
 ); 
  
 String 
  
 priceCustomizerAttributeResourceName 
  
 = 
  
 createPriceCustomizerAttribute 
 ( 
 googleAdsClient 
 , 
  
 customerId 
 , 
  
 priceCustomizerName 
 ); 
  
 // Links the customizer attributes. 
  
 linkCustomizerAttributes 
 ( 
  
 googleAdsClient 
 , 
  
 customerId 
 , 
  
 adGroupId 
 , 
  
 textCustomizerAttributeResourceName 
 , 
  
 priceCustomizerAttributeResourceName 
 ); 
  
 // Creates an ad with the customizations provided by the ad customizer attributes. 
  
 createAdWithCustomizations 
 ( 
  
 googleAdsClient 
 , 
  
 customerId 
 , 
  
 adGroupId 
 , 
  
 stringCustomizerName 
 , 
  
 priceCustomizerName 
 ); 
  
 } 
  
 /** 
 * Creates a text customizer attribute and returns its resource name. 
 * 
 * @param googleAdsClient the Google Ads API client. 
 * @param customerId the client customer ID. 
 * @param customizerName the name of the customizer to create. 
 * @return the attributes of the feed. 
 */ 
  
 private 
  
 String 
  
 createTextCustomizerAttribute 
 ( 
  
 GoogleAdsClient 
  
 googleAdsClient 
 , 
  
 long 
  
 customerId 
 , 
  
 String 
  
 customizerName 
 ) 
  
 { 
  
 // Creates a text customizer attribute. The customizer attribute name is arbitrary and will be 
  
 // used as a placeholder in the ad text fields. 
  
 CustomizerAttribute 
  
 textAttribute 
  
 = 
  
 CustomizerAttribute 
 . 
 newBuilder 
 () 
  
 . 
 setName 
 ( 
 customizerName 
 ) 
  
 . 
 setType 
 ( 
 CustomizerAttributeType 
 . 
 TEXT 
 ) 
  
 . 
 build 
 (); 
  
 CustomizerAttributeOperation 
  
 operation 
  
 = 
  
 CustomizerAttributeOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 textAttribute 
 ). 
 build 
 (); 
  
 try 
  
 ( 
 CustomizerAttributeServiceClient 
  
 customizerAttributeServiceClient 
  
 = 
  
 googleAdsClient 
 . 
 getLatestVersion 
 (). 
 createCustomizerAttributeServiceClient 
 ()) 
  
 { 
  
 MutateCustomizerAttributesResponse 
  
 response 
  
 = 
  
 customizerAttributeServiceClient 
 . 
 mutateCustomizerAttributes 
 ( 
  
 Long 
 . 
 toString 
 ( 
 customerId 
 ), 
  
 ImmutableList 
 . 
 of 
 ( 
 operation 
 )); 
  
 String 
  
 customizerAttributeResourceName 
  
 = 
  
 response 
 . 
 getResults 
 ( 
 0 
 ). 
 getResourceName 
 (); 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "Added text customizer attribute with resource name '%s'.%n" 
 , 
  
 customizerAttributeResourceName 
 ); 
  
 return 
  
 customizerAttributeResourceName 
 ; 
  
 } 
  
 } 
  
 /** 
 * Creates a price customizer attribute and returns its resource name. 
 * 
 * @param googleAdsClient the Google Ads API client. 
 * @param customerId the client customer ID. 
 * @param customizerName the name of the customizer to create. 
 * @return the attributes of the feed. 
 */ 
  
 private 
  
 String 
  
 createPriceCustomizerAttribute 
 ( 
  
 GoogleAdsClient 
  
 googleAdsClient 
 , 
  
 long 
  
 customerId 
 , 
  
 String 
  
 customizerName 
 ) 
  
 { 
  
 // Creates a price customizer attribute. The customizer attribute name is arbitrary and will be 
  
 // used as a placeholder in the ad text fields. 
  
 CustomizerAttribute 
  
 priceAttribute 
  
 = 
  
 CustomizerAttribute 
 . 
 newBuilder 
 () 
  
 . 
 setName 
 ( 
 customizerName 
 ) 
  
 . 
 setType 
 ( 
 CustomizerAttributeType 
 . 
 PRICE 
 ) 
  
 . 
 build 
 (); 
  
 CustomizerAttributeOperation 
  
 operation 
  
 = 
  
 CustomizerAttributeOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 priceAttribute 
 ). 
 build 
 (); 
  
 try 
  
 ( 
 CustomizerAttributeServiceClient 
  
 customizerAttributeServiceClient 
  
 = 
  
 googleAdsClient 
 . 
 getLatestVersion 
 (). 
 createCustomizerAttributeServiceClient 
 ()) 
  
 { 
  
 MutateCustomizerAttributesResponse 
  
 response 
  
 = 
  
 customizerAttributeServiceClient 
 . 
 mutateCustomizerAttributes 
 ( 
  
 Long 
 . 
 toString 
 ( 
 customerId 
 ), 
  
 ImmutableList 
 . 
 of 
 ( 
 operation 
 )); 
  
 String 
  
 customizerAttributeResourceName 
  
 = 
  
 response 
 . 
 getResults 
 ( 
 0 
 ). 
 getResourceName 
 (); 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "Added price customizer attribute with resource name '%s'.%n" 
 , 
  
 customizerAttributeResourceName 
 ); 
  
 return 
  
 customizerAttributeResourceName 
 ; 
  
 } 
  
 } 
  
 /** 
 * Restricts the ad customizer attributes to work only with a specific ad group; this prevents the 
 * customizer attributes from being used elsewhere and makes sure they are used only for 
 * customizing a specific ad group. 
 * 
 * @param googleAdsClient the Google Ads client. 
 * @param customerId the client customer ID. 
 * @param adGroupId the ad group ID to bind the customizer attributes to. 
 * @param textCustomizerAttributeResourceName the resource name of the text customizer attribute. 
 * @param priceCustomizerAttributeResourceName the resource name of the price customizer 
 *     attribute. 
 */ 
  
 private 
  
 void 
  
 linkCustomizerAttributes 
 ( 
  
 GoogleAdsClient 
  
 googleAdsClient 
 , 
  
 long 
  
 customerId 
 , 
  
 long 
  
 adGroupId 
 , 
  
 String 
  
 textCustomizerAttributeResourceName 
 , 
  
 String 
  
 priceCustomizerAttributeResourceName 
 ) 
  
 { 
  
 List<AdGroupCustomizerOperation> 
  
 operations 
  
 = 
  
 new 
  
 ArrayList 
<> (); 
  
 // Binds the text attribute customizer to a specific ad group to make sure it will only be used 
  
 // to customize ads inside that ad group. 
  
 AdGroupCustomizer 
  
 marsCustomizer 
  
 = 
  
 AdGroupCustomizer 
 . 
 newBuilder 
 () 
  
 . 
 setCustomizerAttribute 
 ( 
 textCustomizerAttributeResourceName 
 ) 
  
 . 
 setValue 
 ( 
  
 CustomizerValue 
 . 
 newBuilder 
 () 
  
 . 
 setType 
 ( 
 CustomizerAttributeType 
 . 
 TEXT 
 ) 
  
 . 
 setStringValue 
 ( 
 "Mars" 
 ) 
  
 . 
 build 
 ()) 
  
 . 
 setAdGroup 
 ( 
 ResourceNames 
 . 
 adGroup 
 ( 
 customerId 
 , 
  
 adGroupId 
 )) 
  
 . 
 build 
 (); 
  
 operations 
 . 
 add 
 ( 
 AdGroupCustomizerOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 marsCustomizer 
 ). 
 build 
 ()); 
  
 // Binds the price attribute customizer to a specific ad group to make sure it will only be used 
  
 // to customize ads inside that ad group. 
  
 AdGroupCustomizer 
  
 priceCustomizer 
  
 = 
  
 AdGroupCustomizer 
 . 
 newBuilder 
 () 
  
 . 
 setCustomizerAttribute 
 ( 
 priceCustomizerAttributeResourceName 
 ) 
  
 . 
 setValue 
 ( 
  
 CustomizerValue 
 . 
 newBuilder 
 () 
  
 . 
 setType 
 ( 
 CustomizerAttributeType 
 . 
 PRICE 
 ) 
  
 . 
 setStringValue 
 ( 
 "100.0€" 
 ) 
  
 . 
 build 
 ()) 
  
 . 
 setAdGroup 
 ( 
 ResourceNames 
 . 
 adGroup 
 ( 
 customerId 
 , 
  
 adGroupId 
 )) 
  
 . 
 build 
 (); 
  
 operations 
 . 
 add 
 ( 
 AdGroupCustomizerOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 priceCustomizer 
 ). 
 build 
 ()); 
  
 try 
  
 ( 
 AdGroupCustomizerServiceClient 
  
 adGroupCustomizerServiceClient 
  
 = 
  
 googleAdsClient 
 . 
 getLatestVersion 
 (). 
 createAdGroupCustomizerServiceClient 
 ()) 
  
 { 
  
 MutateAdGroupCustomizersResponse 
  
 response 
  
 = 
  
 adGroupCustomizerServiceClient 
 . 
 mutateAdGroupCustomizers 
 ( 
  
 Long 
 . 
 toString 
 ( 
 customerId 
 ), 
  
 operations 
 ); 
  
 for 
  
 ( 
 MutateAdGroupCustomizerResult 
  
 result 
  
 : 
  
 response 
 . 
 getResultsList 
 ()) 
  
 { 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "Added an ad group customizer with resource name '%s'.%n" 
 , 
  
 result 
 . 
 getResourceName 
 ()); 
  
 } 
  
 } 
  
 } 
  
 /** 
 * Creates a responsive search ad that uses the ad customizer attributes to populate the 
 * placeholders. 
 * 
 * @param googleAdsClient the Google Ads API client. 
 * @param customerId the client customer ID. 
 * @param stringCustomizerName name of the string customizer. 
 * @param priceCustomizerName Name of the price customizer. 
 */ 
  
 private 
  
 void 
  
 createAdWithCustomizations 
 ( 
  
 GoogleAdsClient 
  
 googleAdsClient 
 , 
  
 long 
  
 customerId 
 , 
  
 long 
  
 adGroupId 
 , 
  
 String 
  
 stringCustomizerName 
 , 
  
 String 
  
 priceCustomizerName 
 ) 
  
 { 
  
 // Creates a responsive search ad using the attribute customizer names as placeholders and 
  
 // default values to be used in case there are no attribute customizer values. 
  
 ResponsiveSearchAdInfo 
  
 responsiveSearchAdInfo 
  
 = 
  
 ResponsiveSearchAdInfo 
 . 
 newBuilder 
 () 
  
 . 
 addAllHeadlines 
 ( 
  
 ImmutableList 
 . 
 of 
 ( 
  
 AdTextAsset 
 . 
 newBuilder 
 () 
  
 . 
 setText 
 ( 
  
 String 
 . 
 format 
 ( 
  
 "Luxury cruise to {CUSTOMIZER.%s:Venus}" 
 , 
  
 stringCustomizerName 
 )) 
  
 . 
 setPinnedField 
 ( 
 ServedAssetFieldType 
 . 
 HEADLINE_1 
 ) 
  
 . 
 build 
 (), 
  
 AdTextAsset 
 . 
 newBuilder 
 () 
  
 . 
 setText 
 ( 
  
 String 
 . 
 format 
 ( 
 "Only {CUSTOMIZER.%s:10.0€}" 
 , 
  
 priceCustomizerName 
 )) 
  
 . 
 build 
 (), 
  
 AdTextAsset 
 . 
 newBuilder 
 () 
  
 . 
 setText 
 ( 
  
 String 
 . 
 format 
 ( 
  
 "Cruise to {CUSTOMIZER.%s:Venus} for {CUSTOMIZER.%s:10.0€}" 
 , 
  
 stringCustomizerName 
 , 
  
 priceCustomizerName 
 )) 
  
 . 
 build 
 ())) 
  
 . 
 addAllDescriptions 
 ( 
  
 ImmutableList 
 . 
 of 
 ( 
  
 AdTextAsset 
 . 
 newBuilder 
 () 
  
 . 
 setText 
 ( 
  
 String 
 . 
 format 
 ( 
  
 "Tickets are only {CUSTOMIZER.%s:10.0€}!" 
 , 
  
 priceCustomizerName 
 )) 
  
 . 
 build 
 (), 
  
 AdTextAsset 
 . 
 newBuilder 
 () 
  
 . 
 setText 
 ( 
  
 String 
 . 
 format 
 ( 
  
 "Buy your tickets to {CUSTOMIZER.%s:Venus} now!" 
 , 
  
 stringCustomizerName 
 )) 
  
 . 
 build 
 ())) 
  
 . 
 build 
 (); 
  
 Ad 
  
 ad 
  
 = 
  
 Ad 
 . 
 newBuilder 
 () 
  
 . 
 setResponsiveSearchAd 
 ( 
 responsiveSearchAdInfo 
 ) 
  
 . 
 addFinalUrls 
 ( 
 "https://www.example.com" 
 ) 
  
 . 
 build 
 (); 
  
 List<AdGroupAdOperation> 
  
 adGroupAdOperations 
  
 = 
  
 new 
  
 ArrayList 
<> (); 
  
 AdGroupAd 
  
 adGroupAd 
  
 = 
  
 AdGroupAd 
 . 
 newBuilder 
 () 
  
 . 
 setAd 
 ( 
 ad 
 ) 
  
 . 
 setAdGroup 
 ( 
 ResourceNames 
 . 
 adGroup 
 ( 
 customerId 
 , 
  
 adGroupId 
 )) 
  
 . 
 build 
 (); 
  
 AdGroupAdOperation 
  
 adGroupAdOperation 
  
 = 
  
 AdGroupAdOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 adGroupAd 
 ). 
 build 
 (); 
  
 adGroupAdOperations 
 . 
 add 
 ( 
 adGroupAdOperation 
 ); 
  
 try 
  
 ( 
 AdGroupAdServiceClient 
  
 adGroupAdServiceClient 
  
 = 
  
 googleAdsClient 
 . 
 getLatestVersion 
 (). 
 createAdGroupAdServiceClient 
 ()) 
  
 { 
  
 MutateAdGroupAdsResponse 
  
 response 
  
 = 
  
 adGroupAdServiceClient 
 . 
 mutateAdGroupAds 
 ( 
 Long 
 . 
 toString 
 ( 
 customerId 
 ), 
  
 adGroupAdOperations 
 ); 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
 "Added %d ads:%n" 
 , 
  
 response 
 . 
 getResultsCount 
 ()); 
  
 for 
  
 ( 
 MutateAdGroupAdResult 
  
 result 
  
 : 
  
 response 
 . 
 getResultsList 
 ()) 
  
 { 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
 "Added an ad with resource name '%s'.%n" 
 , 
  
 result 
 . 
 getResourceName 
 ()); 
  
 } 
  
 } 
  
 } 
 } 
  
  

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 
  
 System 
 ; 
 using 
  
 System.Collections.Generic 
 ; 
 using 
  
 Google.Ads.GoogleAds.V21.Enums 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V21 
 . 
 Enums 
 . 
 CustomizerAttributeTypeEnum 
 . 
 Types 
 ; 
 namespace 
  
 Google.Ads.GoogleAds.Examples.V21 
 { 
  
 /// <summary> 
  
 /// This code example adds two ad customizer attributes and associates 
  
 /// them with the ad group. 
  
 /// Then it adds an ad that uses the ad customizer attributes to populate 
  
 /// dynamic data. 
  
 /// </summary> 
  
 public 
  
 class 
  
 AddAdCustomizer 
  
 : 
  
 ExampleBase 
  
 { 
  
 /// <summary> 
  
 /// Command line options for running the <see cref="AddAdCustomizer"/> 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> 
  
 /// ID of the ad group to which ad customizers are added. 
  
 /// </summary> 
  
 [Option("adGroupId", Required = true, HelpText = 
 "ID of the ad group to which ad customizers are added.")] 
  
 public 
  
 long 
  
 AdGroupId 
  
 { 
  
 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 
 ); 
  
 AddAdCustomizer 
  
 codeExample 
  
 = 
  
 new 
  
 AddAdCustomizer 
 (); 
  
 Console 
 . 
 WriteLine 
 ( 
 codeExample 
 . 
 Description 
 ); 
  
 codeExample 
 . 
 Run 
 ( 
 new 
  
 GoogleAdsClient 
 (), 
  
 options 
 . 
 CustomerId 
 , 
  
 options 
 . 
 AdGroupId 
 ); 
  
 } 
  
 /// <summary> 
  
 /// Returns a description about the code example. 
  
 /// </summary> 
  
 public 
  
 override 
  
 string 
  
 Description 
  
 = 
>  
 "This code example adds two ad customizer attributes and associates them with the ad group. " 
  
 + 
  
 "Then it adds an ad that uses the customizer attributes to populate dynamic data." 
 ; 
  
 /// <summary> 
  
 /// Runs the code example. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads client.</param> 
  
 /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> 
  
 /// <param name="adGroupId">ID of the ad group to which ad customizers are added.</param> 
  
 public 
  
 void 
  
 Run 
 ( 
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 long 
  
 adGroupId 
 ) 
  
 { 
  
 // Get the AdGroupBidModifierService. 
  
 AdGroupBidModifierServiceClient 
  
 adGroupBidModifierService 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V21 
 . 
 AdGroupBidModifierService 
 ); 
  
 string 
  
 stringCustomizerName 
  
 = 
  
 "Planet_" 
  
 + 
  
 ExampleUtilities 
 . 
 GetShortRandomString 
 (); 
  
 string 
  
 priceCustomizerName 
  
 = 
  
 "Price_" 
  
 + 
  
 ExampleUtilities 
 . 
 GetShortRandomString 
 (); 
  
 try 
  
 { 
  
 // Create ad customizer attributes. 
  
 string 
  
 textCustomizerAttributeResourceName 
  
 = 
  
 CreateTextCustomizerAttribute 
 ( 
 client 
 , 
  
 customerId 
 , 
  
 stringCustomizerName 
 ); 
  
 string 
  
 priceCustomizerAttributeResourceName 
  
 = 
  
 CreatePriceCustomizerAttribute 
 ( 
 client 
 , 
  
 customerId 
 , 
  
 priceCustomizerName 
 ); 
  
 // Link the customizer attributes to the ad group. 
  
 LinkCustomizerAttributes 
 ( 
 client 
 , 
  
 customerId 
 , 
  
 adGroupId 
 , 
  
 textCustomizerAttributeResourceName 
 , 
  
 priceCustomizerAttributeResourceName 
 ); 
  
 // Create an ad with the customizations provided by the ad customizer attributes. 
  
 CreateAdWithCustomizations 
 ( 
 client 
 , 
  
 customerId 
 , 
  
 adGroupId 
 , 
  
 stringCustomizerName 
 , 
  
 priceCustomizerName 
 ); 
  
 } 
  
 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 a text customizer attribute and returns its resource name. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads client.</param> 
  
 /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> 
  
 /// <param name="customizerName">The name of the customizer to create.</param> 
  
 private 
  
 string 
  
 CreateTextCustomizerAttribute 
 ( 
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 customizerName 
 ) 
  
 { 
  
 // Get the customizer attribute service. 
  
 CustomizerAttributeServiceClient 
  
 customizerAttributeService 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V21 
 . 
 CustomizerAttributeService 
 ); 
  
 // Creates a text customizer attribute. The customizer attribute name is 
  
 // arbitrary and will be used as a placeholder in the ad text fields. 
  
 CustomizerAttribute 
  
 textAttribute 
  
 = 
  
 new 
  
 CustomizerAttribute 
 () 
  
 { 
  
 Name 
  
 = 
  
 customizerName 
 , 
  
 Type 
  
 = 
  
 CustomizerAttributeType 
 . 
 Text 
  
 }; 
  
 CustomizerAttributeOperation 
  
 textAttributeOperation 
  
 = 
  
 new 
  
 CustomizerAttributeOperation 
 (){ 
  
 Create 
  
 = 
  
 textAttribute 
  
 }; 
  
 MutateCustomizerAttributesResponse 
  
 response 
  
 = 
  
 customizerAttributeService 
 . 
 MutateCustomizerAttributes 
 ( 
 customerId 
 . 
 ToString 
 (), 
  
 new 
 [] 
  
 { 
 textAttributeOperation 
 }); 
  
 string 
  
 customizerAttributeResourceName 
  
 = 
  
 response 
 . 
 Results 
 [ 
 0 
 ]. 
 ResourceName 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Added text customizer attribute with resource name" 
  
 + 
  
 $" '{customizerAttributeResourceName}'." 
 ); 
  
 return 
  
 customizerAttributeResourceName 
 ; 
  
 } 
  
 /// <summary> 
  
 /// Creates a price customizer attribute ad returns its resource name. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads client.</param> 
  
 /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> 
  
 /// <param name="customizerName">The name of the customizer to create.</param> 
  
 private 
  
 string 
  
 CreatePriceCustomizerAttribute 
 ( 
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 customizerName 
 ) 
  
 { 
  
 // Get the customizer attribute service. 
  
 CustomizerAttributeServiceClient 
  
 customizerAttributeService 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V21 
 . 
 CustomizerAttributeService 
 ); 
  
 // Creates a price customizer attribute. The customizer attribute name is 
  
 // arbitrary and will be used as a placeholder in the ad text fields. 
  
 CustomizerAttribute 
  
 priceAttribute 
  
 = 
  
 new 
  
 CustomizerAttribute 
 () 
  
 { 
  
 Name 
  
 = 
  
 customizerName 
 , 
  
 Type 
  
 = 
  
 CustomizerAttributeType 
 . 
 Price 
  
 }; 
  
 CustomizerAttributeOperation 
  
 priceAttributeOperation 
  
 = 
  
 new 
  
 CustomizerAttributeOperation 
 (){ 
  
 Create 
  
 = 
  
 priceAttribute 
  
 }; 
  
 MutateCustomizerAttributesResponse 
  
 response 
  
 = 
  
 customizerAttributeService 
 . 
 MutateCustomizerAttributes 
 ( 
 customerId 
 . 
 ToString 
 (), 
  
 new 
 [] 
  
 { 
 priceAttributeOperation 
 }); 
  
 string 
  
 customizerAttributeResourceName 
  
 = 
  
 response 
 . 
 Results 
 [ 
 0 
 ]. 
 ResourceName 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Added price customizer attribute with resource name" 
  
 + 
  
 $" '{customizerAttributeResourceName}'." 
 ); 
  
 return 
  
 customizerAttributeResourceName 
 ; 
  
 } 
  
 /// <summary> 
  
 /// Restricts the ad customizer attributes to work only with a specific ad group; this prevents 
  
 /// the customizer attributes from being used elsewhere and makes sure they are used only for 
  
 /// customizing a specific ad group. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads client.</param> 
  
 /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> 
  
 /// <param name="adGroupId">The ad group ID to bind the customizer attributes to.</param> 
  
 /// <param name="textCustomizerAttributeResourceName">The resource name of the text customizer attribute.</param> 
  
 /// <param name="priceCustomizerAttributeResourceName">The resource name of the price customizer attribute.</param> 
  
 private 
  
 void 
  
 LinkCustomizerAttributes 
 ( 
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 long 
  
 adGroupId 
 , 
  
 string 
  
 textCustomizerAttributeResourceName 
 , 
  
 string 
  
 priceCustomizerAttributeResourceName 
 ) 
  
 { 
  
 // Get the ad group customizer service. 
  
 AdGroupCustomizerServiceClient 
  
 adGroupCustomizerService 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V21 
 . 
 AdGroupCustomizerService 
 ); 
  
 List<AdGroupCustomizerOperation> 
  
 adGroupCustomizerOperations 
  
 = 
  
 new 
  
 List<AdGroupCustomizerOperation> 
 (); 
  
 // Binds the text attribute customizer to a specific ad group to 
  
 // make sure it will only be used to customize ads inside that ad 
  
 // group. 
  
 AdGroupCustomizer 
  
 marsCustomizer 
  
 = 
  
 new 
  
 AdGroupCustomizer 
 (){ 
  
 CustomizerAttribute 
  
 = 
  
 textCustomizerAttributeResourceName 
 , 
  
 Value 
  
 = 
  
 new 
  
 CustomizerValue 
 (){ 
  
 Type 
  
 = 
  
 CustomizerAttributeType 
 . 
 Text 
 , 
  
 StringValue 
  
 = 
  
 "Mars" 
  
 }, 
  
 AdGroup 
  
 = 
  
 ResourceNames 
 . 
 AdGroup 
 ( 
 customerId 
 , 
  
 adGroupId 
 ) 
  
 }; 
  
 adGroupCustomizerOperations 
 . 
 Add 
 ( 
 new 
  
 AdGroupCustomizerOperation 
 (){ 
  
 Create 
  
 = 
  
 marsCustomizer 
  
 }); 
  
 // Binds the price attribute customizer to a specific ad group to 
  
 // make sure it will only be used to customize ads inside that ad 
  
 // group. 
  
 AdGroupCustomizer 
  
 priceCustomizer 
  
 = 
  
 new 
  
 AdGroupCustomizer 
 (){ 
  
 CustomizerAttribute 
  
 = 
  
 priceCustomizerAttributeResourceName 
 , 
  
 Value 
  
 = 
  
 new 
  
 CustomizerValue 
 (){ 
  
 Type 
  
 = 
  
 CustomizerAttributeType 
 . 
 Price 
 , 
  
 StringValue 
  
 = 
  
 "100.0€" 
  
 }, 
  
 AdGroup 
  
 = 
  
 ResourceNames 
 . 
 AdGroup 
 ( 
 customerId 
 , 
  
 adGroupId 
 ) 
  
 }; 
  
 adGroupCustomizerOperations 
 . 
 Add 
 ( 
 new 
  
 AdGroupCustomizerOperation 
 (){ 
  
 Create 
  
 = 
  
 priceCustomizer 
  
 }); 
  
 MutateAdGroupCustomizersResponse 
  
 response 
  
 = 
  
 adGroupCustomizerService 
 . 
 MutateAdGroupCustomizers 
 ( 
 customerId 
 . 
 ToString 
 (), 
  
 adGroupCustomizerOperations 
 ); 
  
 foreach 
  
 ( 
 MutateAdGroupCustomizerResult 
  
 result 
  
 in 
  
 response 
 . 
 Results 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Added an ad group customizer with resource name '{result.ResourceName}'." 
 ); 
  
 } 
  
 } 
  
 /// <summary> 
  
 /// Creates a responsive search ad that uses the ad customizer attributes to populate the placeholders. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads client.</param> 
  
 /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> 
  
 /// <param name="adGroupId">The ad group IDs in which to create the ads.</param> 
  
 /// <param name="stringCustomizerName">Name of the string customizer.</param> 
  
 /// <param name="priceCustomizerName">Name of the price customizer.</param> 
  
 private 
  
 void 
  
 CreateAdWithCustomizations 
 ( 
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 long 
  
 adGroupId 
 , 
  
 string 
  
 stringCustomizerName 
 , 
  
 string 
  
 priceCustomizerName 
 ) 
  
 { 
  
 // Get the AdGroupAdServiceClient. 
  
 AdGroupAdServiceClient 
  
 adGroupAdService 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V21 
 . 
 AdGroupAdService 
 ); 
  
 // Creates a responsive search ad using the attribute customizer names as 
  
 // placeholders and default values to be used in case there are no attribute 
  
 // customizer values. 
  
 Ad 
  
 ad 
  
 = 
  
 new 
  
 Ad 
 () 
  
 { 
  
 ResponsiveSearchAd 
  
 = 
  
 new 
  
 ResponsiveSearchAdInfo 
 () 
  
 { 
  
 Headlines 
  
 = 
  
 { 
  
 new 
  
 AdTextAsset 
 () 
  
 { 
  
 Text 
  
 = 
  
 $"Luxury cruise to {{CUSTOMIZER.{stringCustomizerName}:Venus}}" 
 , 
  
 PinnedField 
  
 = 
  
 ServedAssetFieldTypeEnum 
 . 
 Types 
 . 
 ServedAssetFieldType 
 . 
 Headline1 
  
 }, 
  
 new 
  
 AdTextAsset 
 () 
  
 { 
  
 Text 
  
 = 
  
 $"Only {{CUSTOMIZER.{priceCustomizerName}:10.0€}}" 
  
 }, 
  
 new 
  
 AdTextAsset 
 () 
  
 { 
  
 Text 
  
 = 
  
 $"Cruise to {{CUSTOMIZER.{stringCustomizerName}:Venus}} for {{CUSTOMIZER.{priceCustomizerName}:10.0€}}" 
  
 } 
  
 }, 
  
 Descriptions 
  
 = 
  
 { 
  
 new 
  
 AdTextAsset 
 () 
  
 { 
  
 Text 
  
 = 
  
 $"Tickets are only {{CUSTOMIZER.{priceCustomizerName}:10.0€}}!" 
  
 }, 
  
 new 
  
 AdTextAsset 
 () 
  
 { 
  
 Text 
  
 = 
  
 $"Buy your tickets to {{CUSTOMIZER.{stringCustomizerName}:Venus}} now!" 
  
 } 
  
 } 
  
 }, 
  
 FinalUrls 
  
 = 
  
 { 
  
 "https://www.example.com" 
  
 } 
  
 }; 
  
 AdGroupAd 
  
 adGroupAd 
  
 = 
  
 new 
  
 AdGroupAd 
 () 
  
 { 
  
 Ad 
  
 = 
  
 ad 
 , 
  
 AdGroup 
  
 = 
  
 ResourceNames 
 . 
 AdGroup 
 ( 
 customerId 
 , 
  
 adGroupId 
 ) 
  
 }; 
  
 AdGroupAdOperation 
  
 adGroupAdOperation 
  
 = 
  
 new 
  
 AdGroupAdOperation 
 (){ 
  
 Create 
  
 = 
  
 adGroupAd 
  
 }; 
  
 MutateAdGroupAdsResponse 
  
 response 
  
 = 
  
 adGroupAdService 
 . 
 MutateAdGroupAds 
 ( 
 customerId 
 . 
 ToString 
 (), 
  
 new 
 [] 
  
 { 
  
 adGroupAdOperation 
  
 }); 
  
 foreach 
  
 ( 
 MutateAdGroupAdResult 
  
 result 
  
 in 
  
 response 
 . 
 Results 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Added an ad with resource name '{result.ResourceName}'." 
 ); 
  
 } 
  
 } 
  
 } 
 } 
  
  

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\AdvancedOperations; 
 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\AdTextAsset; 
 use Google\Ads\GoogleAds\V21\Common\CustomizerValue; 
 use Google\Ads\GoogleAds\V21\Common\ResponsiveSearchAdInfo; 
 use Google\Ads\GoogleAds\V21\Enums\CustomizerAttributeTypeEnum\CustomizerAttributeType; 
 use Google\Ads\GoogleAds\V21\Enums\ServedAssetFieldTypeEnum\ServedAssetFieldType; 
 use Google\Ads\GoogleAds\V21\Errors\GoogleAdsError; 
 use Google\Ads\GoogleAds\V21\Resources\Ad; 
 use Google\Ads\GoogleAds\V21\Resources\AdGroupAd; 
 use Google\Ads\GoogleAds\V21\Resources\AdGroupCustomizer; 
 use Google\Ads\GoogleAds\V21\Resources\CustomizerAttribute; 
 use Google\Ads\GoogleAds\V21\Services\AdGroupAdOperation; 
 use Google\Ads\GoogleAds\V21\Services\AdGroupCustomizerOperation; 
 use Google\Ads\GoogleAds\V21\Services\CustomizerAttributeOperation; 
 use Google\Ads\GoogleAds\V21\Services\MutateAdGroupAdsRequest; 
 use Google\Ads\GoogleAds\V21\Services\MutateAdGroupCustomizersRequest; 
 use Google\Ads\GoogleAds\V21\Services\MutateCustomizerAttributesRequest; 
 use Google\ApiCore\ApiException; 
 /** 
 * Adds ad customizer attributes and associates them with the ad group. Then it adds an ad that 
 * uses the customizer attributes to populate dynamic data. 
 */ 
 class AddAdCustomizer 
 { 
 private const CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE'; 
 private const AD_GROUP_ID = 'INSERT_AD_GROUP_ID_HERE'; 
 public static function main() 
 { 
 // Either pass the required parameters for this example on the command line, or insert them 
 // into the constants above. 
 $options = (new ArgumentParser())->parseCommandArguments([ 
 ArgumentNames::CUSTOMER_ID => GetOpt::REQUIRED_ARGUMENT, 
 ArgumentNames::AD_GROUP_ID => GetOpt::REQUIRED_ARGUMENT 
 ]); 
 // 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, 
 $options[ArgumentNames::AD_GROUP_ID] ?: self::AD_GROUP_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 
 * @param int $adGroupId the ad group ID 
 */ 
 public static function runExample( 
 GoogleAdsClient $googleAdsClient, 
 int $customerId, 
 int $adGroupId 
 ) { 
 $stringCustomizerName = 'Planet_' . Helper::getShortPrintableDatetime(); 
 $priceCustomizerName = 'Price_' . Helper::getShortPrintableDatetime(); 
 // Creates ad customizer attributes. 
 $textCustomizerAttributeResourceName = self::createTextCustomizerAttribute( 
 $googleAdsClient, 
 $customerId, 
 $stringCustomizerName 
 ); 
 $priceCustomizerAttributeResourceName = self::createPriceCustomizerAttribute( 
 $googleAdsClient, 
 $customerId, 
 $priceCustomizerName 
 ); 
 // Link the customer attributes to the ad group. 
 self::linkCustomizerAttributes( 
 $googleAdsClient, 
 $customerId, 
 $adGroupId, 
 $textCustomizerAttributeResourceName, 
 $priceCustomizerAttributeResourceName 
 ); 
 // Creates an ad with the customizations provided by the ad customizer attributes. 
 self::createAdsWithCustomizations( 
 $googleAdsClient, 
 $customerId, 
 $adGroupId, 
 $stringCustomizerName, 
 $priceCustomizerName 
 ); 
 } 
 /** 
 * Creates a text customizer attribute and returns its resource name. 
 * 
 * @param GoogleAdsClient $googleAdsClient the Google Ads API client 
 * @param int $customerId the customer ID 
 * @param string $customizerName the name of the customizer to create 
 * @return string the resource name of the newly created text customizer attribute 
 */ 
 private static function createTextCustomizerAttribute( 
 GoogleAdsClient $googleAdsClient, 
 int $customerId, 
 string $customizerName 
 ) { 
 // Creates a text customizer attribute. The customizer attribute name is 
 // arbitrary and will be used as a placeholder in the ad text fields. 
 $textAttribute = new CustomizerAttribute([ 
 'name' => $customizerName, 
 'type' => CustomizerAttributeType::TEXT 
 ]); 
 // Creates a customizer attribute operation for creating a customizer attribute. 
 $customizerAttributeOperation = new CustomizerAttributeOperation(); 
 $customizerAttributeOperation->setCreate($textAttribute); 
 // Issues a mutate request to add the customizer attribute. 
 $customizerAttributeServiceClient = $googleAdsClient->getCustomizerAttributeServiceClient(); 
 $response = $customizerAttributeServiceClient->mutateCustomizerAttributes( 
 MutateCustomizerAttributesRequest::build($customerId, [$customizerAttributeOperation]) 
 ); 
 $customizerAttributeResourceName = $response->getResults()[0]->getResourceName(); 
 printf( 
 "Added text customizer attribute with resource name '%s'.%s", 
 $customizerAttributeResourceName, 
 PHP_EOL 
 ); 
 return $customizerAttributeResourceName; 
 } 
 /** 
 * Creates a price customizer attribute and returns its resource name. 
 * 
 * @param GoogleAdsClient $googleAdsClient the Google Ads API client 
 * @param int $customerId the customer ID 
 * @param string $customizerName the name of the customizer to create 
 * @return string the resource name of the newly created price customizer attribute 
 */ 
 private static function createPriceCustomizerAttribute( 
 GoogleAdsClient $googleAdsClient, 
 int $customerId, 
 string $customizerName 
 ) { 
 // Creates a price customizer attribute. The customizer attribute name is 
 // arbitrary and will be used as a placeholder in the ad text fields. 
 $priceAttribute = new CustomizerAttribute([ 
 'name' => $customizerName, 
 'type' => CustomizerAttributeType::PRICE 
 ]); 
 // Creates a customizer attribute operation for creating a customizer attribute. 
 $customizerAttributeOperation = new CustomizerAttributeOperation(); 
 $customizerAttributeOperation->setCreate($priceAttribute); 
 // Issues a mutate request to add the customizer attribute. 
 $customizerAttributeServiceClient = $googleAdsClient->getCustomizerAttributeServiceClient(); 
 $response = $customizerAttributeServiceClient->mutateCustomizerAttributes( 
 MutateCustomizerAttributesRequest::build($customerId, [$customizerAttributeOperation]) 
 ); 
 $customizerAttributeResourceName = $response->getResults()[0]->getResourceName(); 
 printf( 
 "Added price customizer attribute with resource name '%s'.%s", 
 $customizerAttributeResourceName, 
 PHP_EOL 
 ); 
 return $customizerAttributeResourceName; 
 } 
 /** 
 * Restricts the ad customizer attributes to work only with a specific ad group; this prevents 
 * the customizer attributes from being used elsewhere and makes sure they are used only for 
 * customizing a specific ad group. 
 * 
 * @param GoogleAdsClient $googleAdsClient the Google Ads API client 
 * @param int $customerId the customer ID 
 * @param int $adGroupId the ad group ID to bind the customizer attribute to 
 * @param string $textCustomizerAttributeResourceName the resource name of the text customizer 
 *     attribute 
 * @param string $priceCustomizerAttributeResourceName the resource name of the price 
 *     customizer attribute 
 */ 
 private static function linkCustomizerAttributes( 
 GoogleAdsClient $googleAdsClient, 
 int $customerId, 
 int $adGroupId, 
 string $textCustomizerAttributeResourceName, 
 string $priceCustomizerAttributeResourceName 
 ) { 
 $operations = []; 
 // Binds the text attribute customizer to a specific ad group to 
 // make sure it will only be used to customize ads inside that ad 
 // group. 
 $textAdGroupCustomizer = new AdGroupCustomizer([ 
 'customizer_attribute' => $textCustomizerAttributeResourceName, 
 'value' => new CustomizerValue([ 
 'type' => CustomizerAttributeType::TEXT, 
 'string_value' => 'Mars' 
 ]), 
 'ad_group' => ResourceNames::forAdGroup($customerId, $adGroupId) 
 ]); 
 // Creates an operation for the text attribute ad group customizer. 
 $textAdGroupCustomizerOperation = new AdGroupCustomizerOperation(); 
 $textAdGroupCustomizerOperation->setCreate($textAdGroupCustomizer); 
 $operations[] = $textAdGroupCustomizerOperation; 
 // Binds the price attribute customizer to a specific ad group to 
 // make sure it will only be used to customize ads inside that ad 
 // group. 
 $priceAdGroupCustomizer = new AdGroupCustomizer([ 
 'customizer_attribute' => $priceCustomizerAttributeResourceName, 
 'value' => new CustomizerValue([ 
 'type' => CustomizerAttributeType::PRICE, 
 'string_value' => '100.0€' 
 ]), 
 'ad_group' => ResourceNames::forAdGroup($customerId, $adGroupId) 
 ]); 
 // Creates an operation for the price attribute ad group customizer. 
 $priceAdGroupCustomizerOperation = new AdGroupCustomizerOperation(); 
 $priceAdGroupCustomizerOperation->setCreate($priceAdGroupCustomizer); 
 $operations[] = $priceAdGroupCustomizerOperation; 
 // Issues a mutate request to add ad group customizers. 
 $adGroupCustomizerServiceClient = $googleAdsClient->getAdGroupCustomizerServiceClient(); 
 $response = $adGroupCustomizerServiceClient->mutateAdGroupCustomizers( 
 MutateAdGroupCustomizersRequest::build($customerId, $operations) 
 ); 
 // Displays the results. 
 foreach ($response->getResults() as $result) { 
 printf( 
 "Added an ad group customizer with resource name '%s'.%s", 
 $result->getResourceName(), 
 PHP_EOL 
 ); 
 } 
 } 
 /** 
 * Creates a responsive search ad that uses the ad customizer attributes to populate the 
 * placeholders. 
 * 
 * @param GoogleAdsClient $googleAdsClient the Google Ads API client 
 * @param int $customerId the customer ID 
 * @param int $adGroupId the ad group ID in which to create the ad 
 * @param string $stringCustomizerName the name of the string customizer 
 * @param string $priceCustomizerName the name of the price customizer 
 */ 
 private static function createAdsWithCustomizations( 
 GoogleAdsClient $googleAdsClient, 
 int $customerId, 
 int $adGroupId, 
 string $stringCustomizerName, 
 string $priceCustomizerName 
 ) { 
 // Creates a responsive search ad using the attribute customizer names as 
 // placeholders and default values to be used in case there are no attribute 
 // customizer values. 
 $responsiveSearchAdInfo = new ResponsiveSearchAdInfo([ 
 'headlines' => [ 
 new AdTextAsset([ 
 'text' => "Luxury cruise to {CUSTOMIZER.$stringCustomizerName:Venus}", 
 'pinned_field' => ServedAssetFieldType::HEADLINE_1 
 ]), 
 new AdTextAsset(['text' => "Only {CUSTOMIZER.$priceCustomizerName:10.0€}"]), 
 new AdTextAsset([ 
 'text' => "Cruise to {CUSTOMIZER.$stringCustomizerName:Venus} for " 
 . "{CUSTOMIZER.$priceCustomizerName:10.0€}" 
 ]) 
 ], 
 'descriptions' => [ 
 new AdTextAsset([ 
 'text' => "Tickets are only {CUSTOMIZER.$priceCustomizerName:10.0€}!"]), 
 new AdTextAsset([ 
 'text' => "Buy your tickets to {CUSTOMIZER.$stringCustomizerName:Venus} now!"]) 
 ] 
 ]); 
 // Creates an ad group ad and its operation. 
 $adGroupAd = new AdGroupAd([ 
 'ad' => new Ad([ 
 'responsive_search_ad' => $responsiveSearchAdInfo, 
 'final_urls' => ['https://www.example.com'] 
 ]), 
 'ad_group' => ResourceNames::forAdGroup($customerId, $adGroupId) 
 ]); 
 $adGroupAdOperation = new AdGroupAdOperation(); 
 $adGroupAdOperation->setCreate($adGroupAd); 
 // Issues a mutate request to add the ad. 
 $adGroupAdServiceClient = $googleAdsClient->getAdGroupAdServiceClient(); 
 $adGroupAdResponse = $adGroupAdServiceClient->mutateAdGroupAds( 
 MutateAdGroupAdsRequest::build($customerId, [$adGroupAdOperation]) 
 ); 
 $adGroupAdResourceName = $adGroupAdResponse->getResults()[0]->getResourceName(); 
 printf("Added an ad with resource name '%s'.%s", $adGroupAdResourceName, PHP_EOL); 
 } 
 } 
 AddAdCustomizer::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. 
 """This code example adds two ad customizer attributes. 
 It then associates them with the given ad group and adds an ad that uses the ad 
 customizer attributes to populate dynamic data. 
 """ 
 import 
  
 argparse 
 import 
  
 sys 
 from 
  
 uuid 
  
 import 
 uuid4 
 from 
  
 google.ads.googleads.client 
  
 import 
 GoogleAdsClient 
 from 
  
 google.ads.googleads.errors 
  
 import 
 GoogleAdsException 
 from 
  
 google.ads.googleads.v21.common.types 
  
 import 
 AdTextAsset 
 from 
  
 google.ads.googleads.v21.resources.types 
  
 import 
 ( 
 AdGroupAd 
 , 
 AdGroupCustomizer 
 , 
 CustomizerAttribute 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.services.ad_group_ad_service 
  
 import 
 ( 
 AdGroupAdServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.services.ad_group_customizer_service 
  
 import 
 ( 
 AdGroupCustomizerServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.services.customizer_attribute_service 
  
 import 
 ( 
 CustomizerAttributeServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.services.google_ads_service 
  
 import 
 ( 
 GoogleAdsServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v21.services.types 
  
 import 
 ( 
 AdGroupAdOperation 
 , 
 AdGroupCustomizerOperation 
 , 
 CustomizerAttributeOperation 
 , 
 MutateAdGroupAdsResponse 
 , 
 MutateAdGroupCustomizersResponse 
 , 
 MutateCustomizerAttributesResponse 
 , 
 ) 
 def 
  
 main 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 ad_group_id 
 : 
 str 
 ) 
 - 
> None 
 : 
  
 """The main method that creates all necessary entities for the example. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 ad_group_id: an ad group ID. 
 """ 
 text_customizer_name 
 : 
 str 
 = 
 f 
 "Planet_ 
 { 
 uuid4 
 () 
 . 
 hex 
 [: 
 8 
 ] 
 } 
 " 
 price_customizer_name 
 : 
 str 
 = 
 f 
 "Price_ 
 { 
 uuid4 
 () 
 . 
 hex 
 [: 
 8 
 ] 
 } 
 " 
 text_customizer_resource_name 
 : 
 str 
 = 
 create_text_customizer_attribute 
 ( 
 client 
 , 
 customer_id 
 , 
 text_customizer_name 
 ) 
 price_customizer_resource_name 
 : 
 str 
 = 
 create_price_customizer_attribute 
 ( 
 client 
 , 
 customer_id 
 , 
 price_customizer_name 
 ) 
 link_customizer_attributes 
 ( 
 client 
 , 
 customer_id 
 , 
 ad_group_id 
 , 
 text_customizer_resource_name 
 , 
 price_customizer_resource_name 
 , 
 ) 
 create_ad_with_customizations 
 ( 
 client 
 , 
 customer_id 
 , 
 ad_group_id 
 , 
 text_customizer_name 
 , 
 price_customizer_name 
 , 
 ) 
 def 
  
 create_text_customizer_attribute 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 customizer_name 
 : 
 str 
 ) 
 - 
> str 
 : 
  
 """Creates a text customizer attribute and returns its resource name. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 customizer_name: the name of the customizer to create. 
 Returns: 
 a resource name for a text customizer attribute. 
 """ 
 customizer_attribute_service 
 : 
 CustomizerAttributeServiceClient 
 = 
 ( 
 client 
 . 
 get_service 
 ( 
 "CustomizerAttributeService" 
 ) 
 ) 
 # Creates a text customizer attribute. The customizer attribute name is 
 # arbitrary and will be used as a placeholder in the ad text fields. 
 operation 
 : 
 CustomizerAttributeOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "CustomizerAttributeOperation" 
 ) 
 text_attribute 
 : 
 CustomizerAttribute 
 = 
 operation 
 . 
 create 
 text_attribute 
 . 
 name 
 = 
 customizer_name 
 text_attribute 
 . 
 type_ 
 = 
 client 
 . 
 enums 
 . 
 CustomizerAttributeTypeEnum 
 . 
 TEXT 
 response 
 : 
 MutateCustomizerAttributesResponse 
 = 
 ( 
 customizer_attribute_service 
 . 
 mutate_customizer_attributes 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 [ 
 operation 
 ] 
 ) 
 ) 
 resource_name 
 : 
 str 
 = 
 response 
 . 
 results 
 [ 
 0 
 ] 
 . 
 resource_name 
 print 
 ( 
 f 
 "Added text customizer attribute with resource name ' 
 { 
 resource_name 
 } 
 '" 
 ) 
 return 
 resource_name 
 def 
  
 create_price_customizer_attribute 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 customizer_name 
 : 
 str 
 ) 
 - 
> str 
 : 
  
 """Creates a price customizer attribute and returns its resource name. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 customizer_name: the name of the customizer to create. 
 Returns: 
 a resource name for a text customizer attribute. 
 """ 
 customizer_attribute_service 
 : 
 CustomizerAttributeServiceClient 
 = 
 ( 
 client 
 . 
 get_service 
 ( 
 "CustomizerAttributeService" 
 ) 
 ) 
 # Creates a price customizer attribute. The customizer attribute name is 
 # arbitrary and will be used as a placeholder in the ad text fields. 
 operation 
 : 
 CustomizerAttributeOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "CustomizerAttributeOperation" 
 ) 
 price_attribute 
 : 
 CustomizerAttribute 
 = 
 operation 
 . 
 create 
 price_attribute 
 . 
 name 
 = 
 customizer_name 
 price_attribute 
 . 
 type_ 
 = 
 client 
 . 
 enums 
 . 
 CustomizerAttributeTypeEnum 
 . 
 PRICE 
 response 
 : 
 MutateCustomizerAttributesResponse 
 = 
 ( 
 customizer_attribute_service 
 . 
 mutate_customizer_attributes 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 [ 
 operation 
 ] 
 ) 
 ) 
 resource_name 
 : 
 str 
 = 
 response 
 . 
 results 
 [ 
 0 
 ] 
 . 
 resource_name 
 print 
 ( 
 f 
 "Added price customizer attribute with resource name ' 
 { 
 resource_name 
 } 
 '" 
 ) 
 return 
 resource_name 
 def 
  
 link_customizer_attributes 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 ad_group_id 
 : 
 str 
 , 
 text_customizer_resource_name 
 : 
 str 
 , 
 price_customizer_resource_name 
 : 
 str 
 , 
 ) 
 - 
> None 
 : 
  
 """Restricts the ad customizer attributes to work with a specific ad group. 
 This prevents the customizer attributes from being used elsewhere and makes 
 sure they are used only for customizing a specific ad group. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 ad_group_id: the ad group ID to bind the customizer attributes to. 
 text_customizer_resource_name: the resource name of the text customizer attribute. 
 price_customizer_resource_name: the resource name of the price customizer attribute. 
 """ 
 googleads_service 
 : 
 GoogleAdsServiceClient 
 = 
 client 
 . 
 get_service 
 ( 
 "GoogleAdsService" 
 ) 
 ad_group_customizer_service 
 : 
 AdGroupCustomizerServiceClient 
 = 
 ( 
 client 
 . 
 get_service 
 ( 
 "AdGroupCustomizerService" 
 ) 
 ) 
 # Binds the text attribute customizer to a specific ad group to make sure 
 # it will only be used to customize ads inside that ad group. 
 mars_operation 
 : 
 AdGroupCustomizerOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "AdGroupCustomizerOperation" 
 ) 
 mars_customizer 
 : 
 AdGroupCustomizer 
 = 
 mars_operation 
 . 
 create 
 mars_customizer 
 . 
 customizer_attribute 
 = 
 text_customizer_resource_name 
 mars_customizer 
 . 
 value 
 . 
 type_ 
 = 
 client 
 . 
 enums 
 . 
 CustomizerAttributeTypeEnum 
 . 
 TEXT 
 mars_customizer 
 . 
 value 
 . 
 string_value 
 = 
 "Mars" 
 mars_customizer 
 . 
 ad_group 
 = 
 googleads_service 
 . 
 ad_group_path 
 ( 
 customer_id 
 , 
 ad_group_id 
 ) 
 # Binds the price attribute customizer to a specific ad group to make sure 
 # it will only be used to customize ads inside that ad group. 
 price_operation 
 : 
 AdGroupCustomizerOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "AdGroupCustomizerOperation" 
 ) 
 price_customizer 
 : 
 AdGroupCustomizer 
 = 
 price_operation 
 . 
 create 
 price_customizer 
 . 
 customizer_attribute 
 = 
 price_customizer_resource_name 
 price_customizer 
 . 
 value 
 . 
 type_ 
 = 
 ( 
 client 
 . 
 enums 
 . 
 CustomizerAttributeTypeEnum 
 . 
 PRICE 
 ) 
 price_customizer 
 . 
 value 
 . 
 string_value 
 = 
 "100.0€" 
 price_customizer 
 . 
 ad_group 
 = 
 googleads_service 
 . 
 ad_group_path 
 ( 
 customer_id 
 , 
 ad_group_id 
 ) 
 response 
 : 
 MutateAdGroupCustomizersResponse 
 = 
 ( 
 ad_group_customizer_service 
 . 
 mutate_ad_group_customizers 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 [ 
 mars_operation 
 , 
 price_operation 
 ], 
 ) 
 ) 
 for 
 result 
 in 
 response 
 . 
 results 
 : 
 print 
 ( 
 "Added an ad group customizer with resource name " 
 f 
 "' 
 { 
 result 
 . 
 resource_name 
 } 
 '" 
 ) 
 def 
  
 create_ad_with_customizations 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 ad_group_id 
 : 
 str 
 , 
 text_customizer_name 
 : 
 str 
 , 
 price_customizer_name 
 : 
 str 
 , 
 ) 
 - 
> None 
 : 
  
 """Creates a responsive search ad (RSA). 
 The RSA uses the ad customizer attributes to populate the placeholders. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 ad_group_id: the ad group ID to bind the customizer attributes to. 
 text_customizer_name: name of the text customizer. 
 price_customizer_name: name of the price customizer. 
 """ 
 googleads_service 
 : 
 GoogleAdsServiceClient 
 = 
 client 
 . 
 get_service 
 ( 
 "GoogleAdsService" 
 ) 
 ad_group_ad_service 
 : 
 AdGroupAdServiceClient 
 = 
 client 
 . 
 get_service 
 ( 
 "AdGroupAdService" 
 ) 
 # Creates a responsive search ad using the attribute customizer names as 
 # placeholders and default values to be used in case there are no attribute 
 # customizer values. 
 operation 
 : 
 AdGroupAdOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "AdGroupAdOperation" 
 ) 
 ad_group_ad 
 : 
 AdGroupAd 
 = 
 operation 
 . 
 create 
 ad_group_ad 
 . 
 ad 
 . 
 final_urls 
 . 
 append 
 ( 
 "https://www.example.com" 
 ) 
 ad_group_ad 
 . 
 ad_group 
 = 
 googleads_service 
 . 
 ad_group_path 
 ( 
 customer_id 
 , 
 ad_group_id 
 ) 
 headline_1 
 : 
 AdTextAsset 
 = 
 client 
 . 
 get_type 
 ( 
 "AdTextAsset" 
 ) 
 headline_1 
 . 
 text 
 = 
 ( 
 f 
 "Luxury cruise to 
{{CUSTOMIZER.{text_customizer_name}:Venus} } 
 " 
 ) 
 headline_1 
 . 
 pinned_field 
 = 
 client 
 . 
 enums 
 . 
 ServedAssetFieldTypeEnum 
 . 
 HEADLINE_1 
 headline_2 
 : 
 AdTextAsset 
 = 
 client 
 . 
 get_type 
 ( 
 "AdTextAsset" 
 ) 
 headline_2 
 . 
 text 
 = 
 f 
 "Only 
{{CUSTOMIZER.{price_customizer_name}:10.0€} } 
 " 
 headline_3 
 : 
 AdTextAsset 
 = 
 client 
 . 
 get_type 
 ( 
 "AdTextAsset" 
 ) 
 headline_3 
 . 
 text 
 = 
 f 
 "Cruise to 
{{CUSTOMIZER.{text_customizer_name}:Venus} } 
 for 
{{CUSTOMIZER.{price_customizer_name}:10.0€} } 
 " 
 ad_group_ad 
 . 
 ad 
 . 
 responsive_search_ad 
 . 
 headlines 
 . 
 extend 
 ( 
 [ 
 headline_1 
 , 
 headline_2 
 , 
 headline_3 
 ] 
 ) 
 description_1 
 : 
 AdTextAsset 
 = 
 client 
 . 
 get_type 
 ( 
 "AdTextAsset" 
 ) 
 description_1 
 . 
 text 
 = 
 ( 
 f 
 "Tickets are only 
{{CUSTOMIZER.{price_customizer_name}:10.0€} } 
 !" 
 ) 
 description_2 
 : 
 AdTextAsset 
 = 
 client 
 . 
 get_type 
 ( 
 "AdTextAsset" 
 ) 
 description_2 
 . 
 text 
 = 
 ( 
 f 
 "Buy your tickets to 
{{CUSTOMIZER.{text_customizer_name}:Venus} } 
 now!" 
 ) 
 ad_group_ad 
 . 
 ad 
 . 
 responsive_search_ad 
 . 
 descriptions 
 . 
 extend 
 ( 
 [ 
 description_1 
 , 
 description_2 
 ] 
 ) 
 response 
 : 
 MutateAdGroupAdsResponse 
 = 
 ( 
 ad_group_ad_service 
 . 
 mutate_ad_group_ads 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 [ 
 operation 
 ] 
 ) 
 ) 
 resource_name 
 : 
 str 
 = 
 response 
 . 
 results 
 [ 
 0 
 ] 
 . 
 resource_name 
 print 
 ( 
 f 
 "Added an ad with resource name ' 
 { 
 resource_name 
 } 
 '" 
 ) 
 if 
 __name__ 
 == 
 "__main__" 
 : 
 parser 
 = 
 argparse 
 . 
 ArgumentParser 
 ( 
 description 
 = 
 ( 
 "This code example adds two ad customizer attributes and " 
 "associates them with the ad group. Then it adds an ad that uses " 
 "the customizer attributes to populate dynamic data." 
 ) 
 ) 
 # The following argument(s) should be provided to run the example. 
 parser 
 . 
 add_argument 
 ( 
 "-c" 
 , 
 "--customer_id" 
 , 
 type 
 = 
 str 
 , 
 required 
 = 
 True 
 , 
 help 
 = 
 "The Google Ads customer ID." 
 , 
 ) 
 parser 
 . 
 add_argument 
 ( 
 "-a" 
 , 
 "--ad_group_id" 
 , 
 type 
 = 
 str 
 , 
 required 
 = 
 True 
 , 
 help 
 = 
 "An ad group 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" 
 ) 
 try 
 : 
 main 
 ( 
 googleads_client 
 , 
 args 
 . 
 customer_id 
 , 
 args 
 . 
 ad_group_id 
 ) 
 except 
 GoogleAdsException 
 as 
 ex 
 : 
 print 
 ( 
 f 
 'Request with ID " 
 { 
 ex 
 . 
 request_id 
 } 
 " failed with status ' 
 f 
 '" 
 { 
 ex 
 . 
 error 
 . 
 code 
 () 
 . 
 name 
 } 
 " and includes the following errors:' 
 ) 
 for 
 error 
 in 
 ex 
 . 
 failure 
 . 
 errors 
 : 
 print 
 ( 
 f 
 '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 
 ) 
  

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 code example adds two ad customizer attributes and associates them with 
 # the ad group.  Then it adds an ad that uses the customizer attributes to 
 # populate dynamic data. 
 require 
  
 'date' 
 require 
  
 'google/ads/google_ads' 
 require 
  
 'optparse' 
 require_relative 
  
 '../shared/error_handler.rb' 
 def 
  
 add_ad_customizer 
 ( 
 customer_id 
 , 
  
 ad_group_id 
 ) 
  
 # GoogleAdsClient will read a config file from 
  
 # ENV['HOME']/google_ads_config.rb when called without parameters 
  
 client 
  
 = 
  
 Google 
 :: 
 Ads 
 :: 
 GoogleAds 
 :: 
 GoogleAdsClient 
 . 
 new 
  
 string_customizer_name 
  
 = 
  
 "Planet_ 
 #{ 
 ( 
 Time 
 . 
 new 
 . 
 to_f 
  
 * 
  
 1000 
 ) 
 . 
 to_i 
 } 
 " 
  
 price_customizer_name 
  
 = 
  
 "Price_ 
 #{ 
 ( 
 Time 
 . 
 new 
 . 
 to_f 
  
 * 
  
 1000 
 ) 
 . 
 to_i 
 } 
 " 
  
 # Create the customizer attributes. 
  
 text_customizer_attribute_resource_name 
  
 = 
  
 create_customizer_attribute 
 ( 
  
 client 
 , 
  
 customer_id 
 , 
  
 string_customizer_name 
 , 
  
 :TEXT 
 , 
  
 ) 
  
 price_customizer_attribute_resource_name 
  
 = 
  
 create_customizer_attribute 
 ( 
  
 client 
 , 
  
 customer_id 
 , 
  
 price_customizer_name 
 , 
  
 :PRICE 
 , 
  
 ) 
  
 # Link the customizer attributes to the ad group. 
  
 link_customizer_attributes 
 ( 
  
 client 
 , 
  
 customer_id 
 , 
  
 ad_group_id 
 , 
  
 text_customizer_attribute_resource_name 
 , 
  
 price_customizer_attribute_resource_name 
 , 
  
 ) 
  
 # Create an ad with the customizations provided by the ad customizer 
  
 # attributes. 
  
 create_ad_with_customizations 
 ( 
  
 client 
 , 
  
 customer_id 
 , 
  
 ad_group_id 
 , 
  
 string_customizer_name 
 , 
  
 price_customizer_name 
 , 
  
 ) 
 end 
 def 
  
 create_customizer_attribute 
 ( 
 client 
 , 
  
 customer_id 
 , 
  
 customizer_name 
 , 
  
 customizer_type 
 ) 
  
 operation 
  
 = 
  
 client 
 . 
 operation 
 . 
 create_resource 
 . 
 customizer_attribute 
  
 do 
  
 | 
 ca 
 | 
  
 ca 
 . 
 name 
  
 = 
  
 customizer_name 
  
 ca 
 . 
 type 
  
 = 
  
 customizer_type 
  
 end 
  
 response 
  
 = 
  
 client 
 . 
 service 
 . 
 customizer_attribute 
 . 
 mutate_customizer_attributes 
 ( 
  
 customer_id 
 : 
  
 customer_id 
 , 
  
 operations 
 : 
  
 [ 
 operation 
 ] 
 , 
  
 ) 
  
 resource_name 
  
 = 
  
 response 
 . 
 results 
 . 
 first 
 . 
 resource_name 
  
 puts 
  
 "Added 
 #{ 
 customizer_type 
 } 
 customizer attribute with resource name " 
  
 + 
  
 " 
 #{ 
 resource_name 
 } 
 ." 
  
 resource_name 
 end 
 def 
  
 link_customizer_attributes 
 ( 
 client 
 , 
  
 customer_id 
 , 
  
 ad_group_id 
 , 
  
 text_attribute_name 
 , 
  
 price_attribute_name 
 ) 
  
 operations 
  
 = 
  
 [] 
  
 operations 
 << 
 client 
 . 
 operation 
 . 
 create_resource 
 . 
 ad_group_customizer 
  
 do 
  
 | 
 agc 
 | 
  
 agc 
 . 
 customizer_attribute 
  
 = 
  
 text_attribute_name 
  
 agc 
 . 
 value 
  
 = 
  
 client 
 . 
 resource 
 . 
 customizer_value 
  
 do 
  
 | 
 cv 
 | 
  
 cv 
 . 
 type 
  
 = 
  
 :TEXT 
  
 cv 
 . 
 string_value 
  
 = 
  
 "Mars" 
  
 end 
  
 agc 
 . 
 ad_group 
  
 = 
  
 client 
 . 
 path 
 . 
 ad_group 
 ( 
 customer_id 
 , 
  
 ad_group_id 
 ) 
  
 end 
  
 operations 
 << 
 client 
 . 
 operation 
 . 
 create_resource 
 . 
 ad_group_customizer 
  
 do 
  
 | 
 agc 
 | 
  
 agc 
 . 
 customizer_attribute 
  
 = 
  
 price_attribute_name 
  
 agc 
 . 
 value 
  
 = 
  
 client 
 . 
 resource 
 . 
 customizer_value 
  
 do 
  
 | 
 cv 
 | 
  
 cv 
 . 
 type 
  
 = 
  
 :PRICE 
  
 cv 
 . 
 string_value 
  
 = 
  
 "100.0€" 
  
 end 
  
 agc 
 . 
 ad_group 
  
 = 
  
 client 
 . 
 path 
 . 
 ad_group 
 ( 
 customer_id 
 , 
  
 ad_group_id 
 ) 
  
 end 
  
 response 
  
 = 
  
 client 
 . 
 service 
 . 
 ad_group_customizer 
 . 
 mutate_ad_group_customizers 
 ( 
  
 customer_id 
 : 
  
 customer_id 
 , 
  
 operations 
 : 
  
 operations 
 , 
  
 ) 
  
 response 
 . 
 results 
 . 
 each 
  
 do 
  
 | 
 result 
 | 
  
 puts 
  
 "Added an ad group customizer with resource name 
 #{ 
 result 
 . 
 resource_name 
 } 
 ." 
  
 end 
 end 
 def 
  
 create_ad_with_customizations 
 ( 
 client 
 , 
  
 customer_id 
 , 
  
 ad_group_id 
 , 
  
 string_customizer_name 
 , 
  
 price_customizer_name 
 ) 
  
 operation 
  
 = 
  
 client 
 . 
 operation 
 . 
 create_resource 
 . 
 ad_group_ad 
  
 do 
  
 | 
 aga 
 | 
  
 aga 
 . 
 ad 
  
 = 
  
 client 
 . 
 resource 
 . 
 ad 
  
 do 
  
 | 
 ad 
 | 
  
 ad 
 . 
 responsive_search_ad 
  
 = 
  
 client 
 . 
 resource 
 . 
 responsive_search_ad_info 
  
 do 
  
 | 
 rsa 
 | 
  
 rsa 
 . 
 headlines 
  
 += 
  
 [ 
  
 client 
 . 
 resource 
 . 
 ad_text_asset 
  
 do 
  
 | 
 ata 
 | 
  
 ata 
 . 
 text 
  
 = 
  
 "Luxury cruise to {CUSTOMIZER. 
 #{ 
 string_customizer_name 
 } 
 :Venus}" 
  
 pinned_field 
  
 = 
  
 :HEADLINE_1 
  
 end 
 , 
  
 client 
 . 
 resource 
 . 
 ad_text_asset 
  
 do 
  
 | 
 ata 
 | 
  
 ata 
 . 
 text 
  
 = 
  
 "Only {CUSTOMIZER. 
 #{ 
 price_customizer_name 
 } 
 :10.0€}" 
  
 end 
 , 
  
 client 
 . 
 resource 
 . 
 ad_text_asset 
  
 do 
  
 | 
 ata 
 | 
  
 ata 
 . 
 text 
  
 = 
  
 "Cruise to {CUSTOMIZER. 
 #{ 
 string_customizer_name 
 } 
 :Venus} for {CUSTOMIZER. 
 #{ 
 price_customizer_name 
 } 
 :10.0€}" 
  
 end 
 , 
  
 ] 
  
 rsa 
 . 
 descriptions 
  
 += 
  
 [ 
  
 client 
 . 
 resource 
 . 
 ad_text_asset 
  
 do 
  
 | 
 ata 
 | 
  
 ata 
 . 
 text 
  
 = 
  
 "Tickets are only {CUSTOMIZER. 
 #{ 
 price_customizer_name 
 } 
 :10.0€}!" 
  
 end 
 , 
  
 client 
 . 
 resource 
 . 
 ad_text_asset 
  
 do 
  
 | 
 ata 
 | 
  
 ata 
 . 
 text 
  
 = 
  
 "Buy your tickets to {CUSTOMIZER. 
 #{ 
 string_customizer_name 
 } 
 :Venus} now!" 
  
 end 
 , 
  
 ] 
  
 end 
  
 ad 
 . 
 final_urls 
 << 
 "https://www.example.com" 
  
 end 
  
 aga 
 . 
 ad_group 
  
 = 
  
 client 
 . 
 path 
 . 
 ad_group 
 ( 
 customer_id 
 , 
  
 ad_group_id 
 ) 
  
 end 
  
 response 
  
 = 
  
 client 
 . 
 service 
 . 
 ad_group_ad 
 . 
 mutate_ad_group_ads 
 ( 
  
 customer_id 
 : 
  
 customer_id 
 , 
  
 operations 
 : 
  
 [ 
 operation 
 ] 
 , 
  
 ) 
  
 puts 
  
 "Added an ad with resource name 
 #{ 
 response 
 . 
 results 
 . 
 first 
 . 
 resource_name 
 } 
 ." 
 end 
 if 
  
 __FILE__ 
  
 == 
  
 $0 
  
 options 
  
 = 
  
 {} 
  
 # Running the example with -h will print the command line usage. 
  
 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 
 . 
 on 
 ( 
 '-A' 
 , 
  
 '--ad-group-id AD-GROUP-ID' 
 , 
  
 String 
 , 
  
 'AdGroup ID' 
 ) 
  
 do 
  
 | 
 v 
 | 
  
 options 
 [ 
 :ad_group_id 
 ] 
  
 = 
  
 v 
 . 
 split 
 ( 
 ',' 
 ) 
  
 end 
  
 opts 
 . 
 separator 
  
 '' 
  
 opts 
 . 
 separator 
  
 'Help:' 
  
 opts 
 . 
 on_tail 
 ( 
 '-h' 
 , 
  
 '--help' 
 , 
  
 'Show this message' 
 ) 
  
 do 
  
 puts 
  
 opts 
  
 exit 
  
 end 
  
 end 
 . 
 parse! 
  
 begin 
  
 add_ad_customizer 
 ( 
  
 options 
 . 
 fetch 
 ( 
 :customer_id 
 ) 
 . 
 tr 
 ( 
 "-" 
 , 
  
 "" 
 ), 
  
 options 
 [ 
 :ad_group_id 
 ] 
 , 
  
 ) 
  
 rescue 
  
 Google 
 :: 
 Ads 
 :: 
 GoogleAds 
 :: 
 Errors 
 :: 
 GoogleAdsError 
  
 = 
>  
 e 
  
 GoogleAdsErrorHandler 
 . 
 handle_google_ads_error 
 ( 
 e 
 ) 
  
 raise 
  
 # Re-raise the error to maintain original script behavior. 
  
 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 code example adds two ad customizer attributes and associates them with the ad group. 
 # Then it adds an ad that uses the ad customizer attributes to populate dynamic data. 
 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::AttributeFieldMapping 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::Ad 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::AdGroupAd 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::AdGroupCustomizer 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Resources::CustomizerAttribute 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Common::AdTextAsset 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Common::CustomizerValue 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Common::ResponsiveSearchAdInfo 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::CustomizerAttributeTypeEnum 
  
 qw(TEXT PRICE) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Enums::ServedAssetFieldTypeEnum 
  
 qw(HEADLINE_1) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::AdGroupAdService::AdGroupAdOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::AdGroupCustomizerService::AdGroupCustomizerOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V21::Services::CustomizerAttributeService::CustomizerAttributeOperation 
 ; 
 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) 
 ; 
 sub 
  
 add_ad_customizer 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $ad_group_id 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $string_customizer_name 
  
 = 
  
 "Planet_" 
  
 . 
  
 uniqid 
 (); 
  
 my 
  
 $price_customizer_name 
  
 = 
  
 "Price_" 
  
 . 
  
 uniqid 
 (); 
  
 my 
  
 $text_customizer_attribute_resource_name 
  
 = 
  
 create_text_customizer_attribute 
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $string_customizer_name 
 ); 
  
 my 
  
 $price_customizer_attribute_resource_name 
  
 = 
  
 create_price_customizer_attribute 
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $price_customizer_name 
 ); 
  
 # Link the customizer attributes to the ad group. 
  
 link_customizer_attributes 
 ( 
  
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $ad_group_id 
 , 
  
 $text_customizer_attribute_resource_name 
 , 
  
 $price_customizer_attribute_resource_name 
  
 ); 
  
 # Create an ad with the customizations provided by the ad customizer attributes. 
  
 create_ad_with_customizations 
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $ad_group_id 
 , 
  
 $string_customizer_name 
 , 
  
 $price_customizer_name 
 ); 
  
 return 
  
 1 
 ; 
 } 
 # Creates a text customizer attribute and returns its resource name. 
 sub 
  
 create_text_customizer_attribute 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $customizer_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 # Creates a text customizer attribute. The customizer attribute name is 
  
 # arbitrary and will be used as a placeholder in the ad text fields. 
  
 my 
  
 $text_attribute 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 CustomizerAttribute 
 - 
> new 
 ({ 
  
 name 
  
 = 
>  
 $customizer_name 
 , 
  
 type 
  
 = 
>  
 TEXT 
  
 }); 
  
 # Create a customizer attribute operation for creating a customizer attribute. 
  
 my 
  
 $text_attribute_operation 
  
 = 
  
 Google::Ads::GoogleAds::V21::Services::CustomizerAttributeService:: 
 CustomizerAttributeOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $text_attribute 
  
 }); 
  
 # Issue a mutate request to add the customizer attribute. 
  
 my 
  
 $response 
  
 = 
  
 $api_client 
 - 
> CustomizerAttributeService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 [ 
 $text_attribute_operation 
 ]}); 
  
 my 
  
 $customizer_attribute_resource_name 
  
 = 
  
 $response 
 - 
> { 
 results 
 }[ 
 0 
 ]{ 
 resourceName 
 }; 
  
 printf 
  
 "Added text customizer attribute with resource name '%s'.\n" 
 , 
  
 $customizer_attribute_resource_name 
 ; 
  
 return 
  
 $customizer_attribute_resource_name 
 ; 
 } 
 # Creates a price customizer attribute and returns its resource name. 
 sub 
  
 create_price_customizer_attribute 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $customizer_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 # Creates a price customizer attribute. The customizer attribute name is 
  
 # arbitrary and will be used as a placeholder in the ad text fields. 
  
 my 
  
 $price_attribute 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 CustomizerAttribute 
 - 
> new 
 ({ 
  
 name 
  
 = 
>  
 $customizer_name 
 , 
  
 type 
  
 = 
>  
 PRICE 
  
 }); 
  
 # Create a customizer attribute operation for creating a customizer attribute. 
  
 my 
  
 $price_attribute_operation 
  
 = 
  
 Google::Ads::GoogleAds::V21::Services::CustomizerAttributeService:: 
 CustomizerAttributeOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $price_attribute 
  
 }); 
  
 # Issue a mutate request to add the customizer attribute. 
  
 my 
  
 $response 
  
 = 
  
 $api_client 
 - 
> CustomizerAttributeService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 [ 
 $price_attribute_operation 
 ]}); 
  
 my 
  
 $customizer_attribute_resource_name 
  
 = 
  
 $response 
 - 
> { 
 results 
 }[ 
 0 
 ]{ 
 resourceName 
 }; 
  
 printf 
  
 "Added price customizer attribute with resource name '%s'.\n" 
 , 
  
 $customizer_attribute_resource_name 
 ; 
  
 return 
  
 $customizer_attribute_resource_name 
 ; 
 } 
 # Restricts the ad customizer attributes to work only with a specific ad group; 
 # this prevents the customizer attributes from being used elsewhere and makes sure 
 # they are used only for customizing a specific ad group. 
 sub 
  
 link_customizer_attributes 
  
 { 
  
 my 
  
 ( 
  
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $ad_group_id 
 , 
  
 $text_customizer_attribute_resource_name 
 , 
  
 $price_customizer_attribute_resource_name 
  
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $ad_group_customizer_operations 
  
 = 
  
 [] 
 ; 
  
 # Binds the text attribute customizer to a specific ad group to 
  
 # make sure it will only be used to customizer ads inside that ad group. 
  
 my 
  
 $marsCustomizer 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 AdGroupCustomizer 
 - 
> new 
 ({ 
  
 customizerAttribute 
  
 = 
>  
 $text_customizer_attribute_resource_name 
 , 
  
 value 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Common:: 
 CustomizerValue 
 - 
> new 
 ({ 
  
 type 
  
 = 
>  
 TEXT 
 , 
  
 stringValue 
  
 = 
>  
 "Mars" 
  
 } 
  
 ), 
  
 adGroup 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Utils::ResourceNames:: 
 ad_group 
 ( 
  
 $customer_id 
 , 
  
 $ad_group_id 
  
 )}); 
  
 push 
  
 @$ad_group_customizer_operations 
 , 
  
 Google::Ads::GoogleAds::V21::Services::AdGroupCustomizerService:: 
 AdGroupCustomizerOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $marsCustomizer 
  
 }); 
  
 # Binds the price attribute customizer to a specific ad group to 
  
 # make sure it will only be used to customizer ads inside that ad group. 
  
 my 
  
 $priceCustomizer 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 AdGroupCustomizer 
 - 
> new 
 ({ 
  
 customizerAttribute 
  
 = 
>  
 $price_customizer_attribute_resource_name 
 , 
  
 value 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Common:: 
 CustomizerValue 
 - 
> new 
 ({ 
  
 type 
  
 = 
>  
 PRICE 
 , 
  
 stringValue 
  
 = 
>  
 "100.0€" 
  
 } 
  
 ), 
  
 adGroup 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Utils::ResourceNames:: 
 ad_group 
 ( 
  
 $customer_id 
 , 
  
 $ad_group_id 
  
 )}); 
  
 push 
  
 @$ad_group_customizer_operations 
 , 
  
 Google::Ads::GoogleAds::V21::Services::AdGroupCustomizerService:: 
 AdGroupCustomizerOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $priceCustomizer 
  
 }); 
  
 # Issue a mutate request to link the customizers to the ad group. 
  
 my 
  
 $mutate_ad_group_customizers_response 
  
 = 
  
 $api_client 
 - 
> AdGroupCustomizerService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 $ad_group_customizer_operations 
  
 }); 
  
 # Display the results. 
  
 foreach 
  
 my 
  
 $result 
  
 ( 
 @ 
 { 
 $mutate_ad_group_customizers_response 
 - 
> { 
 results 
 }}) 
  
 { 
  
 printf 
  
 "Added an ad group customizer with resource name '%s'.\n" 
 , 
  
 $result 
 - 
> { 
 resourceName 
 }; 
  
 } 
 } 
 # Creates a responsive search ad that uses the ad customizer attributes to populate the placeholders. 
 sub 
  
 create_ad_with_customizations 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $ad_group_id 
 , 
  
 $string_customizer_name 
 , 
  
 $price_customizer_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 # Creates a responsive search ad using the attribute customizer names as 
  
 # placeholders and default values to be used in case there are no attribute 
  
 # customizer values. 
  
 my 
  
 $responsive_search_ad_info 
  
 = 
  
 Google::Ads::GoogleAds::V21::Common:: 
 ResponsiveSearchAdInfo 
 - 
> new 
 ({ 
  
 headlines 
  
 = 
>  
 [ 
  
 Google::Ads::GoogleAds::V21::Common:: 
 AdTextAsset 
 - 
> new 
 ({ 
  
 text 
  
 = 
>  
 "Luxury cruise to {CUSTOMIZER.$string_customizer_name:Venus}" 
 , 
  
 pinnedField 
  
 = 
>  
 HEADLINE_1 
  
 } 
  
 ), 
  
 Google::Ads::GoogleAds::V21::Common:: 
 AdTextAsset 
 - 
> new 
 ({ 
  
 text 
  
 = 
>  
 "Only {CUSTOMIZER.$price_customizer_name:10.0€}" 
 , 
  
 } 
  
 ), 
  
 Google::Ads::GoogleAds::V21::Common:: 
 AdTextAsset 
 - 
> new 
 ({ 
  
 text 
  
 = 
> "Cruise to {CUSTOMIZER.$string_customizer_name:Venus} for {CUSTOMIZER.$price_customizer_name:10.0€}" 
 , 
  
 }) 
  
 ], 
  
 descriptions 
  
 = 
>  
 [ 
  
 Google::Ads::GoogleAds::V21::Common:: 
 AdTextAsset 
 - 
> new 
 ({ 
  
 text 
  
 = 
>  
 "Tickets are only {CUSTOMIZER.$price_customizer_name:10.0€}!" 
 , 
  
 } 
  
 ), 
  
 Google::Ads::GoogleAds::V21::Common:: 
 AdTextAsset 
 - 
> new 
 ({ 
  
 text 
  
 = 
> "Buy your tickets to {CUSTOMIZER.$string_customizer_name:Venus} now!" 
  
 })]}); 
  
 my 
  
 $ad 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 Ad 
 - 
> new 
 ({ 
  
 responsiveSearchAd 
  
 = 
>  
 $responsive_search_ad_info 
 , 
  
 finalUrls 
  
 = 
>  
 [ 
 "https://www.example.com" 
 ]}); 
  
 my 
  
 $ad_group_ad 
  
 = 
  
 Google::Ads::GoogleAds::V21::Resources:: 
 AdGroupAd 
 - 
> new 
 ({ 
  
 ad 
  
 = 
>  
 $ad 
 , 
  
 adGroup 
  
 = 
>  
 Google::Ads::GoogleAds::V21::Utils::ResourceNames:: 
 ad_group 
 ( 
  
 $customer_id 
 , 
  
 $ad_group_id 
  
 )}); 
  
 my 
  
 $ad_group_ad_operation 
  
 = 
  
 Google::Ads::GoogleAds::V21::Services::AdGroupAdService:: 
 AdGroupAdOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $ad_group_ad 
  
 }); 
  
 # Issue a mutate request to add the ads. 
  
 my 
  
 $response 
  
 = 
  
 $api_client 
 - 
> AdGroupAdService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 [ 
 $ad_group_ad_operation 
 ]}); 
  
 my 
  
 $ad_group_ad_resource_name 
  
 = 
  
 $response 
 - 
> { 
 results 
 }[ 
 0 
 ]{ 
 resourceName 
 }; 
  
 printf 
  
 "Added an ad with resource name '%s'.\n" 
 , 
  
 $ad_group_ad_resource_name 
 ; 
 } 
 # 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 
 ); 
 my 
  
 $customer_id 
  
 = 
  
 undef 
 ; 
 my 
  
 $ad_group_id 
  
 = 
  
 undef 
 ; 
 # Parameters passed on the command line will override any parameters set in code. 
 GetOptions 
 ( 
  
 "customer_id=s" 
  
 = 
>  
 \ 
 $customer_id 
 , 
  
 "ad_group_id=i" 
  
 = 
>  
 \ 
 $ad_group_id 
 ); 
 # Print the help message if the parameters are not initialized in the code nor 
 # in the command line. 
 pod2usage 
 ( 
 2 
 ) 
  
 if 
  
 not 
  
 check_params 
 ( 
 $customer_id 
 , 
  
 $ad_group_id 
 ); 
 # Call the example. 
 add_ad_customizer 
 ( 
 $api_client 
 , 
  
 $customer_id 
  
 =~ 
  
 s/-//g 
 r 
 , 
  
 $ad_group_id 
 ); 
 =pod 
 =head1 NAME 
 add_ad_customizer 
 =head1 DESCRIPTION 
 This code example adds two ad customizer attributes and associates them with the ad group. 
 Then it adds an ad that uses the ad customizer attributes to populate dynamic data. 
 =head1 SYNOPSIS 
 add_ad_customizer.pl [options] 
 -help                       Show the help message. 
 -customer_id                The Google Ads customer ID. 
 -ad_group_id                The ad group ID to add the ad customizers to. 
 =cut 
  
  
Design a Mobile Site
View Site in Mobile | Classic
Share by: