Skip to content

Commit 66311fb

Browse files
Add adopt AI max example (#888)
1 parent bc7c6cf commit 66311fb

1 file changed

Lines changed: 216 additions & 0 deletions

File tree

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
// Copyright 2026 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.experiments;
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.lib.utils.FieldMasks;
22+
import com.google.ads.googleads.v24.enums.AssetAutomationStatusEnum.AssetAutomationStatus;
23+
import com.google.ads.googleads.v24.enums.AssetAutomationTypeEnum.AssetAutomationType;
24+
import com.google.ads.googleads.v24.enums.ExperimentTypeEnum.ExperimentType;
25+
import com.google.ads.googleads.v24.errors.GoogleAdsError;
26+
import com.google.ads.googleads.v24.errors.GoogleAdsException;
27+
import com.google.ads.googleads.v24.resources.Campaign;
28+
import com.google.ads.googleads.v24.resources.Campaign.AiMaxSetting;
29+
import com.google.ads.googleads.v24.resources.Campaign.AssetAutomationSetting;
30+
import com.google.ads.googleads.v24.resources.Experiment;
31+
import com.google.ads.googleads.v24.resources.ExperimentArm;
32+
import com.google.ads.googleads.v24.services.CampaignOperation;
33+
import com.google.ads.googleads.v24.services.ExperimentArmOperation;
34+
import com.google.ads.googleads.v24.services.ExperimentOperation;
35+
import com.google.ads.googleads.v24.services.GoogleAdsServiceClient;
36+
import com.google.ads.googleads.v24.services.MutateGoogleAdsRequest;
37+
import com.google.ads.googleads.v24.services.MutateGoogleAdsResponse;
38+
import com.google.ads.googleads.v24.services.MutateOperation;
39+
import com.google.ads.googleads.v24.utils.ResourceNames;
40+
import com.google.common.collect.ImmutableList;
41+
import java.io.FileNotFoundException;
42+
import java.io.IOException;
43+
import java.util.List;
44+
import java.util.UUID;
45+
46+
/**
47+
* Creates an ADOPT_AI_MAX intra-campaign experiment for a Search campaign.
48+
*
49+
* <p>Intra-campaign experiments split traffic *within* the campaign, based on whether the feature
50+
* (in this case, AI Max) is enabled or not.
51+
*/
52+
public class CreateSearchAdoptAiMaxExperiment {
53+
54+
private static class CreateSearchAdoptAiMaxExperimentParams extends CodeSampleParams {
55+
56+
@Parameter(names = ArgumentNames.CUSTOMER_ID, required = true)
57+
private Long customerId;
58+
59+
@Parameter(names = ArgumentNames.CAMPAIGN_ID, required = true)
60+
private Long campaignId;
61+
}
62+
63+
public static void main(String[] args) {
64+
CreateSearchAdoptAiMaxExperimentParams params = new CreateSearchAdoptAiMaxExperimentParams();
65+
if (!params.parseArguments(args)) {
66+
throw new IllegalArgumentException("Invalid or missing command line arguments");
67+
}
68+
69+
GoogleAdsClient googleAdsClient = null;
70+
try {
71+
googleAdsClient = GoogleAdsClient.newBuilder().fromPropertiesFile().build();
72+
} catch (FileNotFoundException fnfe) {
73+
System.err.printf(
74+
"Failed to load GoogleAdsClient configuration from file. Exception: %s%n", fnfe);
75+
System.exit(1);
76+
} catch (IOException ioe) {
77+
System.err.printf("Failed to create GoogleAdsClient. Exception: %s%n", ioe);
78+
System.exit(1);
79+
}
80+
81+
try {
82+
new CreateSearchAdoptAiMaxExperiment()
83+
.runExample(googleAdsClient, params.customerId, params.campaignId);
84+
} catch (GoogleAdsException gae) {
85+
System.err.printf(
86+
"Request ID %s failed due to GoogleAdsException. Underlying errors:%n",
87+
gae.getRequestId());
88+
int i = 0;
89+
for (GoogleAdsError googleAdsError : gae.getGoogleAdsFailure().getErrorsList()) {
90+
System.err.printf(" Error %d: %s%n", i++, googleAdsError);
91+
}
92+
System.exit(1);
93+
}
94+
}
95+
96+
/**
97+
* Runs the example.
98+
*
99+
* @param googleAdsClient the googleAdsClient.
100+
* @param customerId the customer ID.
101+
* @param campaignId the ID of the campaign to run the experiment on.
102+
*/
103+
private void runExample(GoogleAdsClient googleAdsClient, long customerId, long campaignId) {
104+
// [START create_search_adopt_ai_max_experiment_1]
105+
// Create the experiment resource name using a temporary ID.
106+
String experimentResourceName = ResourceNames.experiment(customerId, -1L);
107+
108+
// Create the experiment.
109+
Experiment experiment =
110+
Experiment.newBuilder()
111+
.setResourceName(experimentResourceName)
112+
.setName("ADOPT_AI_MAX Experiment #" + UUID.randomUUID())
113+
.setType(ExperimentType.ADOPT_AI_MAX)
114+
.build();
115+
MutateOperation experimentOperation =
116+
MutateOperation.newBuilder()
117+
.setExperimentOperation(ExperimentOperation.newBuilder().setCreate(experiment).build())
118+
.build();
119+
120+
// Create the control arm. Both arms in an intra-campaign experiment reference the same base
121+
// campaign.
122+
ExperimentArm controlArm =
123+
ExperimentArm.newBuilder()
124+
.setExperiment(experimentResourceName)
125+
.setName("Control Arm")
126+
.setControl(true)
127+
.setTrafficSplit(50)
128+
.addCampaigns(ResourceNames.campaign(customerId, campaignId))
129+
.build();
130+
MutateOperation controlArmOperation =
131+
MutateOperation.newBuilder()
132+
.setExperimentArmOperation(
133+
ExperimentArmOperation.newBuilder().setCreate(controlArm).build())
134+
.build();
135+
136+
// Create the treatment arm.
137+
ExperimentArm treatmentArm =
138+
ExperimentArm.newBuilder()
139+
.setExperiment(experimentResourceName)
140+
.setName("Treatment Arm")
141+
.setControl(false)
142+
.setTrafficSplit(50)
143+
.addCampaigns(ResourceNames.campaign(customerId, campaignId))
144+
.build();
145+
MutateOperation treatmentArmOperation =
146+
MutateOperation.newBuilder()
147+
.setExperimentArmOperation(
148+
ExperimentArmOperation.newBuilder().setCreate(treatmentArm).build())
149+
.build();
150+
151+
// Create a campaign operation with an update mask to enable AI Max and configure asset
152+
// automation settings.
153+
// Note: For intra-campaign experiments, these settings are applied to the base campaign but are
154+
// only active for the treatment traffic split.
155+
Campaign campaign =
156+
Campaign.newBuilder()
157+
.setResourceName(ResourceNames.campaign(customerId, campaignId))
158+
.setAiMaxSetting(AiMaxSetting.newBuilder().setEnableAiMax(true).build())
159+
.addAssetAutomationSettings(
160+
AssetAutomationSetting.newBuilder()
161+
.setAssetAutomationType(AssetAutomationType.TEXT_ASSET_AUTOMATION)
162+
.setAssetAutomationStatus(AssetAutomationStatus.OPTED_IN)
163+
.build())
164+
.addAssetAutomationSettings(
165+
AssetAutomationSetting.newBuilder()
166+
.setAssetAutomationType(
167+
AssetAutomationType.FINAL_URL_EXPANSION_TEXT_ASSET_AUTOMATION)
168+
.setAssetAutomationStatus(AssetAutomationStatus.OPTED_IN)
169+
.build())
170+
.build();
171+
172+
CampaignOperation campaignOp =
173+
CampaignOperation.newBuilder()
174+
.setUpdate(campaign)
175+
.setUpdateMask(FieldMasks.allSetFieldsOf(campaign))
176+
.build();
177+
MutateOperation campaignMutateOperation =
178+
MutateOperation.newBuilder().setCampaignOperation(campaignOp).build();
179+
180+
// Send all mutate operations in a single Mutate request.
181+
List<MutateOperation> mutateOperations =
182+
ImmutableList.of(
183+
experimentOperation,
184+
controlArmOperation,
185+
treatmentArmOperation,
186+
campaignMutateOperation);
187+
188+
try (GoogleAdsServiceClient googleAdsServiceClient =
189+
googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) {
190+
191+
MutateGoogleAdsRequest request =
192+
MutateGoogleAdsRequest.newBuilder()
193+
.setCustomerId(Long.toString(customerId))
194+
.addAllMutateOperations(mutateOperations)
195+
.build();
196+
197+
MutateGoogleAdsResponse response = googleAdsServiceClient.mutate(request);
198+
// [END create_search_adopt_ai_max_experiment_1]
199+
200+
// Print the results.
201+
// The results will be returned in the same order as the mutate operations.
202+
System.out.printf(
203+
"Created experiment: %s%n",
204+
response.getMutateOperationResponses(0).getExperimentResult().getResourceName());
205+
System.out.printf(
206+
"Created control arm: %s%n",
207+
response.getMutateOperationResponses(1).getExperimentArmResult().getResourceName());
208+
System.out.printf(
209+
"Created treatment arm: %s%n",
210+
response.getMutateOperationResponses(2).getExperimentArmResult().getResourceName());
211+
System.out.printf(
212+
"Updated campaign to enable AI Max: %s%n",
213+
response.getMutateOperationResponses(3).getCampaignResult().getResourceName());
214+
}
215+
}
216+
}

0 commit comments

Comments
 (0)