Creating Responsive Search Ads

  • This document provides code examples in Java, C#, and Python for creating responsive search ads using the Google Ads API.

  • The process involves several steps, including creating a campaign budget, campaign, ad group, keywords, geo targets, and the responsive search ad itself.

  • Responsive search ads require at least three headlines, at least two descriptions, and at least one final URL, and can utilize ad customizers for dynamic content.

  • The code walkthrough covers creating customizer attributes and linking them, setting up budgets, campaigns, and ad groups, building the ad with various elements, and adding keywords and geo targeting.

  • The examples utilize various Google Ads API service clients and demonstrate mutate requests and error handling.

Below you can see code examples showing how to create responsive search ads. As with other ads, ad creation is accomplished using AdGroupAdService.MutateAdGroupAds . A ResponsiveSearchAdInfo requires at least three headlines, at least two descriptions, and at least one final URL.

Java

 // Copyright 2025 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.getPrintableDateTime 
 ; 
 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.v22.common.LocationInfo 
 ; 
 import 
  
 com.google.ads.googleads.v22.resources.CampaignCriterion 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.CampaignCriterionOperation 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.CampaignCriterionServiceClient 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.GeoTargetConstantServiceClient 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.GeoTargetConstantSuggestion 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.MutateAdGroupCriteriaResponse 
 ; 
 import 
  
 com.google.ads.googleads.v22.common.KeywordInfo 
 ; 
 import 
  
 com.google.ads.googleads.v22.enums.AdGroupCriterionStatusEnum.AdGroupCriterionStatus 
 ; 
 import 
  
 com.google.ads.googleads.v22.enums.KeywordMatchTypeEnum.KeywordMatchType 
 ; 
 import 
  
 com.google.ads.googleads.v22.resources.AdGroupCriterion 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.AdGroupCriterionOperation 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.AdGroupCriterionServiceClient 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.AdGroupOperation 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.AdGroupServiceClient 
 ; 
 import 
  
 com.google.ads.googleads.v22.common.TargetSpend 
 ; 
 import 
  
 com.google.ads.googleads.v22.enums.AdGroupAdStatusEnum.AdGroupAdStatus 
 ; 
 import 
  
 com.google.ads.googleads.v22.enums.AdGroupStatusEnum.AdGroupStatus 
 ; 
 import 
  
 com.google.ads.googleads.v22.enums.AdGroupTypeEnum.AdGroupType 
 ; 
 import 
  
 com.google.ads.googleads.v22.enums.AdvertisingChannelTypeEnum.AdvertisingChannelType 
 ; 
 import 
  
 com.google.ads.googleads.v22.enums.BudgetDeliveryMethodEnum.BudgetDeliveryMethod 
 ; 
 import 
  
 com.google.ads.googleads.v22.enums.CampaignStatusEnum.CampaignStatus 
 ; 
 import 
  
 com.google.ads.googleads.v22.enums.ServedAssetFieldTypeEnum.ServedAssetFieldType 
 ; 
 import 
  
 com.google.ads.googleads.v22.resources.AdGroup 
 ; 
 import 
  
 com.google.ads.googleads.v22.resources.Campaign 
 ; 
 import 
  
 com.google.ads.googleads.v22.resources.Campaign.NetworkSettings 
 ; 
 import 
  
 com.google.ads.googleads.v22.resources.CampaignBudget 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.AdGroupAdOperation 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.AdGroupAdServiceClient 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.CampaignBudgetOperation 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.CampaignBudgetServiceClient 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.CampaignOperation 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.CampaignServiceClient 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.MutateAdGroupAdsResponse 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.MutateAdGroupCriterionResult 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.MutateAdGroupsResponse 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.MutateCampaignBudgetsResponse 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.MutateCampaignCriteriaResponse 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.MutateCampaignCriterionResult 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.MutateCampaignsResponse 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.SuggestGeoTargetConstantsRequest 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.SuggestGeoTargetConstantsRequest.LocationNames 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.SuggestGeoTargetConstantsResponse 
 ; 
 import 
  
 com.google.ads.googleads.v22.common.AdTextAsset 
 ; 
 import 
  
 com.google.ads.googleads.v22.common.CustomizerValue 
 ; 
 import 
  
 com.google.ads.googleads.v22.common.ResponsiveSearchAdInfo 
 ; 
 import 
  
 com.google.ads.googleads.v22.enums.CustomizerAttributeTypeEnum.CustomizerAttributeType 
 ; 
 import 
  
 com.google.ads.googleads.v22.errors.GoogleAdsError 
 ; 
 import 
  
 com.google.ads.googleads.v22.errors.GoogleAdsException 
 ; 
 import 
  
 com.google.ads.googleads.v22.resources.Ad 
 ; 
 import 
  
 com.google.ads.googleads.v22.resources.AdGroupAd 
 ; 
 import 
  
 com.google.ads.googleads.v22.resources.CustomerCustomizer 
 ; 
 import 
  
 com.google.ads.googleads.v22.resources.CustomizerAttribute 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.CustomerCustomizerOperation 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.CustomerCustomizerServiceClient 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.CustomizerAttributeOperation 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.CustomizerAttributeServiceClient 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.MutateCustomerCustomizersResponse 
 ; 
 import 
  
 com.google.ads.googleads.v22.services.MutateCustomizerAttributesResponse 
 ; 
 import 
  
 com.google.common.collect.ImmutableList 
 ; 
 import 
  
 java.io.FileNotFoundException 
 ; 
 import 
  
 java.io.IOException 
 ; 
 import 
  
 java.util.ArrayList 
 ; 
 import 
  
 javax.annotation.Nullable 
 ; 
 /** 
 * This example shows how to create a complete Responsive Search Ad. 
 * 
 * <p>Includes creation of: budget, campaign, ad group, ad group ad, keywords, and geo targeting. 
 * 
 * <p>More details on Responsive Search Ads can be found here: 
 * https://support.google.com/google-ads/answer/7684791 
 */ 
 public 
  
 class 
 AddResponsiveSearchAdFull 
  
 { 
  
 private 
  
 static 
  
 class 
 AddResponsiveSearchAdFullParams 
  
 extends 
  
 CodeSampleParams 
  
 { 
  
 @Parameter 
 ( 
 names 
  
 = 
  
 ArgumentNames 
 . 
 CUSTOMER_ID 
 , 
  
 required 
  
 = 
  
 true 
 ) 
  
 private 
  
 Long 
  
 customerId 
 ; 
  
 // The name of the customizer attribute to be used in the ad customizer, which must be unique. 
  
 // To run this example multiple times, change this value or specify its corresponding argument. 
  
 // Note that there is a limit for the number of enabled customizer attributes in one account, 
  
 // so you shouldn't run this example more than necessary. 
  
 // Visit 
  
 // https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads?hl=en#rules_and_limitations 
  
 // for details. 
  
 // 
  
 // Specify the customizer attribute name here or the default specified below will be used. 
  
 @Parameter 
 ( 
 names 
  
 = 
  
 ArgumentNames 
 . 
 CUSTOMIZER_ATTRIBUTE_NAME 
 ) 
  
 private 
  
 String 
  
 customizerAttributeName 
  
 = 
  
 "Price" 
 ; 
  
 } 
  
 public 
  
 static 
  
 void 
  
 main 
 ( 
 String 
 [] 
  
 args 
 ) 
  
 { 
  
 AddResponsiveSearchAdFullParams 
  
 params 
  
 = 
  
 new 
  
 AddResponsiveSearchAdFullParams 
 (); 
  
 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" 
 ); 
  
 // Optional: To use a different customizer attribute name from the default ("Price"), 
  
 // uncomment the line below and insert the desired customizer attribute name. 
  
 // params.customizerAttributeName = "INSERT_CUSTOMIZER_ATTRIBUTE_NAME_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 
  
 AddResponsiveSearchAdFull 
 () 
  
 . 
 runExample 
 ( 
 googleAdsClient 
 , 
  
 params 
 . 
 customerId 
 , 
  
 params 
 . 
 customizerAttributeName 
 ); 
  
 } 
  
 catch 
  
 ( 
 GoogleAdsException 
  
 gae 
 ) 
  
 { 
  
 // GoogleAdsException is the base class for most exceptions thrown by an API request. 
  
 // Instances of this exception have a message and a GoogleAdsFailure that contains a 
  
 // collection of GoogleAdsErrors that indicate the underlying causes of the 
  
 // GoogleAdsException. 
  
 System 
 . 
 err 
 . 
 printf 
 ( 
  
 "Request ID %s failed due to GoogleAdsException. Underlying errors:%n" 
 , 
  
 gae 
 . 
 getRequestId 
 ()); 
  
 int 
  
 i 
  
 = 
  
 0 
 ; 
  
 for 
  
 ( 
 GoogleAdsError 
  
 googleAdsError 
  
 : 
  
 gae 
 . 
 getGoogleAdsFailure 
 (). 
 getErrorsList 
 ()) 
  
 { 
  
 System 
 . 
 err 
 . 
 printf 
 ( 
 "  Error %d: %s%n" 
 , 
  
 i 
 ++ 
 , 
  
 googleAdsError 
 ); 
  
 } 
  
 System 
 . 
 exit 
 ( 
 1 
 ); 
  
 } 
  
 } 
  
 /** 
 * Runs the example. 
 * 
 * @param googleAdsClient the Google Ads API client. 
 * @param customerId the client customer ID. 
 * @param customizerAttributeName the customizer attribute name. 
 */ 
  
 private 
  
 void 
  
 runExample 
 ( 
  
 GoogleAdsClient 
  
 googleAdsClient 
 , 
  
 long 
  
 customerId 
 , 
  
 String 
  
 customizerAttributeName 
 ) 
  
 { 
  
 if 
  
 ( 
 customizerAttributeName 
  
 != 
  
 null 
 && 
 ! 
 customizerAttributeName 
 . 
 isEmpty 
 ()) 
  
 { 
  
 String 
  
 customizerAttributeResourceName 
  
 = 
  
 createCustomizerAttribute 
 ( 
 googleAdsClient 
 , 
  
 customerId 
 , 
  
 customizerAttributeName 
 ); 
  
 linkCustomizerAttributeToCustomer 
 ( 
  
 googleAdsClient 
 , 
  
 customerId 
 , 
  
 customizerAttributeResourceName 
 ); 
  
 } 
  
 String 
  
 campaignBudget 
  
 = 
  
 createCampaignBudget 
 ( 
 googleAdsClient 
 , 
  
 customerId 
 ); 
  
 String 
  
 campaignResourceName 
  
 = 
  
 createCampaign 
 ( 
 googleAdsClient 
 , 
  
 customerId 
 , 
  
 campaignBudget 
 ); 
  
 String 
  
 adGroupResourceName 
  
 = 
  
 createAdGroup 
 ( 
 googleAdsClient 
 , 
  
 customerId 
 , 
  
 campaignResourceName 
 ); 
  
 createAdGroupAd 
 ( 
 googleAdsClient 
 , 
  
 customerId 
 , 
  
 adGroupResourceName 
 , 
  
 customizerAttributeName 
 ); 
  
 addKeywords 
 ( 
 googleAdsClient 
 , 
  
 customerId 
 , 
  
 adGroupResourceName 
 ); 
  
 addGeoTargeting 
 ( 
 googleAdsClient 
 , 
  
 customerId 
 , 
  
 campaignResourceName 
 ); 
  
 } 
  
 /** Creates a customizer attribute with the specified customizer attribute name. */ 
  
 private 
  
 static 
  
 String 
  
 createCustomizerAttribute 
 ( 
  
 GoogleAdsClient 
  
 googleAdsClient 
 , 
  
 long 
  
 customerId 
 , 
  
 String 
  
 customizerAttributeName 
 ) 
  
 { 
  
 // Creates a customizer attribute with the specified name. 
  
 CustomizerAttribute 
  
 customizerAttribute 
  
 = 
  
 CustomizerAttribute 
 . 
 newBuilder 
 () 
  
 . 
 setName 
 ( 
 customizerAttributeName 
 ) 
  
 // Specifies the type to be 'PRICE' so that we can dynamically customize the part of the 
  
 // ad's description that is a price of a product/service we advertise. 
  
 . 
 setType 
 ( 
 CustomizerAttributeType 
 . 
 PRICE 
 ) 
  
 . 
 build 
 (); 
  
 // Creates a customizer attribute operation for creating a customizer attribute. 
  
 CustomizerAttributeOperation 
  
 operation 
  
 = 
  
 CustomizerAttributeOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 customizerAttribute 
 ). 
 build 
 (); 
  
 try 
  
 ( 
 CustomizerAttributeServiceClient 
  
 customizerAttributeServiceClient 
  
 = 
  
 googleAdsClient 
 . 
 getLatestVersion 
 (). 
 createCustomizerAttributeServiceClient 
 ()) 
  
 { 
  
 // Issues a mutate request to add the customizer attribute and prints its information. 
  
 MutateCustomizerAttributesResponse 
  
 response 
  
 = 
  
 customizerAttributeServiceClient 
 . 
 mutateCustomizerAttributes 
 ( 
  
 Long 
 . 
 toString 
 ( 
 customerId 
 ), 
  
 ImmutableList 
 . 
 of 
 ( 
 operation 
 )); 
  
 String 
  
 resourceName 
  
 = 
  
 response 
 . 
 getResults 
 ( 
 0 
 ). 
 getResourceName 
 (); 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
 "Added a customizer with resource name '%s'.%n" 
 , 
  
 resourceName 
 ); 
  
 return 
  
 resourceName 
 ; 
  
 } 
  
 } 
  
 /** 
 * Links the customizer attribute to the customer by providing a value to be used in a responsive 
 * search ad that will be created in a later step. 
 */ 
  
 private 
  
 static 
  
 void 
  
 linkCustomizerAttributeToCustomer 
 ( 
  
 GoogleAdsClient 
  
 googleAdsClient 
 , 
  
 long 
  
 customerId 
 , 
  
 String 
  
 customizerAttributeResourceName 
 ) 
  
 { 
  
 // Creates a customer customizer with the value to be used in the responsive search ad. 
  
 CustomerCustomizer 
  
 customerCustomizer 
  
 = 
  
 CustomerCustomizer 
 . 
 newBuilder 
 () 
  
 . 
 setCustomizerAttribute 
 ( 
 customizerAttributeResourceName 
 ) 
  
 // Specify '100USD' as a text value. The ad customizer will dynamically replace the 
  
 // placeholder with this value when the ad serves. 
  
 . 
 setValue 
 ( 
  
 CustomizerValue 
 . 
 newBuilder 
 () 
  
 . 
 setType 
 ( 
 CustomizerAttributeType 
 . 
 PRICE 
 ) 
  
 . 
 setStringValue 
 ( 
 "100USD" 
 ) 
  
 . 
 build 
 ()) 
  
 . 
 build 
 (); 
  
 // Creates a customer customizer operation. 
  
 CustomerCustomizerOperation 
  
 operation 
  
 = 
  
 CustomerCustomizerOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 customerCustomizer 
 ). 
 build 
 (); 
  
 try 
  
 ( 
 CustomerCustomizerServiceClient 
  
 customerCustomizerServiceClient 
  
 = 
  
 googleAdsClient 
 . 
 getLatestVersion 
 (). 
 createCustomerCustomizerServiceClient 
 ()) 
  
 { 
  
 // Issues a mutate request to add the customer customizer and prints its information. 
  
 MutateCustomerCustomizersResponse 
  
 response 
  
 = 
  
 customerCustomizerServiceClient 
 . 
 mutateCustomerCustomizers 
 ( 
  
 Long 
 . 
 toString 
 ( 
 customerId 
 ), 
  
 ImmutableList 
 . 
 of 
 ( 
 operation 
 )); 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "Added a customer customizer with resource name '%s'.%n" 
 , 
  
 response 
 . 
 getResults 
 ( 
 0 
 ). 
 getResourceName 
 ()); 
  
 } 
  
 } 
  
 /** 
 * Create an AdTextAsset. 
 * 
 * @param text: Text for headlines and descriptions. 
 * @param pinnedField: To pin a text asset so it always shows in the ad. 
 */ 
  
 private 
  
 static 
  
 AdTextAsset 
  
 createAdTextAsset 
 ( 
  
 String 
  
 text 
 , 
  
 @Nullable 
  
 ServedAssetFieldType 
  
 pinnedField 
 ) 
  
 { 
  
 AdTextAsset 
 . 
 Builder 
  
 adTextAsset 
  
 = 
  
 AdTextAsset 
 . 
 newBuilder 
 (). 
 setText 
 ( 
 text 
 ); 
  
 if 
  
 ( 
 pinnedField 
  
 != 
  
 null 
 ) 
  
 { 
  
 adTextAsset 
 . 
 setPinnedField 
 ( 
 pinnedField 
 ); 
  
 } 
  
 return 
  
 adTextAsset 
 . 
 build 
 (); 
  
 } 
  
 /** 
 * Creates an AdTextAsset with a customizer. 
 * 
 * @param customizerAttributeResourceName: The resource name of the customizer attribute. 
 */ 
  
 private 
  
 static 
  
 AdTextAsset 
  
 createAdTextAssetWithCustomizer 
 ( 
  
 String 
  
 customizerAttributeResourceName 
 ) 
  
 { 
  
 // Creates this particular description using the ad customizer. Visit 
  
 // https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads#ad_customizers_in_responsive_search_ads 
  
 // for details about the placeholder format. The ad customizer replaces the placeholder with 
  
 // the value we previously created and linked to the customer using CustomerCustomizer. 
  
 AdTextAsset 
 . 
 Builder 
  
 adTextAsset 
  
 = 
  
 AdTextAsset 
 . 
 newBuilder 
 () 
  
 . 
 setText 
 ( 
 String 
 . 
 format 
 ( 
 "Just {CUSTOMIZER.%s:10USD}" 
 , 
  
 customizerAttributeResourceName 
 )); 
  
 return 
  
 adTextAsset 
 . 
 build 
 (); 
  
 } 
  
 /** 
 * Creates the campaign budget resource. 
 * 
 * @param googleAdsClient: An initialized GoogleAdsClient instance. 
 * @param customerId: A client customer ID. 
 */ 
  
 private 
  
 static 
  
 String 
  
 createCampaignBudget 
 ( 
 GoogleAdsClient 
  
 googleAdsClient 
 , 
  
 Long 
  
 customerId 
 ) 
  
 { 
  
 // Creates the budget. 
  
 CampaignBudget 
  
 budget 
  
 = 
  
 CampaignBudget 
 . 
 newBuilder 
 () 
  
 . 
 setName 
 ( 
 "Interplanetary Cruise Budget #" 
  
 + 
  
 getPrintableDateTime 
 ()) 
  
 . 
 setDeliveryMethod 
 ( 
 BudgetDeliveryMethod 
 . 
 STANDARD 
 ) 
  
 . 
 setAmountMicros 
 ( 
 500000 
 ) 
  
 . 
 build 
 (); 
  
 // Creates the operation. 
  
 CampaignBudgetOperation 
  
 operation 
  
 = 
  
 CampaignBudgetOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 budget 
 ). 
 build 
 (); 
  
 // Gets the CampaignBudgetService. 
  
 try 
  
 ( 
 CampaignBudgetServiceClient 
  
 campaignBudgetServiceClient 
  
 = 
  
 googleAdsClient 
 . 
 getLatestVersion 
 (). 
 createCampaignBudgetServiceClient 
 ()) 
  
 { 
  
 // Adds the campaign budget. 
  
 MutateCampaignBudgetsResponse 
  
 response 
  
 = 
  
 campaignBudgetServiceClient 
 . 
 mutateCampaignBudgets 
 ( 
  
 Long 
 . 
 toString 
 ( 
 customerId 
 ), 
  
 ImmutableList 
 . 
 of 
 ( 
 operation 
 )); 
  
 // Displays the results. 
  
 String 
  
 resourceName 
  
 = 
  
 response 
 . 
 getResults 
 ( 
 0 
 ). 
 getResourceName 
 (); 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
 "Added budget with resource name %s." 
 , 
  
 resourceName 
 ); 
  
 return 
  
 resourceName 
 ; 
  
 } 
  
 } 
  
 /** 
 * Creates a campaign resource. 
 * 
 * @param googleAdsClient: An initialized GoogleAdsClient instance. 
 * @param customerId: A client customer ID. 
 * @param campaignBudget: A budget resource name. 
 */ 
  
 private 
  
 static 
  
 String 
  
 createCampaign 
 ( 
  
 GoogleAdsClient 
  
 googleAdsClient 
 , 
  
 Long 
  
 customerId 
 , 
  
 String 
  
 campaignBudget 
 ) 
  
 { 
  
 // Creates the campaign. 
  
 Campaign 
 . 
 Builder 
  
 campaignBuilder 
  
 = 
  
 Campaign 
 . 
 newBuilder 
 (); 
  
 campaignBuilder 
 . 
 setName 
 ( 
 "Testing RSA via API #" 
  
 + 
  
 getPrintableDateTime 
 ()); 
  
 campaignBuilder 
 . 
 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. 
  
 campaignBuilder 
 . 
 setStatus 
 ( 
 CampaignStatus 
 . 
 PAUSED 
 ); 
  
 // Sets the bidding strategy and budget. The bidding strategy for Maximize Clicks is TargetSpend. 
  
 // The targetSpendMicros is deprecated so don't put any value. See other bidding strategies you 
  
 // can select in the link below. 
  
 // https://developers.google.com/google-ads/api/reference/rpc/latest/Campaign#campaign_bidding_strategy 
  
 campaignBuilder 
 . 
 setTargetSpend 
 ( 
 TargetSpend 
 . 
 newBuilder 
 (). 
 setTargetSpendMicros 
 ( 
 0 
 ). 
 build 
 ()); 
  
 campaignBuilder 
 . 
 setCampaignBudget 
 ( 
 campaignBudget 
 ); 
  
 // Sets the campaign network operations. 
  
 campaignBuilder 
 . 
 setNetworkSettings 
 ( 
  
 NetworkSettings 
 . 
 newBuilder 
 () 
  
 . 
 setTargetGoogleSearch 
 ( 
 true 
 ) 
  
 . 
 setTargetSearchNetwork 
 ( 
 true 
 ) 
  
 . 
 setTargetPartnerSearchNetwork 
 ( 
 false 
 ) 
  
 // Enables Display Expansion on Search campaigns. For more details see: 
  
 // https://support.google.com/google-ads/answer/7193800 
  
 . 
 setTargetContentNetwork 
 ( 
 true 
 ) 
  
 . 
 build 
 ()); 
  
 // Optional: Sets the start date. 
  
 // DateTime startTime = DateTime.now().plusDays(1); 
  
 // campaignBuilder.setStartDate(startTime.toDate().toString()); 
  
 // Optional: Sets the end date. 
  
 // DateTime endTime = startTime.plusWeeks(4); 
  
 // campaignBuilder.setEndDate(endTime.toDate().toString()); 
  
 // Creates the operation. 
  
 CampaignOperation 
  
 operation 
  
 = 
  
 CampaignOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 campaignBuilder 
 . 
 build 
 ()). 
 build 
 (); 
  
 // Gets the CampaignService. 
  
 try 
  
 ( 
 CampaignServiceClient 
  
 campaignServiceClient 
  
 = 
  
 googleAdsClient 
 . 
 getLatestVersion 
 (). 
 createCampaignServiceClient 
 ()) 
  
 { 
  
 // Adds the campaign. 
  
 MutateCampaignsResponse 
  
 response 
  
 = 
  
 campaignServiceClient 
 . 
 mutateCampaigns 
 ( 
  
 Long 
 . 
 toString 
 ( 
 customerId 
 ), 
  
 ImmutableList 
 . 
 of 
 ( 
 operation 
 )); 
  
 String 
  
 resourceName 
  
 = 
  
 response 
 . 
 getResults 
 ( 
 0 
 ). 
 getResourceName 
 (); 
  
 // Displays the result. 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
 "Added campaign with resource name %s" 
 , 
  
 resourceName 
 ); 
  
 return 
  
 resourceName 
 ; 
  
 } 
  
 } 
  
 /** 
 * Creates an ad group. 
 * 
 * @param googleAdsClient: An initialized GoogleAdsClient instance. 
 * @param customerId: A client customer ID. 
 * @param campaignResourceName: An campaign resource name. 
 */ 
  
 private 
  
 static 
  
 String 
  
 createAdGroup 
 ( 
  
 GoogleAdsClient 
  
 googleAdsClient 
 , 
  
 Long 
  
 customerId 
 , 
  
 String 
  
 campaignResourceName 
 ) 
  
 { 
  
 // Creates the ad group. 
  
 AdGroup 
  
 adGroup 
  
 = 
  
 AdGroup 
 . 
 newBuilder 
 () 
  
 . 
 setName 
 ( 
 "Testing RSA via API " 
  
 + 
  
 getPrintableDateTime 
 ()) 
  
 . 
 setStatus 
 ( 
 AdGroupStatus 
 . 
 ENABLED 
 ) 
  
 . 
 setCampaign 
 ( 
 campaignResourceName 
 ) 
  
 . 
 setType 
 ( 
 AdGroupType 
 . 
 SEARCH_STANDARD 
 ) 
  
 . 
 build 
 (); 
  
 // If you want to set up a max CPC bid, uncomment the line below; 
  
 // adGroup = adGroup.toBuilder().setCpcBidMicros(10000000).build(); 
  
 // Creates the operation. 
  
 AdGroupOperation 
  
 operation 
  
 = 
  
 AdGroupOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 adGroup 
 ). 
 build 
 (); 
  
 // Gets the AdGroupService. 
  
 try 
  
 ( 
 AdGroupServiceClient 
  
 adGroupServiceClient 
  
 = 
  
 googleAdsClient 
 . 
 getLatestVersion 
 (). 
 createAdGroupServiceClient 
 ()) 
  
 { 
  
 // Add the ad group. 
  
 MutateAdGroupsResponse 
  
 response 
  
 = 
  
 adGroupServiceClient 
 . 
 mutateAdGroups 
 ( 
  
 Long 
 . 
 toString 
 ( 
 customerId 
 ), 
  
 ImmutableList 
 . 
 of 
 ( 
 operation 
 )); 
  
 // Displays the result. 
  
 String 
  
 resourceName 
  
 = 
  
 response 
 . 
 getResults 
 ( 
 0 
 ). 
 getResourceName 
 (); 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
 "Added ad group with resource name %s." 
 , 
  
 resourceName 
 ); 
  
 return 
  
 resourceName 
 ; 
  
 } 
  
 } 
  
 /** 
 * Creates an ad group ad. 
 * 
 * @param googleAdsClient: An initialized GoogleAdsClient instance. 
 * @param customerId: A client customer ID. 
 * @param adGroupResourceName: An ad group resource name. 
 * @param customizerAttributeName: (optional) If present, indicates the resource name of the 
 *     custoimizer attribute to use in one of the descriptions. 
 */ 
  
 private 
  
 static 
  
 void 
  
 createAdGroupAd 
 ( 
  
 GoogleAdsClient 
  
 googleAdsClient 
 , 
  
 Long 
  
 customerId 
 , 
  
 String 
  
 adGroupResourceName 
 , 
  
 String 
  
 customizerAttributeName 
 ) 
  
 { 
  
 // Creates an ad group ad to hold the ad. 
  
 AdGroupAd 
 . 
 Builder 
  
 adGroupAdBuilder 
  
 = 
  
 AdGroupAd 
 . 
 newBuilder 
 (). 
 setStatus 
 ( 
 AdGroupAdStatus 
 . 
 ENABLED 
 ); 
  
 adGroupAdBuilder 
 . 
 setAdGroup 
 ( 
 adGroupResourceName 
 ); 
  
 // Creates the ad and set responsive search ad info. 
  
 // The list of possible final URLs after all cross-domain redirects for the ad. 
  
 Ad 
 . 
 Builder 
  
 adBuilder 
  
 = 
  
 Ad 
 . 
 newBuilder 
 (). 
 addFinalUrls 
 ( 
 "https://www.example.com/" 
 ); 
  
 // Sets a pinning to always choose this asset for HEADLINE_1. Pinning is optional; if no pinning 
  
 // is set, then headlines and descriptions will be rotated and the ones that perform best will 
  
 // be used more often. 
  
 // Headline 1 
  
 AdTextAsset 
  
 pinned_headline 
  
 = 
  
 createAdTextAsset 
 ( 
 "Headline 1 testing" 
 , 
  
 ServedAssetFieldType 
 . 
 HEADLINE_1 
 ); 
  
 // Headline 2 and 3 
  
 ResponsiveSearchAdInfo 
 . 
 Builder 
  
 responsiveSearchAdBuilder 
  
 = 
  
 ResponsiveSearchAdInfo 
 . 
 newBuilder 
 () 
  
 . 
 addAllHeadlines 
 ( 
  
 ImmutableList 
 . 
 of 
 ( 
  
 pinned_headline 
 , 
  
 createAdTextAsset 
 ( 
 "Headline 2 testing" 
 , 
  
 null 
 ), 
  
 createAdTextAsset 
 ( 
 "Headline 3 testing" 
 , 
  
 null 
 ))); 
  
 // Description 1. 
  
 AdTextAsset 
  
 description1 
  
 = 
  
 createAdTextAsset 
 ( 
 "Desc 1 testing" 
 , 
  
 null 
 ); 
  
 // Creates this particular description using the ad customizer. 
  
 AdTextAsset 
  
 description2 
  
 = 
  
 null 
 ; 
  
 if 
  
 ( 
 customizerAttributeName 
  
 != 
  
 null 
 ) 
  
 { 
  
 description2 
  
 = 
  
 createAdTextAssetWithCustomizer 
 ( 
 customizerAttributeName 
 ); 
  
 } 
  
 else 
  
 { 
  
 description2 
  
 = 
  
 createAdTextAsset 
 ( 
 "Desc 2 testing" 
 , 
  
 null 
 ); 
  
 } 
  
 responsiveSearchAdBuilder 
 . 
 addAllDescriptions 
 ( 
 ImmutableList 
 . 
 of 
 ( 
 description1 
 , 
  
 description2 
 )); 
  
 // Paths 
  
 // First and second part of text that can be appended to the URL in the ad. 
  
 // If you use the examples below, the ad will show https://www.example.com/all-inclusive/deals 
  
 responsiveSearchAdBuilder 
 . 
 setPath1 
 ( 
 "all-inclusive" 
 ); 
  
 responsiveSearchAdBuilder 
 . 
 setPath2 
 ( 
 "deals" 
 ); 
  
 adBuilder 
 . 
 setResponsiveSearchAd 
 ( 
 responsiveSearchAdBuilder 
 ); 
  
 adGroupAdBuilder 
 . 
 setAd 
 ( 
 adBuilder 
 ); 
  
 // Creates an ad group ad operation. 
  
 AdGroupAdOperation 
  
 operation 
  
 = 
  
 AdGroupAdOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 adGroupAdBuilder 
 ). 
 build 
 (); 
  
 // Gets the AdGroupAdService. 
  
 try 
  
 ( 
 AdGroupAdServiceClient 
  
 adGroupAdServiceClient 
  
 = 
  
 googleAdsClient 
 . 
 getLatestVersion 
 (). 
 createAdGroupAdServiceClient 
 ()) 
  
 { 
  
 // Sends a request to the server to add a responsive search ad 
  
 MutateAdGroupAdsResponse 
  
 response 
  
 = 
  
 adGroupAdServiceClient 
 . 
 mutateAdGroupAds 
 ( 
  
 Long 
 . 
 toString 
 ( 
 customerId 
 ), 
  
 ImmutableList 
 . 
 of 
 ( 
 operation 
 )); 
  
 // Displays the result. 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "Created responsive search ad with resource name '%s'.%n" 
 , 
  
 response 
 . 
 getResults 
 ( 
 0 
 ). 
 getResourceName 
 ()); 
  
 } 
  
 } 
  
 /** 
 * Creates keywords. 
 * 
 * <p>For smart bidding, BROAD is the recommended match type. 
 * 
 * @param googleAdsClient: An initialized GoogleAdsClient instance. 
 * @param customerId: A client customer ID. 
 * @param adGroupResourceName: An ad group resource name. 
 */ 
  
 private 
  
 static 
  
 void 
  
 addKeywords 
 ( 
  
 GoogleAdsClient 
  
 googleAdsClient 
 , 
  
 Long 
  
 customerId 
 , 
  
 String 
  
 adGroupResourceName 
 ) 
  
 { 
  
 // Creates keyword. 
  
 AdGroupCriterion 
 . 
 Builder 
  
 keyword 
  
 = 
  
 AdGroupCriterion 
 . 
 newBuilder 
 () 
  
 . 
 setAdGroup 
 ( 
 adGroupResourceName 
 ) 
  
 . 
 setStatus 
 ( 
 AdGroupCriterionStatus 
 . 
 ENABLED 
 ) 
  
 . 
 setKeyword 
 ( 
  
 KeywordInfo 
 . 
 newBuilder 
 () 
  
 . 
 setText 
 ( 
 "example of broad match" 
 ) 
  
 . 
 setMatchType 
 ( 
 KeywordMatchType 
 . 
 BROAD 
 )); 
  
 // Uncomment the below line if you want to change this keyword to a negative target. 
  
 // keyword.setNegative(true); 
  
 // Optional repeated field 
  
 // keyword.setFinalUrls("https://www.example.com"); 
  
 AdGroupCriterionOperation 
  
 operation 
  
 = 
  
 AdGroupCriterionOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 keyword 
 ). 
 build 
 (); 
  
 // Gets the AdGroupCriterionService. 
  
 try 
  
 ( 
 AdGroupCriterionServiceClient 
  
 adGroupCriterionServiceClient 
  
 = 
  
 googleAdsClient 
 . 
 getLatestVersion 
 (). 
 createAdGroupCriterionServiceClient 
 ()) 
  
 { 
  
 // Adds the keyword. 
  
 MutateAdGroupCriteriaResponse 
  
 response 
  
 = 
  
 adGroupCriterionServiceClient 
 . 
 mutateAdGroupCriteria 
 ( 
  
 Long 
 . 
 toString 
 ( 
 customerId 
 ), 
  
 ImmutableList 
 . 
 of 
 ( 
 operation 
 )); 
  
 // Displays the results. 
  
 for 
  
 ( 
 MutateAdGroupCriterionResult 
  
 result 
  
 : 
  
 response 
 . 
 getResultsList 
 ()) 
  
 { 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
 "Created keyword '%s'.%n" 
 , 
  
 result 
 . 
 getResourceName 
 ()); 
  
 } 
  
 } 
  
 } 
  
 /** 
 * Creates geo targets. 
 * 
 * @param googleAdsClient: An initialized GoogleAdsClient instance. 
 * @param customerId: A client customer ID. 
 * @param campaignResourceName: A campaign resource name. 
 */ 
  
 private 
  
 static 
  
 void 
  
 addGeoTargeting 
 ( 
  
 GoogleAdsClient 
  
 googleAdsClient 
 , 
  
 Long 
  
 customerId 
 , 
  
 String 
  
 campaignResourceName 
 ) 
  
 { 
  
 // Searches by location names from GeoTargetConstantService.suggestGeoTargetConstants() and 
  
 // directly apply GeoTargetConstant.resourceName. 
  
 SuggestGeoTargetConstantsRequest 
 . 
 Builder 
  
 gtcRequestBuilder 
  
 = 
  
 SuggestGeoTargetConstantsRequest 
 . 
 newBuilder 
 (). 
 setLocale 
 ( 
 "es" 
 ). 
 setCountryCode 
 ( 
 "AR" 
 ); 
  
 // The location names to get suggested geo target constants. 
  
 gtcRequestBuilder 
 . 
 setLocationNames 
 ( 
  
 LocationNames 
 . 
 newBuilder 
 () 
  
 . 
 addAllNames 
 ( 
 ImmutableList 
 . 
 of 
 ( 
 "Buenos Aires" 
 , 
  
 "San Isidro" 
 , 
  
 "Mar del Plata" 
 )) 
  
 . 
 build 
 ()); 
  
 try 
  
 ( 
 GeoTargetConstantServiceClient 
  
 geoTargetConstantServiceClient 
  
 = 
  
 googleAdsClient 
 . 
 getLatestVersion 
 (). 
 createGeoTargetConstantServiceClient 
 ()) 
  
 { 
  
 SuggestGeoTargetConstantsResponse 
  
 results 
  
 = 
  
 geoTargetConstantServiceClient 
 . 
 suggestGeoTargetConstants 
 ( 
 gtcRequestBuilder 
 . 
 build 
 ()); 
  
 ArrayList<CampaignCriterionOperation> 
  
 operations 
  
 = 
  
 new 
  
 ArrayList<CampaignCriterionOperation> 
 (); 
  
 for 
  
 ( 
 GeoTargetConstantSuggestion 
  
 suggestion 
  
 : 
  
 results 
 . 
 getGeoTargetConstantSuggestionsList 
 ()) 
  
 { 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "geoTargetConstant: %s is found in LOCALE %s with reach %s from search term %s." 
 , 
  
 suggestion 
 . 
 getGeoTargetConstant 
 (). 
 getResourceName 
 (), 
  
 suggestion 
 . 
 getLocale 
 (), 
  
 suggestion 
 . 
 getReach 
 (), 
  
 suggestion 
 . 
 getSearchTerm 
 ()); 
  
 // Creates the campaign criterion for loaction targeting. 
  
 CampaignCriterion 
  
 campaignCriterion 
  
 = 
  
 CampaignCriterion 
 . 
 newBuilder 
 () 
  
 . 
 setCampaign 
 ( 
 campaignResourceName 
 ) 
  
 . 
 setLocation 
 ( 
  
 LocationInfo 
 . 
 newBuilder 
 () 
  
 . 
 setGeoTargetConstant 
 ( 
 suggestion 
 . 
 getGeoTargetConstant 
 (). 
 getResourceName 
 ()) 
  
 . 
 build 
 ()) 
  
 . 
 build 
 (); 
  
 CampaignCriterionOperation 
  
 operation 
  
 = 
  
 CampaignCriterionOperation 
 . 
 newBuilder 
 (). 
 setCreate 
 ( 
 campaignCriterion 
 ). 
 build 
 (); 
  
 operations 
 . 
 add 
 ( 
 operation 
 ); 
  
 } 
  
 // Gets the CampaignCriterionService. 
  
 try 
  
 ( 
 CampaignCriterionServiceClient 
  
 campaignCriterionServiceClient 
  
 = 
  
 googleAdsClient 
 . 
 getLatestVersion 
 (). 
 createCampaignCriterionServiceClient 
 ()) 
  
 { 
  
 MutateCampaignCriteriaResponse 
  
 response 
  
 = 
  
 campaignCriterionServiceClient 
 . 
 mutateCampaignCriteria 
 ( 
  
 Long 
 . 
 toString 
 ( 
 customerId 
 ), 
  
 operations 
 ); 
  
 // Displays the results. 
  
 for 
  
 ( 
 MutateCampaignCriterionResult 
  
 result 
  
 : 
  
 response 
 . 
 getResultsList 
 ()) 
  
 { 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
 "Added campaign criterion %s" 
 , 
  
 result 
 . 
 getResourceName 
 ()); 
  
 } 
  
 } 
  
 } 
  
 } 
 } 
  
  

C#

 // Copyright 2021 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.Gax.Util 
 ; 
 using 
  
 Google.Ads.GoogleAds.Lib 
 ; 
 using 
  
 Google.Ads.GoogleAds.V22.Common 
 ; 
 using 
  
 Google.Ads.GoogleAds.V22.Resources 
 ; 
 using 
  
 Google.Ads.GoogleAds.V22.Services 
 ; 
 using 
  
 System.Collections.Generic 
 ; 
 using 
  
 System.Linq 
 ; 
 using 
  
 System 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V22 
 . 
 Enums 
 . 
 AdGroupTypeEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V22 
 . 
 Enums 
 . 
 AdGroupAdStatusEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V22 
 . 
 Enums 
 . 
 AdGroupCriterionStatusEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V22 
 . 
 Enums 
 . 
 AdGroupStatusEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V22 
 . 
 Enums 
 . 
 AdvertisingChannelTypeEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V22 
 . 
 Enums 
 . 
 BudgetDeliveryMethodEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V22 
 . 
 Enums 
 . 
 CampaignStatusEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V22 
 . 
 Enums 
 . 
 CustomizerAttributeTypeEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V22 
 . 
 Enums 
 . 
 KeywordMatchTypeEnum 
 . 
 Types 
 ; 
 using 
  
 static 
  
 Google 
 . 
 Ads 
 . 
 GoogleAds 
 . 
 V22 
 . 
 Services 
 . 
 SuggestGeoTargetConstantsRequest 
 . 
 Types 
 ; 
 using 
  
 Google.Ads.GoogleAds.Config 
 ; 
 using 
  
 Google.Ads.GoogleAds.Extensions.Config 
 ; 
 namespace 
  
 Google.Ads.GoogleAds.Examples.V22 
 { 
  
 /// <summary> 
  
 /// Adds a customizer attribute, links the customizer attribute to a customer, and then adds 
  
 /// a responsive search ad with a description using the ad customizer to the specified ad group. 
  
 /// </summary> 
  
 public 
  
 class 
  
 AddResponsiveSearchAdFull 
  
 : 
  
 ExampleBase 
  
 { 
  
 /// <summary> 
  
 /// </summary> 
  
 public 
  
 class 
  
 Options 
  
 : 
  
 OptionsBase 
  
 { 
  
 /// <summary> 
  
 /// The Google Ads customer ID. 
  
 /// </summary> 
  
 [Option("customerId", Required = true, HelpText = 
 "The Google Ads customer ID.")] 
  
 public 
  
 long 
  
 CustomerId 
  
 { 
  
 get 
 ; 
  
 set 
 ; 
  
 } 
  
 /// <summary> 
  
 /// The Google Ads customizer attribute name ID. 
  
 /// </summary> 
  
 [Option("customizerAttributeName", Required = false, HelpText = 
 "The Google Ads customizer attribute name.", Default = CUSTOMIZER_ATTRIBUTE_NAME)] 
  
 public 
  
 string 
  
 CustomizerAttributeName 
  
 { 
  
 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 
 ); 
  
 AddResponsiveSearchAdFull 
  
 codeExample 
  
 = 
  
 new 
  
 AddResponsiveSearchAdFull 
 (); 
  
 Console 
 . 
 WriteLine 
 ( 
 codeExample 
 . 
 Description 
 ); 
  
 codeExample 
 . 
 Run 
 ( 
  
 new 
  
 GoogleAdsClient 
 (), 
  
 options 
 . 
 CustomerId 
 , 
  
 options 
 . 
 CustomizerAttributeName 
  
 ); 
  
 } 
  
 // The name of the customizer attribute to be used in the ad customizer must be unique for a 
  
 // given client account. To run this example multiple times, change this value or specify 
  
 // its corresponding argument. Note that there is a limit for the number of enabled 
  
 // customizer attributes in one account, so you shouldn't run this example more than 
  
 // necessary. 
  
 // 
  
 // Visit the following link for more details: 
  
 // https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads#rules_and_limitations 
  
 private 
  
 const 
  
 string 
  
 CUSTOMIZER_ATTRIBUTE_NAME 
  
 = 
  
 "Price" 
 ; 
  
 /// <summary> 
  
 /// Returns a description about the code example. 
  
 /// </summary> 
  
 public 
  
 override 
  
 string 
  
 Description 
  
 = 
>  
 "Adds a customizer attribute, links the customizer attribute to a customer, and then " 
  
 + 
  
 "adds a responsive search ad with a description using the ad customizer to the " 
  
 + 
  
 "specified ad group." 
 ; 
  
 /// <summary> 
  
 /// Runs the example. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads client.</param> 
  
 /// <param name="customerId">The Google Ads customer ID.</param> 
  
 /// <param name="customizerAttributeName">The customizer attribute name.</param> 
  
 public 
  
 void 
  
 Run 
 ( 
  
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 customizerAttributeName 
 ) 
  
 { 
  
 string 
  
 customizerAttributeResourceName 
  
 = 
  
 CreateCustomizerAttribute 
 ( 
  
 client 
 , 
  
 customerId 
 , 
  
 customizerAttributeName 
  
 ); 
  
 LinkCustomizerAttributeToCustomer 
 ( 
 client 
 , 
  
 customerId 
 , 
  
 customizerAttributeResourceName 
 ); 
  
 string 
  
 campaignBudgetResourceName 
  
 = 
  
 AddCampaignBudget 
 ( 
 client 
 , 
  
 customerId 
 ); 
  
 string 
  
 campaignResourceName 
  
 = 
  
 AddCampaign 
 ( 
 client 
 , 
  
 customerId 
 , 
  
 campaignBudgetResourceName 
 ); 
  
 string 
  
 adGroupResourceName 
  
 = 
  
 AddAdGroup 
 ( 
 client 
 , 
  
 customerId 
 , 
  
 campaignResourceName 
 ); 
  
 CreateResponsiveSearchAdWithCustomization 
 ( 
  
 client 
 , 
  
 customerId 
 , 
  
 adGroupResourceName 
 , 
  
 customizerAttributeName 
  
 ); 
  
 AddKeywords 
 ( 
 client 
 , 
  
 customerId 
 , 
  
 adGroupResourceName 
 ); 
  
 AddGeoTargeting 
 ( 
 client 
 , 
  
 customerId 
 , 
  
 campaignResourceName 
 ); 
  
 } 
  
 /// <summary> 
  
 /// Creates a customizer attribute with the specified customizer attribute name. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads API client.</param> 
  
 /// <param name="customerId">The customer ID.</param> 
  
 /// <param name="customizerAttributeName">The name of the customizer attribute.</param> 
  
 /// <returns>The created customizer attribute resource name.</returns> 
  
 private 
  
 string 
  
 CreateCustomizerAttribute 
 ( 
  
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 customizerAttributeName 
 ) 
  
 { 
  
 // Creates a customizer attribute operation for creating a customizer attribute. 
  
 CustomizerAttributeOperation 
  
 operation 
  
 = 
  
 new 
  
 CustomizerAttributeOperation 
 () 
  
 { 
  
 // Creates a customizer attribute with the specified name. 
  
 Create 
  
 = 
  
 new 
  
 CustomizerAttribute 
 () 
  
 { 
  
 Name 
  
 = 
  
 customizerAttributeName 
 , 
  
 // Specifies the type to be 'PRICE' so that we can dynamically customize the part of 
  
 // the ad's description that is a price of a product/service we advertise. 
  
 Type 
  
 = 
  
 CustomizerAttributeType 
 . 
 Price 
  
 } 
  
 }; 
  
 CustomizerAttributeServiceClient 
  
 serviceClient 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V22 
 . 
 CustomizerAttributeService 
 ); 
  
 // Issues a mutate request to add the customizer attribute and prints its information. 
  
 MutateCustomizerAttributesResponse 
  
 response 
  
 = 
  
 serviceClient 
 . 
 MutateCustomizerAttributes 
 ( 
  
 customerId 
 . 
 ToString 
 (), 
  
 new 
  
 [] 
  
 { 
  
 operation 
  
 }. 
 ToList 
 () 
  
 ); 
  
 string 
  
 resourceName 
  
 = 
  
 response 
 . 
 Results 
 [ 
 0 
 ]. 
 ResourceName 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Added a customizer attribute with resource name '{resourceName}'." 
 ); 
  
 return 
  
 resourceName 
 ; 
  
 } 
  
 /// <summary> 
  
 /// Links the customizer attribute to the customer by providing a value to be used in a 
  
 /// responsive search ad that will be created in a later step. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads API client.</param> 
  
 /// <param name="customerId">The customer ID.</param> 
  
 /// <param name="customizerAttributeResourceName">The resource name of the customizer 
  
 /// attribute.</param> 
  
 private 
  
 void 
  
 LinkCustomizerAttributeToCustomer 
 ( 
  
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 customizerAttributeResourceName 
 ) 
  
 { 
  
 // Creates a customer customizer operation. 
  
 CustomerCustomizerOperation 
  
 operation 
  
 = 
  
 new 
  
 CustomerCustomizerOperation 
 () 
  
 { 
  
 // Creates a customer customizer with the value to be used in the responsive search 
  
 // ad. 
  
 Create 
  
 = 
  
 new 
  
 CustomerCustomizer 
 () 
  
 { 
  
 CustomizerAttribute 
  
 = 
  
 customizerAttributeResourceName 
 , 
  
 Value 
  
 = 
  
 new 
  
 CustomizerValue 
 () 
  
 { 
  
 Type 
  
 = 
  
 CustomizerAttributeType 
 . 
 Price 
 , 
  
 // Specify '100USD' as a text value. The ad customizer will dynamically 
  
 // replace the placeholder with this value when the ad serves. 
  
 StringValue 
  
 = 
  
 "100USD" 
  
 } 
  
 } 
  
 }; 
  
 CustomerCustomizerServiceClient 
  
 serviceClient 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V22 
 . 
 CustomerCustomizerService 
 ); 
  
 // Issues a mutate request to add the customer customizer and prints its information. 
  
 MutateCustomerCustomizersResponse 
  
 response 
  
 = 
  
 serviceClient 
 . 
 MutateCustomerCustomizers 
 ( 
  
 customerId 
 . 
 ToString 
 (), 
  
 new 
  
 [] 
  
 { 
  
 operation 
  
 }. 
 ToList 
 () 
  
 ); 
  
 string 
  
 resourceName 
  
 = 
  
 response 
 . 
 Results 
 [ 
 0 
 ]. 
 ResourceName 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Added a customer customizer with resource name '{resourceName}'." 
 ); 
  
 } 
  
 /// <summary> 
  
 /// Adds a campaign budget. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads client.</param> 
  
 /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> 
  
 /// <returns>The campaign budget resource name.</returns> 
  
 private 
  
 static 
  
 string 
  
 AddCampaignBudget 
 ( 
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 ) 
  
 { 
  
 // Get the CampaignBudgetService. 
  
 CampaignBudgetServiceClient 
  
 campaignBudgetService 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V22 
 . 
 CampaignBudgetService 
 ); 
  
 // Create the budget. 
  
 CampaignBudget 
  
 campaignBudget 
  
 = 
  
 new 
  
 CampaignBudget 
 () 
  
 { 
  
 Name 
  
 = 
  
 "Interplanetary Cruise Budget #" 
  
 + 
  
 ExampleUtilities 
 . 
 GetRandomString 
 (), 
  
 AmountMicros 
  
 = 
  
 3 
 _000_000 
 , 
  
 DeliveryMethod 
  
 = 
  
 BudgetDeliveryMethod 
 . 
 Standard 
  
 }; 
  
 // Create the operation. 
  
 CampaignBudgetOperation 
  
 operation 
  
 = 
  
 new 
  
 CampaignBudgetOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 campaignBudget 
  
 }; 
  
 // Add the campaign budget. 
  
 MutateCampaignBudgetsResponse 
  
 response 
  
 = 
  
 campaignBudgetService 
 . 
 MutateCampaignBudgets 
 ( 
 customerId 
 . 
 ToString 
 (), 
  
 new 
  
 CampaignBudgetOperation 
 [] 
  
 { 
  
 operation 
  
 }); 
  
 // Display the result. 
  
 string 
  
 budgetResourceName 
  
 = 
  
 response 
 . 
 Results 
 [ 
 0 
 ]. 
 ResourceName 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Added budget with resource name '{budgetResourceName}'." 
 ); 
  
 return 
  
 budgetResourceName 
 ; 
  
 } 
  
 /// <summary> 
  
 /// Adds a campaign. 
  
 /// </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="budgetResourceName">The campaign budget resource name.</param> 
  
 /// <returns>The campaign resource name.</returns> 
  
 private 
  
 static 
  
 string 
  
 AddCampaign 
 ( 
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 budgetResourceName 
 ) 
  
 { 
  
 // Get the CampaignService. 
  
 CampaignServiceClient 
  
 campaignService 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V22 
 . 
 CampaignService 
 ); 
  
 // Create the campaign. 
  
 Campaign 
  
 campaign 
  
 = 
  
 new 
  
 Campaign 
 () 
  
 { 
  
 Name 
  
 = 
  
 "Testing RSA via API #" 
  
 + 
  
 ExampleUtilities 
 . 
 GetRandomString 
 (), 
  
 AdvertisingChannelType 
  
 = 
  
 AdvertisingChannelType 
 . 
 Search 
 , 
  
 Status 
  
 = 
  
 CampaignStatus 
 . 
 Paused 
 , 
  
 ManualCpc 
  
 = 
  
 new 
  
 ManualCpc 
 (), 
  
 NetworkSettings 
  
 = 
  
 new 
  
 Campaign 
 . 
 Types 
 . 
 NetworkSettings 
 () 
  
 { 
  
 TargetGoogleSearch 
  
 = 
  
 true 
 , 
  
 TargetSearchNetwork 
  
 = 
  
 true 
 , 
  
 TargetPartnerSearchNetwork 
  
 = 
  
 false 
 , 
  
 // Enable Display Expansion on Search campaigns. For more details see: 
  
 // https://support.google.com/google-ads/answer/7193800 
  
 TargetContentNetwork 
  
 = 
  
 true 
  
 }, 
  
 CampaignBudget 
  
 = 
  
 budgetResourceName 
 , 
  
 StartDate 
  
 = 
  
 DateTime 
 . 
 Now 
 . 
 AddDays 
 ( 
 1 
 ). 
 ToString 
 ( 
 "yyyyMMdd" 
 ), 
  
 EndDate 
  
 = 
  
 DateTime 
 . 
 Now 
 . 
 AddDays 
 ( 
 30 
 ). 
 ToString 
 ( 
 "yyyyMMdd" 
 ) 
  
 }; 
  
 // Create the operation. 
  
 CampaignOperation 
  
 operation 
  
 = 
  
 new 
  
 CampaignOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 campaign 
  
 }; 
  
 // Add the campaign. 
  
 MutateCampaignsResponse 
  
 response 
  
 = 
  
 campaignService 
 . 
 MutateCampaigns 
 ( 
 customerId 
 . 
 ToString 
 (), 
  
 new 
  
 CampaignOperation 
 [] 
  
 { 
  
 operation 
  
 }); 
  
 // Displays the result. 
  
 string 
  
 campaignResourceName 
  
 = 
  
 response 
 . 
 Results 
 [ 
 0 
 ]. 
 ResourceName 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Added campaign with resource name '{campaignResourceName}'." 
 ); 
  
 return 
  
 campaignResourceName 
 ; 
  
 } 
  
 /// <summary>Adds an 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="campaignResourceName">The campaign resource name.</param> 
  
 /// <returns>The ad group resource name.</returns> 
  
 private 
  
 static 
  
 string 
  
 AddAdGroup 
 ( 
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 campaignResourceName 
 ) 
  
 { 
  
 // Get the AdGroupService. 
  
 AdGroupServiceClient 
  
 adGroupService 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V22 
 . 
 AdGroupService 
 ); 
  
 // Create the ad group. 
  
 AdGroup 
  
 adGroup 
  
 = 
  
 new 
  
 AdGroup 
 () 
  
 { 
  
 Name 
  
 = 
  
 "Testing RSA via API #" 
  
 + 
  
 ExampleUtilities 
 . 
 GetRandomString 
 (), 
  
 Campaign 
  
 = 
  
 campaignResourceName 
 , 
  
 Type 
  
 = 
  
 AdGroupType 
 . 
 SearchStandard 
 , 
  
 Status 
  
 = 
  
 AdGroupStatus 
 . 
 Enabled 
 , 
  
 // If you want to set up a max CPC bid, uncomment the line below. 
  
 // CpcBidMicros = 50_000 
  
 }; 
  
 // Create the operation. 
  
 AdGroupOperation 
  
 operation 
  
 = 
  
 new 
  
 AdGroupOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 adGroup 
  
 }; 
  
 // Add the ad group. 
  
 MutateAdGroupsResponse 
  
 response 
  
 = 
  
 adGroupService 
 . 
 MutateAdGroups 
 ( 
 customerId 
 . 
 ToString 
 (), 
  
 new 
  
 AdGroupOperation 
 [] 
  
 { 
  
 operation 
  
 }); 
  
 // Display the results. 
  
 string 
  
 adGroupResourceName 
  
 = 
  
 response 
 . 
 Results 
 [ 
 0 
 ]. 
 ResourceName 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Added ad group with resource name '{adGroupResourceName}'." 
 ); 
  
 return 
  
 adGroupResourceName 
 ; 
  
 } 
  
 /// <summary> 
  
 /// Creates a responsive search ad that uses the specified customizer attribute. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads API client.</param> 
  
 /// <param name="customerId">The customer ID.</param> 
  
 /// <param name="adGroupResourceName">The resource name of the ad group.</param> 
  
 /// <param name="customizerAttributeName">The name of the customizer attribute.</param> 
  
 private 
  
 void 
  
 CreateResponsiveSearchAdWithCustomization 
 ( 
  
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 adGroupResourceName 
 , 
  
 string 
  
 customizerAttributeName 
 ) 
  
 { 
  
 // Creates an ad group ad operation. 
  
 AdGroupAdOperation 
  
 operation 
  
 = 
  
 new 
  
 AdGroupAdOperation 
 () 
  
 { 
  
 // Creates an ad group ad to hold the ad. 
  
 Create 
  
 = 
  
 new 
  
 AdGroupAd 
 () 
  
 { 
  
 AdGroup 
  
 = 
  
 adGroupResourceName 
 , 
  
 Status 
  
 = 
  
 AdGroupAdStatus 
 . 
 Enabled 
 , 
  
 // Creates an ad and sets responsive search ad info. 
  
 Ad 
  
 = 
  
 new 
  
 Ad 
 () 
  
 { 
  
 ResponsiveSearchAd 
  
 = 
  
 new 
  
 ResponsiveSearchAdInfo 
 () 
  
 { 
  
 Headlines 
  
 = 
  
 { 
  
 // Sets a pinning to always choose this asset for HEADLINE_1. 
  
 // Pinning is optional; if no pinning is set, then headlines and 
  
 // descriptions will be rotated and the ones that perform best will 
  
 //be used more often. 
  
 new 
  
 AdTextAsset 
 () 
  
 { 
  
 Text 
  
 = 
  
 "Cruise to Mars" 
  
 }, 
  
 new 
  
 AdTextAsset 
 () 
  
 { 
  
 Text 
  
 = 
  
 "Best Space Cruise Line" 
  
 }, 
  
 new 
  
 AdTextAsset 
 () 
  
 { 
  
 Text 
  
 = 
  
 "Experience the Stars" 
  
 } 
  
 }, 
  
 Descriptions 
  
 = 
  
 { 
  
 new 
  
 AdTextAsset 
 () 
  
 { 
  
 Text 
  
 = 
  
 "Buy your tickets now" 
  
 }, 
  
 // Creates this particular description using the ad customizer. For 
  
 // details about the placeholder format, visit the following: 
  
 // https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads#ad_customizers_in_responsive_search_ads 
  
 // 
  
 // The ad customizer replaces the placeholder with the value we 
  
 // previously created and linked to the customer using 
  
 // `CustomerCustomizer`. 
  
 new 
  
 AdTextAsset 
 () 
  
 { 
  
 Text 
  
 = 
  
 $"Just {{CUSTOMIZER.{customizerAttributeName}:10USD}}" 
  
 } 
  
 }, 
  
 Path1 
  
 = 
  
 "all-inclusive" 
 , 
  
 Path2 
  
 = 
  
 "deals" 
  
 }, 
  
 FinalUrls 
  
 = 
  
 { 
  
 "http://www.example.com" 
  
 } 
  
 } 
  
 } 
  
 }; 
  
 // Issues a mutate request to add the ad group ad and prints its information. 
  
 AdGroupAdServiceClient 
  
 serviceClient 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V22 
 . 
 AdGroupAdService 
 ); 
  
 MutateAdGroupAdsResponse 
  
 response 
  
 = 
  
 serviceClient 
 . 
 MutateAdGroupAds 
 ( 
  
 customerId 
 . 
 ToString 
 (), 
  
 new 
  
 [] 
  
 { 
  
 operation 
  
 }. 
 ToList 
 () 
  
 ); 
  
 string 
  
 resourceName 
  
 = 
  
 response 
 . 
 Results 
 [ 
 0 
 ]. 
 ResourceName 
 ; 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Created responsive search ad with resource name '{resourceName}'." 
 ); 
  
 } 
  
 /// <summary> 
  
 /// Creates 3 keyword match types: EXACT, PHRASE, and BROAD. 
  
 /// EXACT: ads may show on searches that ARE the same meaning as your keyword. 
  
 /// PHRASE: ads may show on searches that INCLUDE the meaning of your keyword. 
  
 /// BROAD: ads may show on searches that RELATE to your keyword. 
  
 /// For smart bidding, BROAD is the recommended one. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads API client.</param> 
  
 /// <param name="customerId">The customer ID.</param> 
  
 /// <param name="adGroupResourceName">The resource name of the ad group.</param> 
  
 private 
  
 void 
  
 AddKeywords 
 ( 
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 adGroupResourceName 
 ) 
  
 { 
  
 // Get the AdGroupCriterionService. 
  
 AdGroupCriterionServiceClient 
  
 adGroupCriterionService 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V22 
 . 
 AdGroupCriterionService 
 ); 
  
 List<AdGroupCriterionOperation> 
  
 operations 
  
 = 
  
 new 
  
 List<AdGroupCriterionOperation> 
 (); 
  
 AdGroupCriterionOperation 
  
 exactMatchOperation 
  
 = 
  
 new 
  
 AdGroupCriterionOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 new 
  
 AdGroupCriterion 
 () 
  
 { 
  
 AdGroup 
  
 = 
  
 adGroupResourceName 
 , 
  
 Status 
  
 = 
  
 AdGroupCriterionStatus 
 . 
 Enabled 
 , 
  
 Keyword 
  
 = 
  
 new 
  
 KeywordInfo 
 () 
  
 { 
  
 Text 
  
 = 
  
 "example of exact match" 
 , 
  
 MatchType 
  
 = 
  
 KeywordMatchType 
 . 
 Exact 
  
 }, 
  
 // Uncomment the line below if you want to change this keyword to a negative 
  
 // target. 
  
 // Negative = true 
  
 } 
  
 }; 
  
 // Optional repeated field 
  
 // exactMatchOperation.Create.FinalUrls.Add("https://www.example.com"); 
  
 operations 
 . 
 Add 
 ( 
 exactMatchOperation 
 ); 
  
 AdGroupCriterionOperation 
  
 phraseMatchOperation 
  
 = 
  
 new 
  
 AdGroupCriterionOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 new 
  
 AdGroupCriterion 
 () 
  
 { 
  
 AdGroup 
  
 = 
  
 adGroupResourceName 
 , 
  
 Status 
  
 = 
  
 AdGroupCriterionStatus 
 . 
 Enabled 
 , 
  
 Keyword 
  
 = 
  
 new 
  
 KeywordInfo 
 () 
  
 { 
  
 Text 
  
 = 
  
 "example of phrase match" 
 , 
  
 MatchType 
  
 = 
  
 KeywordMatchType 
 . 
 Phrase 
  
 }, 
  
 // Uncomment the line below if you want to change this keyword to a negative 
  
 // target. 
  
 // Negative = true 
  
 } 
  
 }; 
  
 // Optional repeated field 
  
 // phraseMatchOperation.Create.FinalUrls.Add("https://www.example.com"); 
  
 operations 
 . 
 Add 
 ( 
 phraseMatchOperation 
 ); 
  
 AdGroupCriterionOperation 
  
 broadMatchOperation 
  
 = 
  
 new 
  
 AdGroupCriterionOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 new 
  
 AdGroupCriterion 
 () 
  
 { 
  
 AdGroup 
  
 = 
  
 adGroupResourceName 
 , 
  
 Status 
  
 = 
  
 AdGroupCriterionStatus 
 . 
 Enabled 
 , 
  
 Keyword 
  
 = 
  
 new 
  
 KeywordInfo 
 () 
  
 { 
  
 Text 
  
 = 
  
 "example of broad match" 
 , 
  
 MatchType 
  
 = 
  
 KeywordMatchType 
 . 
 Broad 
  
 }, 
  
 // Uncomment the line below if you want to change this keyword to a negative 
  
 // target. 
  
 // Negative = true 
  
 } 
  
 }; 
  
 // Optional repeated field 
  
 // broadMatchOperation.Create.FinalUrls.Add("https://www.example.com"); 
  
 operations 
 . 
 Add 
 ( 
 broadMatchOperation 
 ); 
  
 MutateAdGroupCriteriaResponse 
  
 response 
  
 = 
  
 adGroupCriterionService 
 . 
 MutateAdGroupCriteria 
 ( 
 customerId 
 . 
 ToString 
 (), 
  
 operations 
 ); 
  
 // Display the results. 
  
 foreach 
  
 ( 
 MutateAdGroupCriterionResult 
  
 newAdGroupCriterion 
  
 in 
  
 response 
 . 
 Results 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 "Keyword with resource name '{0}' was created." 
 , 
  
 newAdGroupCriterion 
 . 
 ResourceName 
 ); 
  
 } 
  
 } 
  
 /// <summary> 
  
 /// Creates geo targets. 
  
 /// </summary> 
  
 /// <param name="client">The Google Ads API client.</param> 
  
 /// <param name="customerId">The customer ID.</param> 
  
 /// <param name="campaignResourceName">The resource name of the campaign.</param> 
  
 private 
  
 void 
  
 AddGeoTargeting 
 ( 
 GoogleAdsClient 
  
 client 
 , 
  
 long 
  
 customerId 
 , 
  
 string 
  
 campaignResourceName 
 ) 
  
 { 
  
 GeoTargetConstantServiceClient 
  
 geoTargetConstantService 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V22 
 . 
 GeoTargetConstantService 
 ); 
  
 SuggestGeoTargetConstantsRequest 
  
 suggestGeoTargetConstantsRequest 
  
 = 
  
 new 
  
 SuggestGeoTargetConstantsRequest 
 () 
  
 { 
  
 // Locale uses the ISO 639-1 format. 
  
 Locale 
  
 = 
  
 "es" 
 , 
  
 // A list of available country codes can be referenced here: 
  
 // https://developers.google.com/google-ads/api/reference/data/geotargets 
  
 CountryCode 
  
 = 
  
 "AR" 
 , 
  
 LocationNames 
  
 = 
  
 new 
  
 LocationNames 
 () 
  
 { 
  
 Names 
  
 = 
  
 { 
 "Buenos aires" 
 , 
  
 "San Isidro" 
 , 
  
 "Mar del Plata" 
 } 
  
 } 
  
 }; 
  
 SuggestGeoTargetConstantsResponse 
  
 suggestGeoTargetConstantsResponse 
  
 = 
  
 geoTargetConstantService 
 . 
 SuggestGeoTargetConstants 
 ( 
  
 suggestGeoTargetConstantsRequest 
 ); 
  
 List<CampaignCriterionOperation> 
  
 operations 
  
 = 
  
 new 
  
 List<CampaignCriterionOperation> 
 (); 
  
 foreach 
  
 ( 
 GeoTargetConstantSuggestion 
  
 suggestion 
  
 in 
  
 suggestGeoTargetConstantsResponse 
 . 
 GeoTargetConstantSuggestions 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Geo target constant: {suggestion.GeoTargetConstant.Name} was " 
  
 + 
  
 $"found in locale ({suggestion.Locale}) with reach ({suggestion.Reach}) from " 
  
 + 
  
 $"search term ({suggestion.SearchTerm})" 
 ); 
  
 CampaignCriterionOperation 
  
 operation 
  
 = 
  
 new 
  
 CampaignCriterionOperation 
 () 
  
 { 
  
 Create 
  
 = 
  
 new 
  
 CampaignCriterion 
 () 
  
 { 
  
 Campaign 
  
 = 
  
 campaignResourceName 
 , 
  
 Location 
  
 = 
  
 new 
  
 LocationInfo 
 () 
  
 { 
  
 GeoTargetConstant 
  
 = 
  
 suggestion 
 . 
 GeoTargetConstant 
 . 
 ResourceName 
  
 } 
  
 } 
  
 }; 
  
 operations 
 . 
 Add 
 ( 
 operation 
 ); 
  
 } 
  
 CampaignCriterionServiceClient 
  
 campaignCriterionService 
  
 = 
  
 client 
 . 
 GetService 
 ( 
 Services 
 . 
 V22 
 . 
 CampaignCriterionService 
 ); 
  
 MutateCampaignCriteriaResponse 
  
 mutateCampaignCriteriaResponse 
  
 = 
  
 campaignCriterionService 
 . 
 MutateCampaignCriteria 
 ( 
 customerId 
 . 
 ToString 
 (), 
  
 operations 
 ); 
  
 foreach 
  
 ( 
 MutateCampaignCriterionResult 
  
 result 
  
 in 
  
 mutateCampaignCriteriaResponse 
 . 
 Results 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 $"Added campaign criterion {result.ResourceName}" 
 ); 
  
 } 
  
 } 
  
 } 
 } 
  
  

PHP

This example is not yet available in PHP; you can take a look at the other languages.

Python

 #!/usr/bin/env python 
 # Copyright 2023 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 shows how to create a complete Responsive Search ad. 
 Includes creation of: budget, campaign, ad group, ad group ad, 
 keywords, and geo targeting. 
 More details on Responsive Search ads can be found here: 
 https://support.google.com/google-ads/answer/7684791 
 """ 
 import 
  
 argparse 
 import 
  
 sys 
 import 
  
 uuid 
 from 
  
 typing 
  
 import 
 List 
 , 
 Optional 
 from 
  
 google.ads.googleads.client 
  
 import 
 GoogleAdsClient 
 from 
  
 google.ads.googleads.errors 
  
 import 
 GoogleAdsException 
 from 
  
 google.ads.googleads.v22.common.types.ad_asset 
  
 import 
 AdTextAsset 
 from 
  
 google.ads.googleads.v22.enums.types.served_asset_field_type 
  
 import 
 ( 
 ServedAssetFieldTypeEnum 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.resources.types.ad_group 
  
 import 
 AdGroup 
 from 
  
 google.ads.googleads.v22.resources.types.ad_group_ad 
  
 import 
 AdGroupAd 
 from 
  
 google.ads.googleads.v22.resources.types.ad_group_criterion 
  
 import 
 ( 
 AdGroupCriterion 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.resources.types.campaign 
  
 import 
 Campaign 
 from 
  
 google.ads.googleads.v22.resources.types.campaign_budget 
  
 import 
 ( 
 CampaignBudget 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.resources.types.campaign_criterion 
  
 import 
 ( 
 CampaignCriterion 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.resources.types.customer_customizer 
  
 import 
 ( 
 CustomerCustomizer 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.resources.types.customizer_attribute 
  
 import 
 ( 
 CustomizerAttribute 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.services.services.ad_group_ad_service 
  
 import 
 ( 
 AdGroupAdServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.services.services.ad_group_criterion_service 
  
 import 
 ( 
 AdGroupCriterionServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.services.services.ad_group_service 
  
 import 
 ( 
 AdGroupServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.services.services.campaign_budget_service 
  
 import 
 ( 
 CampaignBudgetServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.services.services.campaign_criterion_service 
  
 import 
 ( 
 CampaignCriterionServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.services.services.campaign_service 
  
 import 
 ( 
 CampaignServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.services.services.customer_customizer_service 
  
 import 
 ( 
 CustomerCustomizerServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.services.services.customizer_attribute_service 
  
 import 
 ( 
 CustomizerAttributeServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.services.services.geo_target_constant_service 
  
 import 
 ( 
 GeoTargetConstantServiceClient 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.services.types.geo_target_constant_service 
  
 import 
 ( 
 SuggestGeoTargetConstantsRequest 
 , 
 SuggestGeoTargetConstantsResponse 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.services.types.ad_group_ad_service 
  
 import 
 ( 
 AdGroupAdOperation 
 , 
 MutateAdGroupAdsResponse 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.services.types.ad_group_criterion_service 
  
 import 
 ( 
 AdGroupCriterionOperation 
 , 
 MutateAdGroupCriteriaResponse 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.services.types.ad_group_service 
  
 import 
 ( 
 AdGroupOperation 
 , 
 MutateAdGroupsResponse 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.services.types.campaign_budget_service 
  
 import 
 ( 
 CampaignBudgetOperation 
 , 
 MutateCampaignBudgetsResponse 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.services.types.campaign_criterion_service 
  
 import 
 ( 
 CampaignCriterionOperation 
 , 
 MutateCampaignCriteriaResponse 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.services.types.campaign_service 
  
 import 
 ( 
 CampaignOperation 
 , 
 MutateCampaignsResponse 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.services.types.customer_customizer_service 
  
 import 
 ( 
 CustomerCustomizerOperation 
 , 
 MutateCustomerCustomizersResponse 
 , 
 ) 
 from 
  
 google.ads.googleads.v22.services.types.customizer_attribute_service 
  
 import 
 ( 
 CustomizerAttributeOperation 
 , 
 MutateCustomizerAttributesResponse 
 , 
 ) 
 # Keywords from user. 
 KEYWORD_TEXT_EXACT 
 = 
 "example of exact match" 
 KEYWORD_TEXT_PHRASE 
 = 
 "example of phrase match" 
 KEYWORD_TEXT_BROAD 
 = 
 "example of broad match" 
 # Geo targeting from user. 
 GEO_LOCATION_1 
 = 
 "Buenos aires" 
 GEO_LOCATION_2 
 = 
 "San Isidro" 
 GEO_LOCATION_3 
 = 
 "Mar del Plata" 
 # LOCALE and COUNTRY_CODE are used for geo targeting. 
 # LOCALE is using ISO 639-1 format. If an invalid LOCALE is given, 
 # 'es' is used by default. 
 LOCALE 
 = 
 "es" 
 # A list of country codes can be referenced here: 
 # https://developers.google.com/google-ads/api/reference/data/geotargets 
 COUNTRY_CODE 
 = 
 "AR" 
 def 
  
 main 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 customizer_attribute_name 
 : 
 Optional 
 [ 
 str 
 ] 
 = 
 None 
 , 
 ) 
 - 
> None 
 : 
  
 """ 
 The main method that creates all necessary entities for the example. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 customizer_attribute_name: The name of the customizer attribute to be 
 created 
 """ 
 if 
 customizer_attribute_name 
 : 
 customizer_attribute_resource_name 
 : 
 str 
 = 
 create_customizer_attribute 
 ( 
 client 
 , 
 customer_id 
 , 
 customizer_attribute_name 
 ) 
 link_customizer_attribute_to_customer 
 ( 
 client 
 , 
 customer_id 
 , 
 customizer_attribute_resource_name 
 ) 
 # Create a budget, which can be shared by multiple campaigns. 
 campaign_budget 
 : 
 str 
 = 
 create_campaign_budget 
 ( 
 client 
 , 
 customer_id 
 ) 
 campaign_resource_name 
 : 
 str 
 = 
 create_campaign 
 ( 
 client 
 , 
 customer_id 
 , 
 campaign_budget 
 ) 
 ad_group_resource_name 
 : 
 str 
 = 
 create_ad_group 
 ( 
 client 
 , 
 customer_id 
 , 
 campaign_resource_name 
 ) 
 create_ad_group_ad 
 ( 
 client 
 , 
 customer_id 
 , 
 ad_group_resource_name 
 , 
 customizer_attribute_name 
 ) 
 add_keywords 
 ( 
 client 
 , 
 customer_id 
 , 
 ad_group_resource_name 
 ) 
 add_geo_targeting 
 ( 
 client 
 , 
 customer_id 
 , 
 campaign_resource_name 
 ) 
 def 
  
 create_customizer_attribute 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 customizer_attribute_name 
 : 
 str 
 ) 
 - 
> str 
 : 
  
 """Creates a customizer attribute with the given customizer attribute name. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 customizer_attribute_name: the name for the customizer attribute. 
 Returns: 
 A resource name for a customizer attribute. 
 """ 
 # Create a customizer attribute operation for creating a customizer 
 # attribute. 
 operation 
 : 
 CustomizerAttributeOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "CustomizerAttributeOperation" 
 ) 
 # Create a customizer attribute with the specified name. 
 customizer_attribute 
 : 
 CustomizerAttribute 
 = 
 operation 
 . 
 create 
 customizer_attribute 
 . 
 name 
 = 
 customizer_attribute_name 
 # Specify the type to be 'PRICE' so that we can dynamically customize the 
 # part of the ad's description that is a price of a product/service we 
 # advertise. 
 customizer_attribute 
 . 
 type_ 
 = 
 client 
 . 
 enums 
 . 
 CustomizerAttributeTypeEnum 
 . 
 PRICE 
 # Issue a mutate request to add the customizer attribute and prints its 
 # information. 
 customizer_attribute_service 
 : 
 CustomizerAttributeServiceClient 
 = 
 ( 
 client 
 . 
 get_service 
 ( 
 "CustomizerAttributeService" 
 ) 
 ) 
 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 a customizer attribute with resource name: ' 
 { 
 resource_name 
 } 
 '" 
 ) 
 return 
 resource_name 
 def 
  
 link_customizer_attribute_to_customer 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 customizer_attribute_resource_name 
 : 
 str 
 , 
 ) 
 - 
> None 
 : 
  
 """Links the customizer attribute to the customer. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 customizer_attribute_resource_name: a resource name for  customizer 
 attribute. 
 """ 
 # Create a customer customizer operation. 
 operation 
 : 
 CustomerCustomizerOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "CustomerCustomizerOperation" 
 ) 
 # Create a customer customizer with the value to be used in the responsive 
 # search ad. 
 customer_customizer 
 : 
 CustomerCustomizer 
 = 
 operation 
 . 
 create 
 customer_customizer 
 . 
 customizer_attribute 
 = 
 ( 
 customizer_attribute_resource_name 
 ) 
 customer_customizer 
 . 
 value 
 . 
 type_ 
 = 
 ( 
 client 
 . 
 enums 
 . 
 CustomizerAttributeTypeEnum 
 . 
 PRICE 
 ) 
 # The ad customizer will dynamically replace the placeholder with this value 
 # when the ad serves. 
 customer_customizer 
 . 
 value 
 . 
 string_value 
 = 
 "100USD" 
 customer_customizer_service 
 : 
 CustomerCustomizerServiceClient 
 = 
 ( 
 client 
 . 
 get_service 
 ( 
 "CustomerCustomizerService" 
 ) 
 ) 
 # Issue a mutate request to create the customer customizer and prints its 
 # information. 
 response 
 : 
 MutateCustomerCustomizersResponse 
 = 
 ( 
 customer_customizer_service 
 . 
 mutate_customer_customizers 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 [ 
 operation 
 ] 
 ) 
 ) 
 resource_name 
 : 
 str 
 = 
 response 
 . 
 results 
 [ 
 0 
 ] 
 . 
 resource_name 
 print 
 ( 
 f 
 "Added a customer customizer to the customer with resource name: ' 
 { 
 resource_name 
 } 
 '" 
 ) 
 def 
  
 create_ad_text_asset 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 text 
 : 
 str 
 , 
 pinned_field 
 : 
 Optional 
 [ 
 ServedAssetFieldTypeEnum 
 . 
 ServedAssetFieldType 
 ] 
 = 
 None 
 , 
 ) 
 - 
> AdTextAsset 
 : 
  
 """Create an AdTextAsset. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 text: text for headlines and descriptions. 
 pinned_field: to pin a text asset so it always shows in the ad. 
 Returns: 
 An AdTextAsset. 
 """ 
 ad_text_asset 
 : 
 AdTextAsset 
 = 
 client 
 . 
 get_type 
 ( 
 "AdTextAsset" 
 ) 
 ad_text_asset 
 . 
 text 
 = 
 text 
 if 
 pinned_field 
 : 
 ad_text_asset 
 . 
 pinned_field 
 = 
 pinned_field 
 return 
 ad_text_asset 
 def 
  
 create_ad_text_asset_with_customizer 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customizer_attribute_resource_name 
 : 
 str 
 ) 
 - 
> AdTextAsset 
 : 
  
 """Create an AdTextAsset. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customizer_attribute_resource_name: The resource name of the customizer attribute. 
 Returns: 
 An AdTextAsset. 
 """ 
 ad_text_asset 
 : 
 AdTextAsset 
 = 
 client 
 . 
 get_type 
 ( 
 "AdTextAsset" 
 ) 
 # Create this particular description using the ad customizer. Visit 
 # https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads#ad_customizers_in_responsive_search_ads 
 # for details about the placeholder format. The ad customizer replaces the 
 # placeholder with the value we previously created and linked to the 
 # customer using CustomerCustomizer. 
 ad_text_asset 
 . 
 text 
 = 
 ( 
 f 
 "Just 
{{CUSTOMIZER.{customizer_attribute_resource_name}:10USD} } 
 " 
 ) 
 return 
 ad_text_asset 
 def 
  
 create_campaign_budget 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 ) 
 - 
> str 
 : 
  
 """Creates campaign budget resource. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 Returns: 
 Campaign budget resource name. 
 """ 
 # Create a budget, which can be shared by multiple campaigns. 
 campaign_budget_service 
 : 
 CampaignBudgetServiceClient 
 = 
 client 
 . 
 get_service 
 ( 
 "CampaignBudgetService" 
 ) 
 campaign_budget_operation 
 : 
 CampaignBudgetOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "CampaignBudgetOperation" 
 ) 
 campaign_budget 
 : 
 CampaignBudget 
 = 
 campaign_budget_operation 
 . 
 create 
 campaign_budget 
 . 
 name 
 = 
 f 
 "Campaign budget 
 { 
 uuid 
 . 
 uuid4 
 () 
 } 
 " 
 campaign_budget 
 . 
 delivery_method 
 = 
 ( 
 client 
 . 
 enums 
 . 
 BudgetDeliveryMethodEnum 
 . 
 STANDARD 
 ) 
 campaign_budget 
 . 
 amount_micros 
 = 
 500000 
 # Add budget. 
 campaign_budget_response 
 : 
 MutateCampaignBudgetsResponse 
 = 
 ( 
 campaign_budget_service 
 . 
 mutate_campaign_budgets 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 [ 
 campaign_budget_operation 
 ] 
 ) 
 ) 
 return 
 campaign_budget_response 
 . 
 results 
 [ 
 0 
 ] 
 . 
 resource_name 
 def 
  
 create_campaign 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 campaign_budget 
 : 
 str 
 ) 
 - 
> str 
 : 
  
 """Creates campaign resource. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 campaign_budget: a budget resource name. 
 Returns: 
 Campaign resource name. 
 """ 
 campaign_service 
 : 
 CampaignServiceClient 
 = 
 client 
 . 
 get_service 
 ( 
 "CampaignService" 
 ) 
 campaign_operation 
 : 
 CampaignOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "CampaignOperation" 
 ) 
 campaign 
 : 
 Campaign 
 = 
 campaign_operation 
 . 
 create 
 campaign 
 . 
 name 
 = 
 f 
 "Testing RSA via API 
 { 
 uuid 
 . 
 uuid4 
 () 
 } 
 " 
 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 budget. 
 # The bidding strategy for Maximize Clicks is TargetSpend. 
 # The target_spend_micros is deprecated so don't put any value. 
 # See other bidding strategies you can select in the link below. 
 # https://developers.google.com/google-ads/api/reference/rpc/latest/Campaign#campaign_bidding_strategy 
 campaign 
 . 
 target_spend 
 . 
 target_spend_micros 
 = 
 0 
 campaign 
 . 
 campaign_budget 
 = 
 campaign_budget 
 # Set the campaign network options. 
 campaign 
 . 
 network_settings 
 . 
 target_google_search 
 = 
 True 
 campaign 
 . 
 network_settings 
 . 
 target_search_network 
 = 
 True 
 campaign 
 . 
 network_settings 
 . 
 target_partner_search_network 
 = 
 False 
 # Enable Display Expansion on Search campaigns. For more details see: 
 # https://support.google.com/google-ads/answer/7193800 
 campaign 
 . 
 network_settings 
 . 
 target_content_network 
 = 
 True 
 # # Optional: Set the start date. 
 # start_time = datetime.date.today() + datetime.timedelta(days=1) 
 # campaign.start_date = datetime.date.strftime(start_time, _DATE_FORMAT) 
 # # Optional: Set the end date. 
 # end_time = start_time + datetime.timedelta(weeks=4) 
 # campaign.end_date = datetime.date.strftime(end_time, _DATE_FORMAT) 
 # Add the campaign. 
 campaign_response 
 : 
 MutateCampaignsResponse 
 = 
 ( 
 campaign_service 
 . 
 mutate_campaigns 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 [ 
 campaign_operation 
 ] 
 ) 
 ) 
 resource_name 
 : 
 str 
 = 
 campaign_response 
 . 
 results 
 [ 
 0 
 ] 
 . 
 resource_name 
 print 
 ( 
 f 
 "Created campaign 
 { 
 resource_name 
 } 
 ." 
 ) 
 return 
 resource_name 
 def 
  
 create_ad_group 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 campaign_resource_name 
 : 
 str 
 , 
 ) 
 - 
> str 
 : 
  
 """Creates ad group. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 campaign_resource_name: a campaign resource name. 
 Returns: 
 Ad group ID. 
 """ 
 ad_group_service 
 : 
 AdGroupServiceClient 
 = 
 client 
 . 
 get_service 
 ( 
 "AdGroupService" 
 ) 
 ad_group_operation 
 : 
 AdGroupOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "AdGroupOperation" 
 ) 
 ad_group 
 : 
 AdGroup 
 = 
 ad_group_operation 
 . 
 create 
 ad_group 
 . 
 name 
 = 
 f 
 "Testing RSA via API 
 { 
 uuid 
 . 
 uuid4 
 () 
 } 
 " 
 ad_group 
 . 
 status 
 = 
 client 
 . 
 enums 
 . 
 AdGroupStatusEnum 
 . 
 ENABLED 
 ad_group 
 . 
 campaign 
 = 
 campaign_resource_name 
 ad_group 
 . 
 type_ 
 = 
 client 
 . 
 enums 
 . 
 AdGroupTypeEnum 
 . 
 SEARCH_STANDARD 
 # If you want to set up a max CPC bid uncomment line below. 
 # ad_group.cpc_bid_micros = 10000000 
 # Add the ad group. 
 ad_group_response 
 : 
 MutateAdGroupsResponse 
 = 
 ( 
 ad_group_service 
 . 
 mutate_ad_groups 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 [ 
 ad_group_operation 
 ] 
 ) 
 ) 
 ad_group_resource_name 
 : 
 str 
 = 
 ad_group_response 
 . 
 results 
 [ 
 0 
 ] 
 . 
 resource_name 
 print 
 ( 
 f 
 "Created ad group 
 { 
 ad_group_resource_name 
 } 
 ." 
 ) 
 return 
 ad_group_resource_name 
 def 
  
 create_ad_group_ad 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 ad_group_resource_name 
 : 
 str 
 , 
 customizer_attribute_name 
 : 
 Optional 
 [ 
 str 
 ], 
 ) 
 - 
> None 
 : 
  
 """Creates ad group ad. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 ad_group_resource_name: an ad group resource name. 
 customizer_attribute_name: (optional) If present, indicates the resource 
 name of the customizer attribute to use in one of the descriptions 
 Returns: 
 None. 
 """ 
 ad_group_ad_service 
 : 
 AdGroupAdServiceClient 
 = 
 client 
 . 
 get_service 
 ( 
 "AdGroupAdService" 
 ) 
 ad_group_ad_operation 
 : 
 AdGroupAdOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "AdGroupAdOperation" 
 ) 
 ad_group_ad 
 : 
 AdGroupAd 
 = 
 ad_group_ad_operation 
 . 
 create 
 ad_group_ad 
 . 
 status 
 = 
 client 
 . 
 enums 
 . 
 AdGroupAdStatusEnum 
 . 
 ENABLED 
 ad_group_ad 
 . 
 ad_group 
 = 
 ad_group_resource_name 
 # Set responsive search ad info. 
 # https://developers.google.com/google-ads/api/reference/rpc/latest/ResponsiveSearchAdInfo 
 # The list of possible final URLs after all cross-domain redirects for the ad. 
 ad_group_ad 
 . 
 ad 
 . 
 final_urls 
 . 
 append 
 ( 
 "https://www.example.com/" 
 ) 
 # Set a pinning to always choose this asset for HEADLINE_1. Pinning is 
 # optional; if no pinning is set, then headlines and descriptions will be 
 # rotated and the ones that perform best will be used more often. 
 # Headline 1 
 served_asset_enum 
 : 
 ServedAssetFieldTypeEnum 
 = 
 ( 
 client 
 . 
 enums 
 . 
 ServedAssetFieldTypeEnum 
 ) 
 pinned_headline 
 : 
 AdTextAsset 
 = 
 create_ad_text_asset 
 ( 
 client 
 , 
 "Headline 1 testing" 
 , 
 served_asset_enum 
 ) 
 # Headline 2 and 3 
 ad_group_ad 
 . 
 ad 
 . 
 responsive_search_ad 
 . 
 headlines 
 . 
 extend 
 ( 
 [ 
 pinned_headline 
 , 
 create_ad_text_asset 
 ( 
 client 
 , 
 "Headline 2 testing" 
 ), 
 create_ad_text_asset 
 ( 
 client 
 , 
 "Headline 3 testing" 
 ), 
 ] 
 ) 
 # Description 1 and 2 
 description_1 
 : 
 AdTextAsset 
 = 
 create_ad_text_asset 
 ( 
 client 
 , 
 "Desc 1 testing" 
 ) 
 description_2 
 : 
 Optional 
 [ 
 AdTextAsset 
 ] 
 = 
 None 
 if 
 customizer_attribute_name 
 : 
 description_2 
 = 
 create_ad_text_asset_with_customizer 
 ( 
 client 
 , 
 customizer_attribute_name 
 ) 
 else 
 : 
 description_2 
 = 
 create_ad_text_asset 
 ( 
 client 
 , 
 "Desc 2 testing" 
 ) 
 ad_group_ad 
 . 
 ad 
 . 
 responsive_search_ad 
 . 
 descriptions 
 . 
 extend 
 ( 
 [ 
 description_1 
 , 
 description_2 
 ] 
 ) 
 # Paths 
 # First and second part of text that can be appended to the URL in the ad. 
 # If you use the examples below, the ad will show 
 # https://www.example.com/all-inclusive/deals 
 ad_group_ad 
 . 
 ad 
 . 
 responsive_search_ad 
 . 
 path1 
 = 
 "all-inclusive" 
 ad_group_ad 
 . 
 ad 
 . 
 responsive_search_ad 
 . 
 path2 
 = 
 "deals" 
 # Send a request to the server to add a responsive search ad. 
 ad_group_ad_response 
 : 
 MutateAdGroupAdsResponse 
 = 
 ( 
 ad_group_ad_service 
 . 
 mutate_ad_group_ads 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 [ 
 ad_group_ad_operation 
 ] 
 ) 
 ) 
 for 
 result 
 in 
 ad_group_ad_response 
 . 
 results 
 : 
 print 
 ( 
 f 
 "Created responsive search ad with resource name " 
 f 
 '" 
 { 
 result 
 . 
 resource_name 
 } 
 ".' 
 ) 
 def 
  
 add_keywords 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 ad_group_resource_name 
 : 
 str 
 ) 
 - 
> None 
 : 
  
 """Creates keywords. 
 Creates 3 keyword match types: EXACT, PHRASE, and BROAD. 
 EXACT: ads may show on searches that ARE the same meaning as your keyword. 
 PHRASE: ads may show on searches that INCLUDE the meaning of your keyword. 
 BROAD: ads may show on searches that RELATE to your keyword. 
 For smart bidding, BROAD is the recommended one. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 ad_group_resource_name: an ad group resource name. 
 """ 
 ad_group_criterion_service 
 : 
 AdGroupCriterionServiceClient 
 = 
 ( 
 client 
 . 
 get_service 
 ( 
 "AdGroupCriterionService" 
 ) 
 ) 
 operations 
 : 
 List 
 [ 
 AdGroupCriterionOperation 
 ] 
 = 
 [] 
 # Create keyword 1. 
 ad_group_criterion_operation 
 : 
 AdGroupCriterionOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "AdGroupCriterionOperation" 
 ) 
 ad_group_criterion 
 : 
 AdGroupCriterion 
 = 
 ad_group_criterion_operation 
 . 
 create 
 ad_group_criterion 
 . 
 ad_group 
 = 
 ad_group_resource_name 
 ad_group_criterion 
 . 
 status 
 = 
 client 
 . 
 enums 
 . 
 AdGroupCriterionStatusEnum 
 . 
 ENABLED 
 ad_group_criterion 
 . 
 keyword 
 . 
 text 
 = 
 KEYWORD_TEXT_EXACT 
 ad_group_criterion 
 . 
 keyword 
 . 
 match_type 
 = 
 ( 
 client 
 . 
 enums 
 . 
 KeywordMatchTypeEnum 
 . 
 EXACT 
 ) 
 # Uncomment the below line if you want to change this keyword to a negative target. 
 # ad_group_criterion.negative = True 
 # Optional repeated field 
 # ad_group_criterion.final_urls.append('https://www.example.com') 
 # Add operation 
 operations 
 . 
 append 
 ( 
 ad_group_criterion_operation 
 ) 
 # Create keyword 2. 
 ad_group_criterion_operation 
 : 
 AdGroupCriterionOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "AdGroupCriterionOperation" 
 ) 
 ad_group_criterion 
 : 
 AdGroupCriterion 
 = 
 ad_group_criterion_operation 
 . 
 create 
 ad_group_criterion 
 . 
 ad_group 
 = 
 ad_group_resource_name 
 ad_group_criterion 
 . 
 status 
 = 
 client 
 . 
 enums 
 . 
 AdGroupCriterionStatusEnum 
 . 
 ENABLED 
 ad_group_criterion 
 . 
 keyword 
 . 
 text 
 = 
 KEYWORD_TEXT_PHRASE 
 ad_group_criterion 
 . 
 keyword 
 . 
 match_type 
 = 
 ( 
 client 
 . 
 enums 
 . 
 KeywordMatchTypeEnum 
 . 
 PHRASE 
 ) 
 # Uncomment the below line if you want to change this keyword to a negative target. 
 # ad_group_criterion.negative = True 
 # Optional repeated field 
 # ad_group_criterion.final_urls.append('https://www.example.com') 
 # Add operation 
 operations 
 . 
 append 
 ( 
 ad_group_criterion_operation 
 ) 
 # Create keyword 3. 
 ad_group_criterion_operation 
 : 
 AdGroupCriterionOperation 
 = 
 client 
 . 
 get_type 
 ( 
 "AdGroupCriterionOperation" 
 ) 
 ad_group_criterion 
 : 
 AdGroupCriterion 
 = 
 ad_group_criterion_operation 
 . 
 create 
 ad_group_criterion 
 . 
 ad_group 
 = 
 ad_group_resource_name 
 ad_group_criterion 
 . 
 status 
 = 
 client 
 . 
 enums 
 . 
 AdGroupCriterionStatusEnum 
 . 
 ENABLED 
 ad_group_criterion 
 . 
 keyword 
 . 
 text 
 = 
 KEYWORD_TEXT_BROAD 
 ad_group_criterion 
 . 
 keyword 
 . 
 match_type 
 = 
 ( 
 client 
 . 
 enums 
 . 
 KeywordMatchTypeEnum 
 . 
 BROAD 
 ) 
 # Uncomment the below line if you want to change this keyword to a negative target. 
 # ad_group_criterion.negative = True 
 # Optional repeated field 
 # ad_group_criterion.final_urls.append('https://www.example.com') 
 # Add operation 
 operations 
 . 
 append 
 ( 
 ad_group_criterion_operation 
 ) 
 # Add keywords 
 ad_group_criterion_response 
 : 
 MutateAdGroupCriteriaResponse 
 = 
 ( 
 ad_group_criterion_service 
 . 
 mutate_ad_group_criteria 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 operations 
 , 
 ) 
 ) 
 for 
 result 
 in 
 ad_group_criterion_response 
 . 
 results 
 : 
 print 
 ( 
 "Created keyword " 
 f 
 " 
 { 
 result 
 . 
 resource_name 
 } 
 ." 
 ) 
 def 
  
 add_geo_targeting 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 campaign_resource_name 
 : 
 str 
 ) 
 - 
> None 
 : 
  
 """Creates geo targets. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: a client customer ID. 
 campaign_resource_name: an campaign resource name. 
 Returns: 
 None. 
 """ 
 geo_target_constant_service 
 : 
 GeoTargetConstantServiceClient 
 = 
 ( 
 client 
 . 
 get_service 
 ( 
 "GeoTargetConstantService" 
 ) 
 ) 
 # Search by location names from 
 # GeoTargetConstantService.suggest_geo_target_constants() and directly 
 # apply GeoTargetConstant.resource_name. 
 gtc_request 
 : 
 SuggestGeoTargetConstantsRequest 
 = 
 client 
 . 
 get_type 
 ( 
 "SuggestGeoTargetConstantsRequest" 
 ) 
 gtc_request 
 . 
 locale 
 = 
 LOCALE 
 gtc_request 
 . 
 country_code 
 = 
 COUNTRY_CODE 
 # The location names to get suggested geo target constants. 
 gtc_request 
 . 
 location_names 
 . 
 names 
 . 
 extend 
 ( 
 [ 
 GEO_LOCATION_1 
 , 
 GEO_LOCATION_2 
 , 
 GEO_LOCATION_3 
 ] 
 ) 
 results 
 : 
 SuggestGeoTargetConstantsResponse 
 = 
 ( 
 geo_target_constant_service 
 . 
 suggest_geo_target_constants 
 ( 
 gtc_request 
 ) 
 ) 
 operations 
 : 
 List 
 [ 
 CampaignCriterionOperation 
 ] 
 = 
 [] 
 for 
 suggestion 
 in 
 results 
 . 
 geo_target_constant_suggestions 
 : 
 print 
 ( 
 "geo_target_constant: " 
 f 
 " 
 { 
 suggestion 
 . 
 geo_target_constant 
 . 
 resource_name 
 } 
 " 
 f 
 "is found in LOCALE ( 
 { 
 suggestion 
 . 
 locale 
 } 
 ) " 
 f 
 "with reach ( 
 { 
 suggestion 
 . 
 reach 
 } 
 ) " 
 f 
 "from search term ( 
 { 
 suggestion 
 . 
 search_term 
 } 
 )." 
 ) 
 # Create the campaign criterion for location targeting. 
 campaign_criterion_operation 
 : 
 CampaignCriterionOperation 
 = 
 ( 
 client 
 . 
 get_type 
 ( 
 "CampaignCriterionOperation" 
 ) 
 ) 
 campaign_criterion 
 : 
 CampaignCriterion 
 = 
 ( 
 campaign_criterion_operation 
 . 
 create 
 ) 
 campaign_criterion 
 . 
 campaign 
 = 
 campaign_resource_name 
 campaign_criterion 
 . 
 location 
 . 
 geo_target_constant 
 = 
 ( 
 suggestion 
 . 
 geo_target_constant 
 . 
 resource_name 
 ) 
 operations 
 . 
 append 
 ( 
 campaign_criterion_operation 
 ) 
 campaign_criterion_service 
 : 
 CampaignCriterionServiceClient 
 = 
 ( 
 client 
 . 
 get_service 
 ( 
 "CampaignCriterionService" 
 ) 
 ) 
 campaign_criterion_response 
 : 
 MutateCampaignCriteriaResponse 
 = 
 ( 
 campaign_criterion_service 
 . 
 mutate_campaign_criteria 
 ( 
 customer_id 
 = 
 customer_id 
 , 
 operations 
 = 
 [ 
 * 
 operations 
 ] 
 ) 
 ) 
 for 
 result 
 in 
 campaign_criterion_response 
 . 
 results 
 : 
 print 
 ( 
 f 
 'Added campaign criterion " 
 { 
 result 
 . 
 resource_name 
 } 
 ".' 
 ) 
 if 
 __name__ 
 == 
 "__main__" 
 : 
 parser 
 : 
 argparse 
 . 
 ArgumentParser 
 = 
 argparse 
 . 
 ArgumentParser 
 ( 
 description 
 = 
 ( 
 "Creates a Responsive Search Ad for specified customer." 
 ) 
 ) 
 # 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." 
 , 
 ) 
 # The name of the customizer attribute used in the ad customizer, which 
 # must be unique for a given customer account. To run this example multiple 
 # times, specify a unique value as a command line argument. Note that there is 
 # a limit for the number of enabled customizer attributes in one account 
 # For more details visit: 
 # https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads#rules_and_limitations 
 parser 
 . 
 add_argument 
 ( 
 "-n" 
 , 
 "--customizer_attribute_name" 
 , 
 type 
 = 
 str 
 , 
 default 
 = 
 None 
 , 
 help 
 = 
 ( 
 "The name of the customizer attribute to be created. The name must " 
 "be unique across a client account, so be sure not to use " 
 "the same value more than once." 
 ), 
 ) 
 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 
 = 
 "v22" 
 ) 
 try 
 : 
 main 
 ( 
 googleads_client 
 , 
 args 
 . 
 customer_id 
 , 
 args 
 . 
 customizer_attribute_name 
 , 
 ) 
 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 2025 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 shows how to create a complete Responsive Search ad. 
 # 
 # Includes creation of: budget, campaign, ad group, ad group ad, 
 # keywords, and geo targeting. 
 # 
 # More details on Responsive Search ads can be found here: 
 # https://support.google.com/google-ads/answer/7684791 
 require 
  
 'optparse' 
 require 
  
 'google/ads/google_ads' 
 require 
  
 'date' 
 # The name of the customizer attribute to be used in the ad customizer must be unique for a 
 # given client account. To run this example multiple times, change this value or specify 
 # its corresponding argument. Note that there is a limit for the number of enabled 
 # customizer attributes in one account, so you shouldn't run this example more than 
 # necessary. 
 # 
 # Visit the following link for more details: 
 # https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads#rules_and_limitations 
 DEFAULT_CUSTOMIZER_ATTRIBUTE_NAME 
  
 = 
  
 "Price" 
 # Keywords from user. 
 KEYWORD_TEXT_EXACT 
  
 = 
  
 "example of exact match" 
 KEYWORD_TEXT_PHRASE 
  
 = 
  
 "example of phrase match" 
 KEYWORD_TEXT_BROAD 
  
 = 
  
 "example of broad match" 
 # Geo targeting from user. 
 GEO_LOCATION_1 
  
 = 
  
 "Buenos aires" 
 GEO_LOCATION_2 
  
 = 
  
 "San Isidro" 
 GEO_LOCATION_3 
  
 = 
  
 "Mar del Plata" 
 # LOCALE and COUNTRY_CODE are used for geo targeting. 
 # LOCALE is using ISO 639-1 format. If an invalid LOCALE is given, 
 # 'es' is used by default. 
 LOCALE 
  
 = 
  
 "es" 
 # A list of country codes can be referenced here: 
 # https://developers.google.com/google-ads/api/reference/data/geotargets 
 COUNTRY_CODE 
  
 = 
  
 "AR" 
 # Creates a customizer attribute with the given customizer attribute name. 
 # 
 # Args: 
 #   client: An initialized GoogleAdsClient instance. 
 #   customer_id: A client customer ID. 
 #   customizer_attribute_name: The name for the customizer attribute. 
 # 
 # Returns: 
 #   A resource name for a customizer attribute. 
 def 
  
 create_customizer_attribute 
 ( 
 client 
 , 
  
 customer_id 
 , 
  
 customizer_attribute_name 
 ) 
  
 # Create a customizer attribute operation for creating a customizer attribute. 
  
 operation 
  
 = 
  
 client 
 . 
 operation 
 . 
 create_resource 
 . 
 customizer_attribute 
  
 do 
  
 | 
 ca 
 | 
  
 ca 
 . 
 name 
  
 = 
  
 customizer_attribute_name 
  
 # Specify the type to be 'PRICE' so that we can dynamically customize the 
  
 # part of the ad's description that is a price of a product/service we 
  
 # advertise. 
  
 ca 
 . 
 type 
  
 = 
  
 :PRICE 
  
 end 
  
 # Issue a mutate request to add the customizer attribute and print its 
  
 # information. 
  
 customizer_attribute_service 
  
 = 
  
 client 
 . 
 service 
 . 
 customizer_attribute 
  
 response 
  
 = 
  
 customizer_attribute_service 
 . 
 mutate_customizer_attributes 
 ( 
  
 customer_id 
 : 
  
 customer_id 
 , 
  
 operations 
 : 
  
 [ 
 operation 
 ] 
 , 
  
 ) 
  
 resource_name 
  
 = 
  
 response 
 . 
 results 
 . 
 first 
 . 
 resource_name 
  
 puts 
  
 "Added a customizer attribute with resource name: ' 
 #{ 
 resource_name 
 } 
 '" 
  
 resource_name 
 end 
 # Links the customizer attribute to the customer. 
 # 
 # Args: 
 #   client: An initialized GoogleAdsClient instance. 
 #   customer_id: A client customer ID. 
 #   customizer_attribute_resource_name: A resource name for a customizer attribute. 
 def 
  
 link_customizer_attribute_to_customer 
 ( 
 client 
 , 
  
 customer_id 
 , 
  
 customizer_attribute_resource_name 
 ) 
  
 # Create a customer customizer operation. 
  
 operation 
  
 = 
  
 client 
 . 
 operation 
 . 
 create_customer_customizer 
  
 do 
  
 | 
 cc 
 | 
  
 cc 
 . 
 customizer_attribute 
  
 = 
  
 customizer_attribute_resource_name 
  
 cc 
 . 
 value 
  
 = 
  
 client 
 . 
 resource 
 . 
 customizer_value 
  
 do 
  
 | 
 val 
 | 
  
 val 
 . 
 type 
  
 = 
  
 :PRICE 
  
 # The ad customizer will dynamically replace the placeholder with this value 
  
 # when the ad serves. 
  
 val 
 . 
 string_value 
  
 = 
  
 "100USD" 
  
 end 
  
 end 
  
 customer_customizer_service 
  
 = 
  
 client 
 . 
 service 
 . 
 customer_customizer 
  
 # Issue a mutate request to create the customer customizer and prints its 
  
 # information. 
  
 response 
  
 = 
  
 customer_customizer_service 
 . 
 mutate_customer_customizers 
 ( 
  
 customer_id 
 : 
  
 customer_id 
 , 
  
 operations 
 : 
  
 [ 
 operation 
 ] 
 , 
  
 ) 
  
 resource_name 
  
 = 
  
 response 
 . 
 results 
 . 
 first 
 . 
 resource_name 
  
 puts 
  
 "Added a customer customizer to the customer with resource name: ' 
 #{ 
 resource_name 
 } 
 '" 
 end 
 # Helper function to create an AdTextAsset. 
 # 
 # Args: 
 #   client: An initialized GoogleAdsClient instance. 
 #   text: Text for headlines and descriptions. 
 #   pinned_field: To pin a text asset so it always shows in the ad. 
 # 
 # Returns: 
 #   An AdTextAsset. 
 def 
  
 create_ad_text_asset 
 ( 
 client 
 , 
  
 text 
 , 
  
 pinned_field 
  
 = 
  
 nil 
 ) 
  
 client 
 . 
 resource 
 . 
 ad_text_asset 
  
 do 
  
 | 
 ad_text_asset 
 | 
  
 ad_text_asset 
 . 
 text 
  
 = 
  
 text 
  
 unless 
  
 pinned_field 
 . 
 nil? 
  
 ad_text_asset 
 . 
 pinned_field 
  
 = 
  
 pinned_field 
  
 end 
  
 end 
 end 
 # Helper function to create an AdTextAsset with a customizer. 
 # 
 # Args: 
 #   client: An initialized GoogleAdsClient instance. 
 #   customizer_attribute_resource_name: The resource name of the customizer attribute. 
 # 
 # Returns: 
 #   An AdTextAsset. 
 def 
  
 create_ad_text_asset_with_customizer 
 ( 
 client 
 , 
  
 customizer_attribute_resource_name 
 ) 
  
 client 
 . 
 resource 
 . 
 ad_text_asset 
  
 do 
  
 | 
 ad_text_asset 
 | 
  
 # Create this particular description using the ad customizer. Visit 
  
 # https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads#ad_customizers_in_responsive_search_ads 
  
 # for details about the placeholder format. The ad customizer replaces the 
  
 # placeholder with the value we previously created and linked to the 
  
 # customer using CustomerCustomizer. 
  
 ad_text_asset 
 . 
 text 
  
 = 
  
 "Just {CUSTOMIZER. 
 #{ 
 customizer_attribute_resource_name 
 } 
 :10USD}" 
  
 end 
 end 
 # Creates a campaign budget resource. 
 # 
 # Args: 
 #   client: An initialized GoogleAdsClient instance. 
 #   customer_id: A client customer ID. 
 # 
 # Returns: 
 #   Campaign budget resource name. 
 def 
  
 create_campaign_budget 
 ( 
 client 
 , 
  
 customer_id 
 ) 
  
 # Create a budget, which can be shared by multiple campaigns. 
  
 campaign_budget_service 
  
 = 
  
 client 
 . 
 service 
 . 
 campaign_budget 
  
 operation 
  
 = 
  
 client 
 . 
 operation 
 . 
 create_resource 
 . 
 campaign_budget 
  
 do 
  
 | 
 cb 
 | 
  
 cb 
 . 
 name 
  
 = 
  
 "Campaign budget 
 \# 
 {SecureRandom.uuid}" 
  
 cb 
 . 
 delivery_method 
  
 = 
  
 :STANDARD 
  
 cb 
 . 
 amount_micros 
  
 = 
  
 500_000 
  
 # 500,000 
  
 end 
  
 # Add budget. 
  
 response 
  
 = 
  
 campaign_budget_service 
 . 
 mutate_campaign_budgets 
 ( 
  
 customer_id 
 : 
  
 customer_id 
 , 
  
 operations 
 : 
  
 [ 
 operation 
 ] 
 , 
  
 ) 
  
 resource_name 
  
 = 
  
 response 
 . 
 results 
 . 
 first 
 . 
 resource_name 
  
 puts 
  
 "Created campaign budget 
 #{ 
 resource_name 
 } 
 " 
  
 resource_name 
 end 
 # Creates a campaign resource. 
 # 
 # Args: 
 #   client: An initialized GoogleAdsClient instance. 
 #   customer_id: A client customer ID. 
 #   campaign_budget_resource_name: A budget resource name. 
 # 
 # Returns: 
 #   Campaign resource name. 
 def 
  
 create_campaign 
 ( 
 client 
 , 
  
 customer_id 
 , 
  
 campaign_budget_resource_name 
 ) 
  
 campaign_service 
  
 = 
  
 client 
 . 
 service 
 . 
 campaign 
  
 operation 
  
 = 
  
 client 
 . 
 operation 
 . 
 create_campaign 
  
 do 
  
 | 
 campaign 
 | 
  
 campaign 
 . 
 name 
  
 = 
  
 "Testing RSA via API 
 \# 
 {SecureRandom.uuid}" 
  
 campaign 
 . 
 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. 
  
 campaign 
 . 
 status 
  
 = 
  
 :PAUSED 
  
 # Set the bidding strategy and budget. 
  
 # The bidding strategy for Maximize Clicks is TargetSpend. 
  
 # The target_spend_micros is deprecated so don't put any value. 
  
 # See other bidding strategies you can select in the link below. 
  
 # https://developers.google.com/google-ads/api/reference/rpc/latest/Campaign#campaign_bidding_strategy 
  
 campaign 
 . 
 bidding_strategy_type 
  
 = 
  
 :TARGET_SPEND 
  
 campaign 
 . 
 target_spend 
  
 = 
  
 client 
 . 
 resource 
 . 
 target_spend 
  
 do 
  
 | 
 ts 
 | 
  
 ts 
 . 
 target_spend_micros 
  
 = 
  
 0 
  
 end 
  
 campaign 
 . 
 campaign_budget 
  
 = 
  
 campaign_budget_resource_name 
  
 # Set the campaign network options. 
  
 campaign 
 . 
 network_settings 
  
 = 
  
 client 
 . 
 resource 
 . 
 network_settings 
  
 do 
  
 | 
 ns 
 | 
  
 ns 
 . 
 target_google_search 
  
 = 
  
 true 
  
 ns 
 . 
 target_search_network 
  
 = 
  
 true 
  
 ns 
 . 
 target_partner_search_network 
  
 = 
  
 false 
  
 # Enable Display Expansion on Search campaigns. For more details see: 
  
 # https://support.google.com/google-ads/answer/7193800 
  
 ns 
 . 
 target_content_network 
  
 = 
  
 true 
  
 end 
  
 # Optional: Set the start date. 
  
 #c.start_date = DateTime.parse((Date.today + 1).to_s).strftime('%Y%m%d') 
  
 # Optional: Set the end date. 
  
 #c.end_date = DateTime.parse((Date.today.next_year).to_s).strftime('%Y%m%d') 
  
 end 
  
 # Add the campaign. 
  
 response 
  
 = 
  
 campaign_service 
 . 
 mutate_campaigns 
 ( 
  
 customer_id 
 : 
  
 customer_id 
 , 
  
 operations 
 : 
  
 [ 
 operation 
 ] 
 , 
  
 ) 
  
 resource_name 
  
 = 
  
 response 
 . 
 results 
 . 
 first 
 . 
 resource_name 
  
 puts 
  
 "Created campaign 
 #{ 
 resource_name 
 } 
 ." 
  
 resource_name 
 end 
 # Creates an ad group. 
 # 
 # Args: 
 #   client: An initialized GoogleAdsClient instance. 
 #   customer_id: A client customer ID. 
 #   campaign_resource_name: A campaign resource name. 
 #   customizer_attribute_resource_name: (optional) If present, indicates the resource 
 #     name of the customizer attribute to use in one of the descriptions. 
 # 
 # Returns: 
 #   Ad group resource name. 
 def 
  
 create_ad_group 
 ( 
 client 
 , 
  
 customer_id 
 , 
  
 campaign_resource_name 
 ) 
  
 ad_group_service 
  
 = 
  
 client 
 . 
 service 
 . 
 ad_group 
  
 operation 
  
 = 
  
 client 
 . 
 operation 
 . 
 create_ad_group 
  
 do 
  
 | 
 ag 
 | 
  
 ag 
 . 
 name 
  
 = 
  
 "Testing RSA via API 
 \# 
 {SecureRandom.uuid}" 
  
 ag 
 . 
 status 
  
 = 
  
 :ENABLED 
  
 ag 
 . 
 campaign 
  
 = 
  
 campaign_resource_name 
  
 ag 
 . 
 type 
  
 = 
  
 :SEARCH_STANDARD 
  
 # If you want to set up a max CPC bid uncomment line below. 
  
 # ag.cpc_bid_micros = 1_000_000 # 1,000,000 
  
 end 
  
 # Add the ad group. 
  
 response 
  
 = 
  
 ad_group_service 
 . 
 mutate_ad_groups 
 ( 
  
 customer_id 
 : 
  
 customer_id 
 , 
  
 operations 
 : 
  
 [ 
 operation 
 ] 
 , 
  
 ) 
  
 ad_group_resource_name 
  
 = 
  
 response 
 . 
 results 
 . 
 first 
 . 
 resource_name 
  
 puts 
  
 "Created ad group 
 #{ 
 ad_group_resource_name 
 } 
 ." 
  
 ad_group_resource_name 
 end 
 # Creates an ad group ad (Responsive Search Ad). 
 # 
 # Args: 
 #   client: An initialized GoogleAdsClient instance. 
 #   customer_id: A client customer ID. 
 #   ad_group_resource_name: An ad group resource name. 
 # 
 # Returns: 
 #   Ad group ad resource name. 
 def 
  
 create_ad_group_ad 
 ( 
 client 
 , 
  
 customer_id 
 , 
  
 ad_group_resource_name 
 , 
  
 customizer_attribute_resource_name 
 = 
 nil 
 ) 
  
 ad_group_ad_service 
  
 = 
  
 client 
 . 
 service 
 . 
 ad_group_ad 
  
 operation 
  
 = 
  
 client 
 . 
 operation 
 . 
 create_ad_group_ad 
  
 do 
  
 | 
 aga 
 | 
  
 aga 
 . 
 status 
  
 = 
  
 :ENABLED 
  
 aga 
 . 
 ad_group 
  
 = 
  
 ad_group_resource_name 
  
 # Set responsive search ad info. 
  
 # https://developers.google.com/google-ads/api/reference/rpc/latest/ResponsiveSearchAdInfo 
  
 aga 
 . 
 ad 
  
 = 
  
 client 
 . 
 resource 
 . 
 ad 
  
 do 
  
 | 
 ad 
 | 
  
 ad 
 . 
 final_urls 
 << 
 "https://www.example.com/" 
  
 # Headline 1 (pinned) 
  
 pinned_headline 
  
 = 
  
 create_ad_text_asset 
 ( 
  
 client 
 , 
  
 "Headline 1 testing" 
 , 
  
 client 
 . 
 enum 
 . 
 served_asset_field_type 
 . 
 HEADLINE_1 
 , 
  
 ) 
  
 # Headlines 
  
 ad 
 . 
 responsive_search_ad 
  
 = 
  
 client 
 . 
 resource 
 . 
 responsive_search_ad_info 
  
 do 
  
 | 
 rsa 
 | 
  
 rsa 
 . 
 headlines 
 << 
 pinned_headline 
  
 rsa 
 . 
 headlines 
 << 
 create_ad_text_asset 
 ( 
 client 
 , 
  
 "Headline 2 testing" 
 ) 
  
 rsa 
 . 
 headlines 
 << 
 create_ad_text_asset 
 ( 
 client 
 , 
  
 "Headline 3 testing" 
 ) 
  
 # Descriptions 
  
 description_1 
  
 = 
  
 create_ad_text_asset 
 ( 
 client 
 , 
  
 "Desc 1 testing" 
 ) 
  
 description_2 
  
 = 
  
 if 
  
 customizer_attribute_resource_name 
  
 create_ad_text_asset_with_customizer 
 ( 
 client 
 , 
  
 customizer_attribute_resource_name 
 ) 
  
 else 
  
 create_ad_text_asset 
 ( 
 client 
 , 
  
 "Desc 2 testing" 
 ) 
  
 end 
  
 rsa 
 . 
 descriptions 
 << 
 description_1 
  
 rsa 
 . 
 descriptions 
 << 
 description_2 
  
 # Paths 
  
 rsa 
 . 
 path1 
  
 = 
  
 "all-inclusive" 
  
 rsa 
 . 
 path2 
  
 = 
  
 "deals" 
  
 end 
  
 end 
  
 end 
  
 # Send a request to the server to add a responsive search ad. 
  
 response 
  
 = 
  
 ad_group_ad_service 
 . 
 mutate_ad_group_ads 
 ( 
  
 customer_id 
 : 
  
 customer_id 
 , 
  
 operations 
 : 
  
 [ 
 operation 
 ] 
 , 
  
 ) 
  
 response 
 . 
 results 
 . 
 each 
  
 do 
  
 | 
 result 
 | 
  
 puts 
  
 "Created responsive search ad with resource name " 
 #{result.resource_name}"." 
  
 end 
 end 
 # Creates keywords. 
 # 
 # Creates 3 keyword match types: EXACT, PHRASE, and BROAD. 
 # 
 # Args: 
 #   client: An initialized GoogleAdsClient instance. 
 #   customer_id: A client customer ID. 
 #   ad_group_resource_name: An ad group resource name. 
 def 
  
 add_keywords 
 ( 
 client 
 , 
  
 customer_id 
 , 
  
 ad_group_resource_name 
 ) 
  
 ad_group_criterion_service 
  
 = 
  
 client 
 . 
 service 
 . 
 ad_group_criterion 
  
 keywords_to_add 
  
 = 
  
 [ 
  
 { 
  
 text 
 : 
  
 KEYWORD_TEXT_EXACT 
 , 
  
 match_type 
 : 
  
 :EXACT 
  
 }, 
  
 { 
  
 text 
 : 
  
 KEYWORD_TEXT_PHRASE 
 , 
  
 match_type 
 : 
  
 :PHRASE 
  
 }, 
  
 { 
  
 text 
 : 
  
 KEYWORD_TEXT_BROAD 
 , 
  
 match_type 
 : 
  
 :BROAD 
  
 }, 
  
 ] 
  
 operations 
  
 = 
  
 keywords_to_add 
 . 
 map 
  
 do 
  
 | 
 keyword_info 
 | 
  
 client 
 . 
 operation 
 . 
 create_ad_group_criterion 
  
 do 
  
 | 
 agc 
 | 
  
 agc 
 . 
 ad_group 
  
 = 
  
 ad_group_resource_name 
  
 agc 
 . 
 status 
  
 = 
  
 :ENABLED 
  
 agc 
 . 
 keyword 
  
 = 
  
 client 
 . 
 resource 
 . 
 keyword_info 
  
 do 
  
 | 
 ki 
 | 
  
 ki 
 . 
 text 
  
 = 
  
 keyword_info 
 [ 
 :text 
 ] 
  
 ki 
 . 
 match_type 
  
 = 
  
 keyword_info 
 [ 
 :match_type 
 ] 
  
 end 
  
 # Optional: agc.negative = true 
  
 # Optional: agc.final_urls << 'https://www.example.com' 
  
 end 
  
 end 
  
 # Add keywords 
  
 response 
  
 = 
  
 ad_group_criterion_service 
 . 
 mutate_ad_group_criteria 
 ( 
  
 customer_id 
 : 
  
 customer_id 
 , 
  
 operations 
 : 
  
 operations 
 , 
  
 ) 
  
 response 
 . 
 results 
 . 
 each 
  
 do 
  
 | 
 result 
 | 
  
 puts 
  
 "Created keyword 
 #{ 
 result 
 . 
 resource_name 
 } 
 ." 
  
 end 
 end 
 # Creates geo targets. 
 # 
 # Args: 
 #   client: An initialized GoogleAdsClient instance. 
 #   customer_id: A client customer ID. 
 #   campaign_resource_name: A campaign resource name. 
 def 
  
 add_geo_targeting 
 ( 
 client 
 , 
  
 customer_id 
 , 
  
 campaign_resource_name 
 ) 
  
 geo_target_constant_service 
  
 = 
  
 client 
 . 
 service 
 . 
 geo_target_constant 
  
 # Search by location names from 
  
 # GeoTargetConstantService.suggest_geo_target_constants() and directly 
  
 # apply GeoTargetConstant.resource_name. 
  
 gtc_request 
  
 = 
  
 client 
 . 
 request 
 . 
 suggest_geo_target_constants 
  
 do 
  
 | 
 req 
 | 
  
 req 
 . 
 locale 
  
 = 
  
 LOCALE 
  
 req 
 . 
 country_code 
  
 = 
  
 COUNTRY_CODE 
  
 # The location names to get suggested geo target constants. 
  
 req 
 . 
 location_names 
  
 = 
  
 client 
 . 
 resource 
 . 
 location_names 
  
 do 
  
 | 
 ln 
 | 
  
 ln 
 . 
 names 
 << 
 GEO_LOCATION_1 
  
 ln 
 . 
 names 
 << 
 GEO_LOCATION_2 
  
 ln 
 . 
 names 
 << 
 GEO_LOCATION_3 
  
 end 
  
 end 
  
 response 
  
 = 
  
 geo_target_constant_service 
 . 
 suggest_geo_target_constants 
 ( 
 gtc_request 
 ) 
  
 operations 
  
 = 
  
 response 
 . 
 geo_target_constant_suggestions 
 . 
 map 
  
 do 
  
 | 
 suggestion 
 | 
  
 puts 
  
 "geo_target_constant: 
 #{ 
 suggestion 
 . 
 geo_target_constant 
 . 
 resource_name 
 } 
 " 
 \ 
  
 "is found in LOCALE ( 
 #{ 
 suggestion 
 . 
 locale 
 } 
 ) " 
 \ 
  
 "with reach ( 
 #{ 
 suggestion 
 . 
 reach 
 } 
 ) " 
 \ 
  
 "from search term ( 
 #{ 
 suggestion 
 . 
 search_term 
 } 
 )." 
  
 # Create the campaign criterion for location targeting. 
  
 client 
 . 
 operation 
 . 
 create_campaign_criterion 
  
 do 
  
 | 
 cc 
 | 
  
 cc 
 . 
 campaign 
  
 = 
  
 campaign_resource_name 
  
 cc 
 . 
 location 
  
 = 
  
 client 
 . 
 resource 
 . 
 location_info 
  
 do 
  
 | 
 li 
 | 
  
 li 
 . 
 geo_target_constant 
  
 = 
  
 suggestion 
 . 
 geo_target_constant 
 . 
 resource_name 
  
 end 
  
 end 
  
 end 
  
 unless 
  
 operations 
 . 
 empty? 
  
 campaign_criterion_service 
  
 = 
  
 client 
 . 
 service 
 . 
 campaign_criterion 
  
 response 
  
 = 
  
 campaign_criterion_service 
 . 
 mutate_campaign_criteria 
 ( 
  
 customer_id 
 : 
  
 customer_id 
 , 
  
 operations 
 : 
  
 operations 
 , 
  
 ) 
  
 response 
 . 
 results 
 . 
 each 
  
 do 
  
 | 
 result 
 | 
  
 puts 
  
 "Added campaign criterion " 
 #{result.resource_name}"." 
  
 end 
  
 else 
  
 puts 
  
 "No geo target suggestions found for the given locations. Skipping campaign criteria creation." 
  
 end 
 end 
 # Main function that creates all necessary entities for the example. 
 # 
 # Args: 
 #   client: An initialized GoogleAdsClient instance. 
 #   customer_id: A client customer ID. 
 #   customizer_attribute_name: The name of the customizer attribute to be created. 
 def 
  
 main_function 
 ( 
 client 
 , 
  
 customer_id 
 , 
  
 customizer_attribute_name 
  
 = 
  
 nil 
 ) 
  
 customizer_attribute_resource_name 
  
 = 
  
 nil 
  
 if 
  
 customizer_attribute_name 
  
 customizer_attribute_resource_name 
  
 = 
  
 create_customizer_attribute 
 ( 
  
 client 
 , 
  
 customer_id 
 , 
  
 customizer_attribute_name 
 , 
  
 ) 
  
 link_customizer_attribute_to_customer 
 ( 
  
 client 
 , 
  
 customer_id 
 , 
  
 customizer_attribute_resource_name 
 , 
  
 ) 
  
 end 
  
 # Create a budget, which can be shared by multiple campaigns. 
  
 campaign_budget_resource_name 
  
 = 
  
 create_campaign_budget 
 ( 
 client 
 , 
  
 customer_id 
 ) 
  
 campaign_resource_name 
  
 = 
  
 create_campaign 
 ( 
  
 client 
 , 
  
 customer_id 
 , 
  
 campaign_budget_resource_name 
 , 
  
 ) 
  
 ad_group_resource_name 
  
 = 
  
 create_ad_group 
 ( 
  
 client 
 , 
  
 customer_id 
 , 
  
 campaign_resource_name 
 , 
  
 ) 
  
 create_ad_group_ad 
 ( 
  
 client 
 , 
  
 customer_id 
 , 
  
 ad_group_resource_name 
 , 
  
 customizer_attribute_resource_name 
 , 
  
 # Pass the resource name here 
  
 ) 
  
 add_keywords 
 ( 
 client 
 , 
  
 customer_id 
 , 
  
 ad_group_resource_name 
 ) 
  
 add_geo_targeting 
 ( 
 client 
 , 
  
 customer_id 
 , 
  
 campaign_resource_name 
 ) 
 end 
 # Entry point of the script 
 if 
  
 __FILE__ 
  
 == 
  
 $0 
  
 options 
  
 = 
  
 {} 
  
 # The following parameter(s) should be provided to run the example. You can 
  
 # either specify them here or provide them as command-line arguments. 
  
 # 
  
 # e.g. add_responsive_search_ad_full.rb -C YOUR_CUSTOMER_ID 
  
 OptionParser 
 . 
 new 
  
 do 
  
 | 
 opts 
 | 
  
 opts 
 . 
 banner 
  
 = 
  
 "Usage: add_responsive_search_ad_full.rb [options]" 
  
 opts 
 . 
 on 
 ( 
 '-C' 
 , 
  
 '--customer-id CUSTOMER-ID' 
 , 
  
 String 
 , 
  
 'Customer ID' 
 ) 
  
 do 
  
 | 
 v 
 | 
  
 options 
 [ 
 :customer_id 
 ] 
  
 = 
  
 v 
  
 end 
  
 opts 
 . 
 on 
 ( 
 '-N' 
 , 
  
 '--customizer-attribute-name CUSTOMIZER-ATTRIBUTE-NAME' 
 , 
  
 String 
 , 
  
 'Customizer attribute name' 
 ) 
  
 do 
  
 | 
 v 
 | 
  
 options 
 [ 
 :customizer_attribute_name 
 ] 
  
 = 
  
 v 
  
 end 
  
 end 
 . 
 parse! 
  
 if 
  
 options 
 [ 
 :customizer_attribute_name 
 ]. 
 nil? 
  
 options 
 [ 
 :customizer_attribute_name 
 ] 
  
 = 
  
 DEFAULT_CUSTOMIZER_ATTRIBUTE_NAME 
  
 end 
  
 # GoogleAdsClient will read the google-ads.yaml configuration file in the 
  
 # home directory if none is specified. 
  
 client 
  
 = 
  
 Google 
 :: 
 Ads 
 :: 
 GoogleAds 
 :: 
 GoogleAdsClient 
 . 
 new 
  
 begin 
  
 main_function 
 ( 
  
 client 
 , 
  
 options 
 . 
 fetch 
 ( 
 :customer_id 
 ) 
 . 
 tr 
 ( 
 "-" 
 , 
  
 "" 
 ), 
  
 options 
 . 
 fetch 
 ( 
 :customizer_attribute_name 
 ), 
  
 ) 
  
 rescue 
  
 Google 
 :: 
 Ads 
 :: 
 GoogleAds 
 :: 
 Errors 
 :: 
 GoogleAdsError 
  
 = 
>  
 e 
  
 e 
 . 
 failure 
 . 
 errors 
 . 
 each 
  
 do 
  
 | 
 error 
 | 
  
 STDERR 
 . 
 puts 
  
 "	Error with message ' 
 #{ 
 error 
 . 
 message 
 } 
 '." 
  
 if 
  
 error 
 . 
 location 
  
 error 
 . 
 location 
 . 
 field_path_elements 
 . 
 each 
  
 do 
  
 | 
 field_path_element 
 | 
  
 STDERR 
 . 
 puts 
  
 "		On field: 
 #{ 
 field_path_element 
 . 
 field_name 
 } 
 " 
  
 end 
  
 end 
  
 end 
  
 exit 
  
 1 
  
 rescue 
  
 OptionParser 
 :: 
 MissingArgument 
 , 
  
 KeyError 
  
 puts 
  
 "Missing required argument: -C or --customer-id" 
  
 exit 
  
 1 
  
 end 
 end 
  
  

Perl

 #!/usr/bin/perl -w 
 # 
 # Copyright 2024, 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 shows how to create a complete Responsive Search ad. 
 # Includes creation of: budget, campaign, ad group, ad group ad, keywords, 
 # and geo targeting. More details on Responsive Search ads can be found here: 
 # https://support.google.com/google-ads/answer/7684791 
 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::V22::Resources::Campaign 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Resources::CampaignBudget 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Resources::CampaignCriterion 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Resources::CustomizerAttribute 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Resources::CustomerCustomizer 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Resources::Ad 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Resources::AdGroup 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Resources::AdGroupAd 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Resources::AdGroupCriterion 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Resources::NetworkSettings 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Common::AdTextAsset 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Common::CustomizerValue 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Common::ImageDimension 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Common::KeywordInfo 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Common::LocationInfo 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Common::ResponsiveSearchAdInfo 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Common::TargetSpend 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Enums::AdvertisingChannelTypeEnum 
  
 qw(SEARCH) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Enums::BudgetDeliveryMethodEnum 
  
 qw(STANDARD) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Enums::CustomizerAttributeTypeEnum 
  
 qw(PRICE) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Enums::AdGroupAdStatusEnum 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Enums::AdGroupCriterionStatusEnum 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Enums::AdGroupStatusEnum 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Enums::AdGroupTypeEnum 
  
 qw(SEARCH_STANDARD) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Enums::AssetTypeEnum 
  
 qw(IMAGE) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Enums::CampaignStatusEnum 
  
 qw(PAUSED) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Enums::KeywordMatchTypeEnum 
  
 qw(BROAD EXACT PHRASE) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Enums::MimeTypeEnum 
  
 qw(IMAGE_PNG) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Enums::ServedAssetFieldTypeEnum 
  
 qw(HEADLINE_1) 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Services::AdGroupService::AdGroupOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Services::AdGroupAdService::AdGroupAdOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Services::AdGroupCriterionService::AdGroupCriterionOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Services::AssetService::AssetOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Services::CampaignBudgetService::CampaignBudgetOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Services::CampaignCriterionService::CampaignCriterionOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Services::CampaignService::CampaignOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Services::CustomizerAttributeService::CustomizerAttributeOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Services::CustomerCustomizerService::CustomerCustomizerOperation 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Services::GeoTargetConstantService::LocationNames 
 ; 
 use 
  
 Google::Ads::GoogleAds::V22::Utils::ResourceNames 
 ; 
 use 
  
 Getopt::Long 
  
 qw(:config auto_help) 
 ; 
 use 
  
 Pod::Usage 
 ; 
 use 
  
 Cwd 
  
 qw(abs_path) 
 ; 
 use 
  
 Data::Uniqid 
  
 qw(uniqid) 
 ; 
 # Keywords from the user. 
 use 
  
 constant 
  
 KEYWORD_TEXT_EXACT 
  
 = 
>  
 "example of exact match" 
 ; 
 use 
  
 constant 
  
 KEYWORD_TEXT_PHRASE 
  
 = 
>  
 "example of phrase match" 
 ; 
 use 
  
 constant 
  
 KEYWORD_TEXT_BROAD 
  
 = 
>  
 "example of broad match" 
 ; 
 # Geo targeting from the user. 
 use 
  
 constant 
  
 GEO_LOCATION_1 
  
 = 
>  
 "Buenos Aires" 
 ; 
 use 
  
 constant 
  
 GEO_LOCATION_2 
  
 = 
>  
 "San Isidro" 
 ; 
 use 
  
 constant 
  
 GEO_LOCATION_3 
  
 = 
>  
 "Mar del Plata" 
 ; 
 # LOCALE and COUNTRY_CODE are used for geo targeting. 
 # LOCALE is using ISO 639-1 format. If an invalid LOCALE is given, 
 # 'es' is used by default. 
 use 
  
 constant 
  
 LOCALE 
  
 = 
>  
 "es" 
 ; 
 # A list of country codes can be referenced here: 
 # https://developers.google.com/google-ads/api/reference/data/geotargets 
 use 
  
 constant 
  
 COUNTRY_CODE 
  
 = 
>  
 "AR" 
 ; 
 use 
  
 constant 
  
 IMAGE_URL 
  
 = 
>  
 "https://gaagl.page.link/bjYi" 
 ; 
 sub 
  
 add_responsive_search_ad_full 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $customizer_attribute_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 # If a customizer attribute name is provided, create the customizer 
  
 # attribute and link it to the customer. 
  
 # For more information on customizer attributes, visit: 
  
 # https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads 
  
 if 
  
 ( 
 defined 
  
 $customizer_attribute_name 
 ) 
  
 { 
  
 my 
  
 $customizer_attribute_resource_name 
  
 = 
  
 create_customizer_attribute 
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $customizer_attribute_name 
 ); 
  
 link_customizer_attribute_to_customer 
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $customizer_attribute_resource_name 
 ); 
  
 } 
  
 # Create a budget, which can be shared by multiple campaigns. 
  
 my 
  
 $campaign_budget 
  
 = 
  
 create_campaign_budget 
 ( 
 $api_client 
 , 
  
 $customer_id 
 ); 
  
 # Create a search campaign. 
  
 my 
  
 $campaign_resource_name 
  
 = 
  
 create_campaign 
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $campaign_budget 
 ); 
  
 # Create an empty ad group. 
  
 my 
  
 $ad_group_resource_name 
  
 = 
  
 create_ad_group 
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $campaign_resource_name 
 ); 
  
 # Create a responsive search ad within the ad group we just created. 
  
 create_ad_group_ad 
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $ad_group_resource_name 
 , 
  
 $customizer_attribute_name 
 ); 
  
 # Create 3 keywords of match type EXACT, PHRASE, and BROAD, and add them 
  
 # as criteria on our ad group. 
  
 add_keywords 
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $ad_group_resource_name 
 ); 
  
 # Create geo targets and add them as criteria on our campaign. 
  
 add_geo_targeting 
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $campaign_resource_name 
 ); 
  
 return 
  
 1 
 ; 
 } 
 # Creates a customizer attribute with the given customizer attribute name. 
 sub 
  
 create_customizer_attribute 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $customizer_attribute_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $customizer_attribute 
  
 = 
  
 Google::Ads::GoogleAds::V22::Resources:: 
 CustomizerAttribute 
 - 
> new 
 ({ 
  
 name 
  
 = 
>  
 $customizer_attribute_name 
 , 
  
 # Specify the type to be 'PRICE' so that we can dynamically customize the part 
  
 # of the ad's description that is a price of a product/service we advertise. 
  
 type 
  
 = 
>  
 PRICE 
  
 }); 
  
 # Create a customizer attribute operation for creating a customizer attribute. 
  
 my 
  
 $operation 
  
 = 
  
 Google::Ads::GoogleAds::V22::Services::CustomizerAttributeService:: 
 CustomizerAttributeOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $customizer_attribute 
  
 }); 
  
 my 
  
 $response 
  
 = 
  
 $api_client 
 - 
> CustomizerAttributeService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 [ 
 $operation 
 ]}); 
  
 my 
  
 $resource_name 
  
 = 
  
 $response 
 - 
> { 
 results 
 }[ 
 0 
 ]{ 
 resourceName 
 }; 
  
 printf 
  
 "Added a customizer attribute with resource name '%s'.\n" 
 , 
  
 $resource_name 
 ; 
  
 return 
  
 $resource_name 
 ; 
 } 
 # Links the customizer attribute to the customer. 
 sub 
  
 link_customizer_attribute_to_customer 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $customizer_attribute_resource_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 # Create a customer customizer with the value to be used in the responsive search ad. 
  
 my 
  
 $customer_customizer 
  
 = 
  
 Google::Ads::GoogleAds::V22::Resources:: 
 CustomerCustomizer 
 - 
> new 
 ({ 
  
 customizerAttribute 
  
 = 
>  
 $customizer_attribute_resource_name 
 , 
  
 # Specify '100USD' as a text value. The ad customizer will dynamically replace 
  
 # the placeholder with this value when the ad serves. 
  
 value 
  
 = 
>  
 Google::Ads::GoogleAds::V22::Common:: 
 CustomizerValue 
 - 
> new 
 ({ 
  
 type 
  
 = 
>  
 PRICE 
 , 
  
 stringValue 
  
 = 
>  
 "100USD" 
  
 })}); 
  
 # Create a customer customizer operation. 
  
 my 
  
 $operation 
  
 = 
  
 Google::Ads::GoogleAds::V22::Services::CustomerCustomizerService:: 
 CustomerCustomizerOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $customer_customizer 
  
 }); 
  
 # Issue a mutate request to add the customer customizer and print its information. 
  
 my 
  
 $response 
  
 = 
  
 $api_client 
 - 
> CustomerCustomizerService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 [ 
 $operation 
 ]}); 
  
 printf 
  
 "Added a customer customizer with resource name '%s'.\n" 
 , 
  
 $response 
 - 
> { 
 results 
 }[ 
 0 
 ]{ 
 resourceName 
 }; 
 } 
 # Creates an AdTextAsset. 
 sub 
  
 create_ad_text_asset 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $text 
 , 
  
 $pinned_field 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $ad_text_asset 
  
 = 
  
 Google::Ads::GoogleAds::V22::Common:: 
 AdTextAsset 
 - 
> new 
 ({ 
  
 text 
  
 = 
>  
 $text 
  
 }); 
  
 if 
  
 ( 
 defined 
  
 $pinned_field 
 ) 
  
 { 
  
 $ad_text_asset 
 - 
> { 
 pinnedField 
 } 
  
 = 
  
 $pinned_field 
 ; 
  
 } 
  
 return 
  
 $ad_text_asset 
 ; 
 } 
 # Creates an AdTextAsset with a customizer in the text. 
 sub 
  
 create_ad_text_asset_with_customizer 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customizer_attribute_resource_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $ad_text_asset 
  
 = 
  
 create_ad_text_asset 
 ( 
 $api_client 
 , 
  
 "Just {CUSTOMIZER.$customizer_attribute_resource_name:10USD}" 
 ); 
  
 return 
  
 $ad_text_asset 
 ; 
 } 
 # Creates a campaign budget. 
 sub 
  
 create_campaign_budget 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 ) 
  
 = 
  
 @_ 
 ; 
  
 # Create a campaign budget. 
  
 my 
  
 $campaign_budget 
  
 = 
  
 Google::Ads::GoogleAds::V22::Resources:: 
 CampaignBudget 
 - 
> new 
 ({ 
  
 name 
  
 = 
>  
 "Campaign budget " 
  
 . 
  
 uniqid 
 (), 
  
 amountMicros 
  
 = 
>  
 50000000 
 , 
  
 deliveryMethod 
  
 = 
>  
 STANDARD 
  
 }); 
  
 # Create a campaign budget operation. 
  
 my 
  
 $campaign_budget_operation 
  
 = 
  
 Google::Ads::GoogleAds::V22::Services::CampaignBudgetService:: 
 CampaignBudgetOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $campaign_budget 
  
 }); 
  
 # Issue a mutate request to add the campaign budget. 
  
 my 
  
 $campaign_budgets_response 
  
 = 
  
 $api_client 
 - 
> CampaignBudgetService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 [ 
 $campaign_budget_operation 
 ]}); 
  
 my 
  
 $campaign_budget_resource_name 
  
 = 
  
 $campaign_budgets_response 
 - 
> { 
 results 
 }[ 
 0 
 ]{ 
 resourceName 
 }; 
  
 return 
  
 $campaign_budget_resource_name 
 ; 
 } 
 # Creates a campaign. 
 sub 
  
 create_campaign 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $campaign_budget 
 ) 
  
 = 
  
 @_ 
 ; 
  
 # Create a campaign. 
  
 my 
  
 $campaign 
  
 = 
  
 Google::Ads::GoogleAds::V22::Resources:: 
 Campaign 
 - 
> new 
 ({ 
  
 name 
  
 = 
>  
 "Testing RSA via API " 
  
 . 
  
 uniqid 
 (), 
  
 campaignBudget 
  
 = 
>  
 $campaign_budget 
 , 
  
 # 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 
  
 = 
>  
 PAUSED 
 , 
  
 advertisingChannelType 
  
 = 
>  
 SEARCH 
 , 
  
 # Set the bidding strategy and budget. 
  
 # The bidding strategy for Maximize Clicks is TargetSpend. 
  
 # The target_spend_micros is deprecated so don't put any value. 
  
 # See other bidding strategies you can select in the link below. 
  
 # https://developers.google.com/google-ads/api/reference/rpc/latest/Campaign#campaign_bidding_strategy 
  
 targetSpend 
  
 = 
>  
 Google::Ads::GoogleAds::V22::Common:: 
 TargetSpend 
 - 
> new 
 (), 
  
 # Set the campaign network options 
  
 networkSettings 
  
 = 
>  
 Google::Ads::GoogleAds::V22::Resources:: 
 NetworkSettings 
 - 
> new 
 ({ 
  
 targetGoogleSearch 
  
 = 
>  
 "true" 
 , 
  
 targetSearchNetwork 
  
 = 
>  
 "true" 
 , 
  
 # Enable Display Expansion on Search campaigns. See 
  
 # https://support.google.com/google-ads/answer/7193800 to learn more. 
  
 targetContentNetwork 
  
 = 
>  
 "true" 
 , 
  
 targetPartnerSearchNetwork 
  
 = 
>  
 "false" 
  
 } 
  
 ), 
  
 # Optional: Set the start date. The campaign starts tomorrow. 
  
 # startDate => strftime("%Y%m%d", localtime(time + 60 * 60 * 24)), 
  
 # Optional: Set the end date. The campaign runs for 30 days. 
  
 # endDate => strftime("%Y%m%d", localtime(time + 60 * 60 * 24 * 30)), 
  
 }); 
  
 # Create a campaign operation. 
  
 my 
  
 $campaign_operation 
  
 = 
  
 Google::Ads::GoogleAds::V22::Services::CampaignService:: 
 CampaignOperation 
 - 
>  
 new 
 ({ 
  
 create 
  
 = 
>  
 $campaign 
  
 }); 
  
 # Issue a mutate request to add the campaign. 
  
 my 
  
 $campaigns_response 
  
 = 
  
 $api_client 
 - 
> CampaignService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 [ 
 $campaign_operation 
 ]}); 
  
 my 
  
 $resource_name 
  
 = 
  
 $campaigns_response 
 - 
> { 
 results 
 }[ 
 0 
 ]{ 
 resourceName 
 }; 
  
 printf 
  
 "Created App campaign with resource name: '%s'.\n" 
 , 
  
 $resource_name 
 ; 
  
 return 
  
 $resource_name 
 ; 
 } 
 # Creates an ad group. 
 sub 
  
 create_ad_group 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $campaign_resource_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 # Create an ad group, setting an optional CPC value. 
  
 my 
  
 $ad_group 
  
 = 
  
 Google::Ads::GoogleAds::V22::Resources:: 
 AdGroup 
 - 
> new 
 ({ 
  
 name 
  
 = 
>  
 "Testing RSA via API " 
  
 . 
  
 uniqid 
 (), 
  
 status 
  
 = 
>  
 Google::Ads::GoogleAds::V22::Enums::AdGroupStatusEnum:: 
 ENABLED 
 , 
  
 campaign 
  
 = 
>  
 $campaign_resource_name 
 , 
  
 type 
  
 = 
>  
 SEARCH_STANDARD 
 , 
  
 # If you want to set up a max CPC bid, uncomment the line below. 
  
 # cpcBidMicros => 10000000 
  
 }); 
  
 # Create an ad group operation. 
  
 my 
  
 $ad_group_operation 
  
 = 
  
 Google::Ads::GoogleAds::V22::Services::AdGroupService:: 
 AdGroupOperation 
 - 
>  
 new 
 ({ 
 create 
  
 = 
>  
 $ad_group 
 }); 
  
 # Add the ad group. 
  
 my 
  
 $ad_groups_response 
  
 = 
  
 $api_client 
 - 
> AdGroupService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 [ 
 $ad_group_operation 
 ]}); 
  
 my 
  
 $ad_group_resource_name 
  
 = 
  
 $ad_groups_response 
 - 
> { 
 results 
 }[ 
 0 
 ]{ 
 resourceName 
 }; 
  
 printf 
  
 "Created ad group '%s'.\n" 
 , 
  
 $ad_group_resource_name 
 ; 
  
 return 
  
 $ad_group_resource_name 
 ; 
 } 
 # Creates an ad group ad. 
 sub 
  
 create_ad_group_ad 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $ad_group_resource_name 
 , 
  
 $customizer_attribute_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 # Set a pinning to always choose this asset for HEADLINE_1. Pinning is optional; if no 
  
 # pinning is set, then headlines and descriptions will be rotated and the ones that perform 
  
 # best will be used more often. 
  
 my 
  
 $pinned_headline 
  
 = 
  
 create_ad_text_asset 
 ( 
 $api_client 
 , 
  
 "Headline 1 testing" 
 , 
  
 HEADLINE_1 
 ); 
  
 my 
  
 $ad_group_ad 
  
 = 
  
 Google::Ads::GoogleAds::V22::Resources:: 
 AdGroupAd 
 - 
> new 
 ({ 
  
 adGroup 
  
 = 
>  
 $ad_group_resource_name 
 , 
  
 status 
  
 = 
>  
 Google::Ads::GoogleAds::V22::Enums::AdGroupAdStatusEnum:: 
 ENABLED 
 , 
  
 ad 
  
 = 
>  
 Google::Ads::GoogleAds::V22::Resources:: 
 Ad 
 - 
> new 
 ({ 
  
 # Set responsive search ad info. 
  
 # https://developers.google.com/google-ads/api/reference/rpc/latest/ResponsiveSearchAdInfo 
  
 responsiveSearchAd 
  
 = 
>  
 Google::Ads::GoogleAds::V22::Common:: 
 ResponsiveSearchAdInfo 
 - 
> new 
 ({ 
  
 headlines 
  
 = 
>  
 [ 
  
 $pinned_headline 
 , 
  
 create_ad_text_asset 
 ( 
 $api_client 
 , 
  
 "Headline 2 testing" 
 ), 
  
 create_ad_text_asset 
 ( 
 $api_client 
 , 
  
 "Headline 3 testing" 
 ), 
  
 ], 
  
 descriptions 
  
 = 
>  
 [ 
  
 create_ad_text_asset 
 ( 
 $api_client 
 , 
  
 "Desc 1 testing" 
 ), 
  
 defined 
  
 $customizer_attribute_name 
  
 ? 
  
 create_ad_text_asset_with_customizer 
 ( 
 $api_client 
 , 
  
 $customizer_attribute_name 
 ) 
  
 : 
  
 create_ad_text_asset 
 ( 
 $api_client 
 , 
  
 "Desc 2 testing" 
 ), 
  
 ], 
  
 # First and second part of text that can be appended to the URL in the ad. 
  
 # If you use the examples below, the ad will show 
  
 # https://www.example.com/all-inclusive/deals 
  
 path1 
  
 = 
>  
 "all-inclusive" 
 , 
  
 path2 
  
 = 
>  
 "deals" 
  
 } 
  
 ), 
  
 finalUrls 
  
 = 
>  
 [ 
 "https://www.example.com" 
 ]})}); 
  
 # Create an ad group ad operation. 
  
 my 
  
 $operation 
  
 = 
  
 Google::Ads::GoogleAds::V22::Services::AdGroupAdService:: 
 AdGroupAdOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $ad_group_ad 
  
 }); 
  
 # Issue a mutate request to add the ad group ad and print its information. 
  
 my 
  
 $response 
  
 = 
  
 $api_client 
 - 
> AdGroupAdService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 [ 
 $operation 
 ]}); 
  
 printf 
  
 "Created responsive search ad with resource name '%s'.\n" 
 , 
  
 $response 
 - 
> { 
 results 
 }[ 
 0 
 ]{ 
 resourceName 
 }; 
 } 
 # Creates keywords of 3 keyword match types: EXACT, PHRASE, and BROAD. 
 # EXACT: ads may show on searches that ARE the same meaning as your keyword. 
 # PHRASE: ads may show on searches that INCLUDE the meaning of your keyword. 
 # BROAD: ads may show on searches that RELATE to your keyword. 
 # For smart bidding, BROAD is the recommended one. 
 sub 
  
 add_keywords 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $ad_group_resource_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $operations 
  
 = 
  
 [] 
 ; 
  
 # Create a hash of keyword match types to keyword text to simplify ad group 
  
 # criteria construction. 
  
 my 
  
 $keywords 
  
 = 
  
 { 
  
 EXACT 
 () 
  
 = 
>  
 KEYWORD_TEXT_EXACT 
 , 
  
 BROAD 
 () 
  
 = 
>  
 KEYWORD_TEXT_BROAD 
 , 
  
 PHRASE 
 () 
  
 = 
>  
 KEYWORD_TEXT_PHRASE 
 , 
  
 }; 
  
 foreach 
  
 my 
  
 $keyword 
  
 ( 
 keys 
  
 %$keywords 
 ) 
  
 { 
  
 my 
  
 $keyword_info 
  
 = 
  
 Google::Ads::GoogleAds::V22::Common:: 
 KeywordInfo 
 - 
> new 
 ({ 
  
 text 
  
 = 
>  
 $keywords 
 - 
> { 
 $keyword 
 }, 
  
 matchType 
  
 = 
>  
 $keyword 
 , 
  
 }); 
  
 my 
  
 $ad_group_criterion 
  
 = 
  
 Google::Ads::GoogleAds::V22::Resources:: 
 AdGroupCriterion 
 - 
> new 
 ({ 
  
 adGroup 
  
 = 
>  
 $ad_group_resource_name 
 , 
  
 status 
  
 = 
>  
 Google::Ads::GoogleAds::V22::Enums::AdGroupCriterionStatusEnum:: 
 ENABLED 
 , 
  
 keyword 
  
 = 
>  
 $keyword_info 
 , 
  
 # Uncomment the below line if you want to change this keyword to a negative target. 
  
 # negative => "true", 
  
 # Optional repeated field. 
  
 # finalUrls => ["https://www.example.com"], 
  
 }); 
  
 my 
  
 $ad_group_criterion_operation 
  
 = 
  
 Google::Ads::GoogleAds::V22::Services::AdGroupCriterionService:: 
 AdGroupCriterionOperation 
  
 - 
> new 
 ({ 
 create 
  
 = 
>  
 $ad_group_criterion 
 }); 
  
 push 
  
 @$operations 
 , 
  
 $ad_group_criterion_operation 
 ; 
  
 } 
  
 my 
  
 $response 
  
 = 
  
 $api_client 
 - 
> AdGroupCriterionService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 $operations 
  
 }); 
  
 foreach 
  
 my 
  
 $result 
  
 ( 
 @ 
 { 
 $response 
 - 
> { 
 results 
 }}) 
  
 { 
  
 printf 
  
 "Created keyword with resource name: '%s'.\n" 
 , 
  
 $result 
 - 
> { 
 resourceName 
 }; 
  
 } 
 } 
 # Creates geo targets. 
 sub 
  
 add_geo_targeting 
  
 { 
  
 my 
  
 ( 
 $api_client 
 , 
  
 $customer_id 
 , 
  
 $campaign_resource_name 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $suggest_response 
  
 = 
  
 $api_client 
 - 
> GeoTargetConstantService 
 () 
 - 
> suggest 
 ({ 
  
 locale 
  
 = 
>  
 LOCALE 
 , 
  
 countryCode 
  
 = 
>  
 COUNTRY_CODE 
 , 
  
 locationNames 
  
 = 
>  
 Google::Ads::GoogleAds::V22::Services::GeoTargetConstantService:: 
 LocationNames 
  
 - 
> new 
 ({ 
  
 names 
  
 = 
>  
 [ 
 GEO_LOCATION_1 
 , 
  
 GEO_LOCATION_2 
 , 
  
 GEO_LOCATION_3 
 ]})}); 
  
 my 
  
 $operations 
  
 = 
  
 [] 
 ; 
  
 foreach 
  
 my 
  
 $geo_target_constant_suggestion 
  
 ( 
  
 @ 
 { 
 $suggest_response 
 - 
> { 
 geoTargetConstantSuggestions 
 }}) 
  
 { 
  
 printf 
  
 "geo target constant: '%s' is found in locale '%s' with reach %d" 
  
 . 
  
 " for the search term '%s'.\n" 
 , 
  
 $geo_target_constant_suggestion 
 - 
> { 
 geoTargetConstant 
 }{ 
 resourceName 
 }, 
  
 $geo_target_constant_suggestion 
 - 
> { 
 locale 
 }, 
  
 $geo_target_constant_suggestion 
 - 
> { 
 reach 
 }, 
  
 $geo_target_constant_suggestion 
 - 
> { 
 searchTerm 
 }; 
  
 # Create the campaign criterion for location targeting. 
  
 my 
  
 $campaign_criterion 
  
 = 
  
 Google::Ads::GoogleAds::V22::Resources:: 
 CampaignCriterion 
 - 
> new 
 ({ 
  
 location 
  
 = 
>  
 Google::Ads::GoogleAds::V22::Common:: 
 LocationInfo 
 - 
> new 
 ({ 
  
 geoTargetConstant 
  
 = 
>  
 $geo_target_constant_suggestion 
 - 
> { 
 geoTargetConstant 
 }{ 
 resourceName 
 } 
  
 } 
  
 ), 
  
 campaign 
  
 = 
>  
 $campaign_resource_name 
  
 }); 
  
 push 
  
 @$operations 
 , 
  
 Google::Ads::GoogleAds::V22::Services::CampaignCriterionService:: 
 CampaignCriterionOperation 
  
 - 
> new 
 ({ 
  
 create 
  
 = 
>  
 $campaign_criterion 
  
 }); 
  
 } 
  
 # Return if operations is empty. 
  
 if 
  
 ( 
 scalar 
  
 @$operations 
  
 == 
  
 0 
 ) 
  
 { 
  
 return 
 ; 
  
 } 
  
 my 
  
 $campaign_criterion_response 
  
 = 
  
 $api_client 
 - 
> CampaignCriterionService 
 () 
 - 
> mutate 
 ({ 
  
 customerId 
  
 = 
>  
 $customer_id 
 , 
  
 operations 
  
 = 
>  
 $operations 
  
 }); 
  
 my 
  
 $campaign_criterion_results 
  
 = 
  
 $campaign_criterion_response 
 - 
> { 
 results 
 }; 
  
 printf 
  
 "Added %d campaign criteria:\n" 
 , 
  
 scalar 
  
 @$campaign_criterion_results 
 ; 
  
 foreach 
  
 my 
  
 $campaign_criterion_result 
  
 ( 
 @$campaign_criterion_results 
 ) 
  
 { 
  
 printf 
  
 "\t%s\n" 
 , 
  
 $campaign_criterion_result 
 - 
> { 
 resourceName 
 }; 
  
 } 
 } 
 # Don't run the example if the file is being included. 
 if 
  
 ( 
 abs_path 
 ( 
 $0 
 ) 
  
 ne 
  
 abs_path 
 ( 
 __FILE__ 
 )) 
  
 { 
  
 return 
  
 1 
 ; 
 } 
 # Get Google Ads Client, credentials will be read from ~/googleads.properties. 
 my 
  
 $api_client 
  
 = 
  
 Google::Ads::GoogleAds:: 
 Client 
 - 
> new 
 (); 
 # By default examples are set to die on any server returned fault. 
 $api_client 
 - 
> set_die_on_faults 
 ( 
 1 
 ); 
 my 
  
 $customer_id 
 ; 
 my 
  
 $customizer_attribute_name 
 ; 
 # Parameters passed on the command line will override any parameters set in code. 
 GetOptions 
 ( 
  
 "customer_id=s" 
  
 = 
>  
 \ 
 $customer_id 
 , 
  
 "customizer_attribute_name=s" 
  
 = 
>  
 \ 
 $customizer_attribute_name 
 , 
 ); 
 # 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_responsive_search_ad_full 
 ( 
 $api_client 
 , 
  
 $customer_id 
  
 =~ 
  
 s/-//g 
 r 
 , 
  
 $customizer_attribute_name 
 ); 
 =pod 
 =head1 NAME 
 add_responsive_search_ad_full 
 =head1 DESCRIPTION 
 This example shows how to create a complete Responsive Search ad. 
 Includes creation of: budget, campaign, ad group, ad group ad, keywords, 
 and geo targeting. More details on Responsive Search ads can be found here: 
 https://support.google.com/google-ads/answer/7684791 
 =head1 SYNOPSIS 
 add_responsive_search_ad_full.pl [options] 
 -help                           Show the help message. 
 -customer_id                    The Google Ads customer ID. 
 -customizer_attribute_name      [optional] The name of the customizer attribute. 
 =cut 
  
  
Design a Mobile Site
View Site in Mobile | Classic
Share by: