Skip to content

Commit ab8fb84

Browse files
authored
Add RSA customizers example (#523)
* Add RSA customizers example Change-Id: I93551c73d83afd708519aedb328ea0b9cb50b93d * Add clarifying comments Change-Id: Ieac4935f01860d841141e1ecf559feee071aa071
1 parent 83b3bb4 commit ab8fb84

2 files changed

Lines changed: 270 additions & 0 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
// Copyright 2021 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.ads.googleads.examples.advancedoperations;
16+
17+
import com.beust.jcommander.Parameter;
18+
import com.google.ads.googleads.examples.utils.ArgumentNames;
19+
import com.google.ads.googleads.examples.utils.CodeSampleParams;
20+
import com.google.ads.googleads.lib.GoogleAdsClient;
21+
import com.google.ads.googleads.v9.enums.AdGroupAdStatusEnum.AdGroupAdStatus;
22+
import com.google.ads.googleads.v9.services.AdGroupAdOperation;
23+
import com.google.ads.googleads.v9.services.AdGroupAdServiceClient;
24+
import com.google.ads.googleads.v9.services.MutateAdGroupAdsResponse;
25+
import com.google.ads.googleads.v9.utils.ResourceNames;
26+
import com.google.ads.googleads.v9.common.AdTextAsset;
27+
import com.google.ads.googleads.v9.common.CustomizerValue;
28+
import com.google.ads.googleads.v9.common.ResponsiveSearchAdInfo;
29+
import com.google.ads.googleads.v9.enums.CustomizerAttributeTypeEnum.CustomizerAttributeType;
30+
import com.google.ads.googleads.v9.errors.GoogleAdsError;
31+
import com.google.ads.googleads.v9.errors.GoogleAdsException;
32+
import com.google.ads.googleads.v9.resources.Ad;
33+
import com.google.ads.googleads.v9.resources.AdGroupAd;
34+
import com.google.ads.googleads.v9.resources.CustomerCustomizer;
35+
import com.google.ads.googleads.v9.resources.CustomizerAttribute;
36+
import com.google.ads.googleads.v9.services.CustomerCustomizerOperation;
37+
import com.google.ads.googleads.v9.services.CustomerCustomizerServiceClient;
38+
import com.google.ads.googleads.v9.services.CustomizerAttributeOperation;
39+
import com.google.ads.googleads.v9.services.CustomizerAttributeServiceClient;
40+
import com.google.ads.googleads.v9.services.MutateCustomerCustomizersResponse;
41+
import com.google.ads.googleads.v9.services.MutateCustomizerAttributesResponse;
42+
import com.google.common.collect.ImmutableList;
43+
import java.io.FileNotFoundException;
44+
import java.io.IOException;
45+
import java.util.List;
46+
import java.util.stream.Collectors;
47+
48+
/**
49+
* Adds a customizer attribute, links the customizer attribute to a customer, and then adds a
50+
* responsive search ad with a description using the ad customizer to the specified ad group.
51+
*/
52+
public class AddResponsiveSearchAdWithAdCustomizer {
53+
54+
private static class AddResponsiveSearchAdWithAdCustomizerParams extends CodeSampleParams {
55+
56+
@Parameter(names = ArgumentNames.CUSTOMER_ID, required = true)
57+
private Long customerId;
58+
59+
@Parameter(names = ArgumentNames.AD_GROUP_ID, required = true)
60+
private Long adGroupId;
61+
62+
// The name of the customizer attribute to be used in the ad customizer, which must be unique.
63+
// To run this example multiple times, change this value or specify its corresponding argument.
64+
// Note that there is a limit for the number of enabled customizer attributes in one account,
65+
// so you shouldn't run this example more than necessary.
66+
// Visit
67+
// https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads?hl=en#rules_and_limitations
68+
// for details.
69+
@Parameter(names = ArgumentNames.CUSTOMIZER_ATTRIBUTE_NAME)
70+
private String customizerAttributeName;
71+
}
72+
73+
public static void main(String[] args) {
74+
AddResponsiveSearchAdWithAdCustomizerParams params =
75+
new AddResponsiveSearchAdWithAdCustomizerParams();
76+
if (!params.parseArguments(args)) {
77+
78+
// Either pass the required parameters for this example on the command line, or insert them
79+
// into the code here. See the parameter class definition above for descriptions.
80+
params.customerId = Long.parseLong("INSERT_CUSTOMER_ID_HERE");
81+
params.adGroupId = Long.parseLong("INSERT_AD_GROUP_ID_HERE");
82+
83+
// Optional: Specify a customizerAttributeName. The default value in this example is "Price".
84+
params.customizerAttributeName = "Price";
85+
}
86+
87+
GoogleAdsClient googleAdsClient = null;
88+
try {
89+
googleAdsClient = GoogleAdsClient.newBuilder().fromPropertiesFile().build();
90+
} catch (FileNotFoundException fnfe) {
91+
System.err.printf(
92+
"Failed to load GoogleAdsClient configuration from file. Exception: %s%n", fnfe);
93+
System.exit(1);
94+
} catch (IOException ioe) {
95+
System.err.printf("Failed to create GoogleAdsClient. Exception: %s%n", ioe);
96+
System.exit(1);
97+
}
98+
99+
try {
100+
new AddResponsiveSearchAdWithAdCustomizer()
101+
.runExample(
102+
googleAdsClient, params.customerId, params.adGroupId, params.customizerAttributeName);
103+
} catch (GoogleAdsException gae) {
104+
// GoogleAdsException is the base class for most exceptions thrown by an API request.
105+
// Instances of this exception have a message and a GoogleAdsFailure that contains a
106+
// collection of GoogleAdsErrors that indicate the underlying causes of the
107+
// GoogleAdsException.
108+
System.err.printf(
109+
"Request ID %s failed due to GoogleAdsException. Underlying errors:%n",
110+
gae.getRequestId());
111+
int i = 0;
112+
for (GoogleAdsError googleAdsError : gae.getGoogleAdsFailure().getErrorsList()) {
113+
System.err.printf(" Error %d: %s%n", i++, googleAdsError);
114+
}
115+
System.exit(1);
116+
}
117+
}
118+
119+
/**
120+
* Runs the example.
121+
*
122+
* @param googleAdsClient the Google Ads API client.
123+
* @param customerId the client customer ID.
124+
* @param adGroupId the ad group ID.
125+
* @param customizerAttributeName the customizer attribute name.
126+
*/
127+
private void runExample(
128+
GoogleAdsClient googleAdsClient,
129+
long customerId,
130+
long adGroupId,
131+
String customizerAttributeName) {
132+
String customizerAttributeResourceName =
133+
createCustomizerAttribute(googleAdsClient, customerId, customizerAttributeName);
134+
linkCustomizerAttributeToCustomer(googleAdsClient, customerId, customizerAttributeResourceName);
135+
createResponsiveSearchAdWithCustomization(
136+
googleAdsClient, customerId, adGroupId, customizerAttributeName);
137+
}
138+
139+
// [START add_responsive_search_ad_with_ad_customizer_1]
140+
/** Creates a customizer attribute with the specified customizer attribute name. */
141+
private static String createCustomizerAttribute(
142+
GoogleAdsClient googleAdsClient, long customerId, String customizerAttributeName) {
143+
// Creates a customizer attribute with the specified name.
144+
CustomizerAttribute customizerAttribute =
145+
CustomizerAttribute.newBuilder()
146+
.setName(customizerAttributeName)
147+
// Specifies the type to be 'PRICE' so that we can dynamically customize the part of the
148+
// ad's description that is a price of a product/service we advertise.
149+
.setType(CustomizerAttributeType.PRICE)
150+
.build();
151+
// Creates a customizer attribute operation for creating a customizer attribute.
152+
CustomizerAttributeOperation operation =
153+
CustomizerAttributeOperation.newBuilder().setCreate(customizerAttribute).build();
154+
155+
try (CustomizerAttributeServiceClient customizerAttributeServiceClient =
156+
googleAdsClient.getLatestVersion().createCustomizerAttributeServiceClient()) {
157+
// Issues a mutate request to add the customizer attribute and prints its information.
158+
MutateCustomizerAttributesResponse response =
159+
customizerAttributeServiceClient.mutateCustomizerAttributes(
160+
Long.toString(customerId), ImmutableList.of(operation));
161+
String resourceName = response.getResults(0).getResourceName();
162+
System.out.printf("Added a customizer with resource name '%s'.%n", resourceName);
163+
return resourceName;
164+
}
165+
}
166+
// [END add_responsive_search_ad_with_ad_customizer_1]
167+
168+
// [START add_responsive_search_ad_with_ad_customizer_2]
169+
/**
170+
* Links the customizer attribute to the customer by providing a value to be used in a responsive
171+
* search ad that will be created in a later step.
172+
*/
173+
private static void linkCustomizerAttributeToCustomer(
174+
GoogleAdsClient googleAdsClient, long customerId, String customizerAttributeResourceName) {
175+
// Creates a customer customizer with the value to be used in the responsive search ad.
176+
CustomerCustomizer customerCustomizer =
177+
CustomerCustomizer.newBuilder()
178+
.setCustomizerAttribute(customizerAttributeResourceName)
179+
// Specify '100USD' as a text value. The ad customizer will dynamically replace the
180+
// placeholder with this value when the ad serves.
181+
.setValue(
182+
CustomizerValue.newBuilder()
183+
.setType(CustomizerAttributeType.PRICE)
184+
.setStringValue("100USD")
185+
.build())
186+
.build();
187+
188+
// Creates a customer customizer operation.
189+
CustomerCustomizerOperation operation =
190+
CustomerCustomizerOperation.newBuilder().setCreate(customerCustomizer).build();
191+
192+
try (CustomerCustomizerServiceClient customerCustomizerServiceClient =
193+
googleAdsClient.getLatestVersion().createCustomerCustomizerServiceClient()) {
194+
// Issues a mutate request to add the customer customizer and prints its information.
195+
MutateCustomerCustomizersResponse response =
196+
customerCustomizerServiceClient.mutateCustomerCustomizers(
197+
Long.toString(customerId), ImmutableList.of(operation));
198+
System.out.printf(
199+
"Added a customer customizer with resource name '%s'.%n",
200+
response.getResults(0).getResourceName());
201+
}
202+
}
203+
// [END add_responsive_search_ad_with_ad_customizer_2]
204+
205+
// [START add_responsive_search_ad_with_ad_customizer_3]
206+
/** Creates a responsive search ad that uses the specified customizer attribute. */
207+
private static void createResponsiveSearchAdWithCustomization(
208+
GoogleAdsClient googleAdsClient,
209+
long customerId,
210+
long adGroupId,
211+
String customizerAttributeName) {
212+
List<String> headlines =
213+
ImmutableList.of("Cruise to Mars", "Best Space Cruise Line", "Experience the Stars");
214+
List<AdTextAsset> headlineAssets =
215+
headlines.stream()
216+
.map(headline -> AdTextAsset.newBuilder().setText(headline).build())
217+
.collect(Collectors.toList());
218+
List<String> descriptions =
219+
ImmutableList.of(
220+
"Buy your tickets now",
221+
// Creates this particular description using the ad customizer.
222+
// Visit
223+
// https://developers.google.com/google-ads/api/docs/ads/customize-responsive-search-ads#ad_customizers_in_responsive_search_ads
224+
// for details about the placeholder format.
225+
// The ad customizer replaces the placeholder with the value we previously
226+
// created and linked to the customer using CustomerCustomizer.
227+
String.format("Just {CUSTOMIZER.%s:10USD}", customizerAttributeName));
228+
List<AdTextAsset> descriptionAssets =
229+
descriptions.stream()
230+
.map(description -> AdTextAsset.newBuilder().setText(description).build())
231+
.collect(Collectors.toList());
232+
233+
// Creates an ad and sets responsive search ad info.
234+
Ad ad =
235+
Ad.newBuilder()
236+
.setResponsiveSearchAd(
237+
ResponsiveSearchAdInfo.newBuilder()
238+
.addAllHeadlines(headlineAssets)
239+
.addAllDescriptions(descriptionAssets)
240+
.setPath1("all-inclusive")
241+
.setPath2("deals")
242+
.build())
243+
.addAllFinalUrls(ImmutableList.of("http://www.example.com"))
244+
.build();
245+
246+
// Creates an ad group ad to hold the above ad.
247+
AdGroupAd adGroupAd =
248+
AdGroupAd.newBuilder()
249+
.setAdGroup(ResourceNames.adGroup(customerId, adGroupId))
250+
.setStatus(AdGroupAdStatus.PAUSED)
251+
.setAd(ad)
252+
.build();
253+
254+
// Creates an ad group ad operation.
255+
AdGroupAdOperation operation = AdGroupAdOperation.newBuilder().setCreate(adGroupAd).build();
256+
257+
try (AdGroupAdServiceClient adGroupAdServiceClient =
258+
googleAdsClient.getLatestVersion().createAdGroupAdServiceClient()) {
259+
// Issues a mutate request to add the ad group ad and prints its information.
260+
MutateAdGroupAdsResponse response =
261+
adGroupAdServiceClient.mutateAdGroupAds(
262+
Long.toString(customerId), ImmutableList.of(operation));
263+
System.out.printf(
264+
"Created a responsive search ad with resource name '%s'.%n",
265+
response.getResults(0).getResourceName());
266+
}
267+
}
268+
// [END add_responsive_search_ad_with_ad_customizer_3]
269+
}

google-ads-examples/src/main/java/com/google/ads/googleads/examples/utils/ArgumentNames.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public final class ArgumentNames {
5050
public static final String CONVERSION_DATE_TIME = "--conversionDateTime";
5151
public static final String CONVERSION_RATE_MODIFIER = "--conversionRateModifier";
5252
public static final String CONVERSION_VALUE = "--conversionValue";
53+
public static final String CUSTOMIZER_ATTRIBUTE_NAME = "--customizerAttributeName";
5354
public static final String COUNTRY_CODE = "--countryCode";
5455
public static final String CPC_BID_CEILING_MICRO_AMOUNT = "--cpcBidCeilingMicroAmount";
5556
public static final String CPC_BID_MICRO_AMOUNT = "--cpcBidMicroAmount";

0 commit comments

Comments
 (0)