// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.ads.googleads.examples.remarketing; 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.lib.utils.FieldMasks; import com.google.ads.googleads.v3.common.ExpressionRuleUserListInfo; import com.google.ads.googleads.v3.common.RuleBasedUserListInfo; import com.google.ads.googleads.v3.common.UserListInfo; import com.google.ads.googleads.v3.common.UserListRuleInfo; import com.google.ads.googleads.v3.common.UserListRuleItemGroupInfo; import com.google.ads.googleads.v3.common.UserListRuleItemInfo; import com.google.ads.googleads.v3.common.UserListStringRuleItemInfo; import com.google.ads.googleads.v3.enums.UserListMembershipStatusEnum.UserListMembershipStatus; import com.google.ads.googleads.v3.enums.UserListPrepopulationStatusEnum.UserListPrepopulationStatus; import com.google.ads.googleads.v3.enums.UserListStringRuleItemOperatorEnum.UserListStringRuleItemOperator; import com.google.ads.googleads.v3.errors.GoogleAdsError; import com.google.ads.googleads.v3.errors.GoogleAdsException; import com.google.ads.googleads.v3.resources.AdGroupCriterion; import com.google.ads.googleads.v3.resources.CampaignCriterion; import com.google.ads.googleads.v3.resources.UserList; import com.google.ads.googleads.v3.services.AdGroupCriterionOperation; import com.google.ads.googleads.v3.services.AdGroupCriterionServiceClient; import com.google.ads.googleads.v3.services.CampaignCriterionOperation; import com.google.ads.googleads.v3.services.CampaignCriterionServiceClient; import com.google.ads.googleads.v3.services.GoogleAdsRow; import com.google.ads.googleads.v3.services.GoogleAdsServiceClient; import com.google.ads.googleads.v3.services.GoogleAdsServiceClient.SearchPagedResponse; import com.google.ads.googleads.v3.services.MutateAdGroupCriteriaResponse; import com.google.ads.googleads.v3.services.MutateAdGroupCriterionResult; import com.google.ads.googleads.v3.services.MutateCampaignCriteriaResponse; import com.google.ads.googleads.v3.services.MutateUserListsResponse; import com.google.ads.googleads.v3.services.SearchGoogleAdsRequest; import com.google.ads.googleads.v3.services.UserListOperation; import com.google.ads.googleads.v3.services.UserListServiceClient; import com.google.ads.googleads.v3.utils.ResourceNames; import com.google.common.collect.ImmutableList; import com.google.protobuf.DoubleValue; import com.google.protobuf.FloatValue; import com.google.protobuf.Int64Value; import com.google.protobuf.StringValue; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * Demonstrates various operations involved in remarketing, including (a) creating a user list based * on visitors to a website, (b) targeting a user list with an ad group criterion, (c) updating the * bid modifier on an ad group criterion, (d) finding and removing all ad group criteria under a * given campaign, (e) targeting a user list with a campaign criterion, and (f) updating the bid * modifier on a campaign criterion. It is unlikely that users will need to perform all of these * operations consecutively, and all of the operations contained herein are meant of for * illustrative purposes. */ public class SetupRemarketing { private static final int PAGE_SIZE = 1000; private static class SetupRemarketingParams extends CodeSampleParams { @Parameter(names = ArgumentNames.CUSTOMER_ID, required = true) private Long customerId; @Parameter(names = ArgumentNames.AD_GROUP_ID, required = true) private Long adGroupId; @Parameter(names = ArgumentNames.CAMPAIGN_ID, required = true) private Long campaignId; /** Specify the bid modifier value here or the default specified below will be used. */ @Parameter(names = ArgumentNames.BID_MODIFIER) private Double bidModifier = 1.5; } public static void main(String[] args) { SetupRemarketingParams params = new SetupRemarketingParams(); if (!params.parseArguments(args)) { // Either pass the required parameters for this example on the command line, or insert them // into the code here. See the parameter class definition above for descriptions. params.customerId = Long.parseLong("INSERT_CUSTOMER_ID_HERE"); params.adGroupId = Long.parseLong("INSERT_AD_GROUP_ID_HERE"); params.campaignId = Long.parseLong("INSERT_CAMPAIGN_ID_HERE"); // Optional: To use a different bid modifier value from the default (1.5), uncomment // the line below and insert the desired bid modifier value. // params.bidModifier = Double.parseDouble("INSERT_BID_MODIFIER_VALUE_HERE"); } GoogleAdsClient googleAdsClient; try { googleAdsClient = GoogleAdsClient.newBuilder().fromPropertiesFile().build(); } catch (FileNotFoundException fnfe) { System.err.printf( "Failed to load GoogleAdsClient configuration from file. Exception: %s%n", fnfe); return; } catch (IOException ioe) { System.err.printf("Failed to create GoogleAdsClient. Exception: %s%n", ioe); return; } try { new SetupRemarketing() .runExample( googleAdsClient, params.customerId, params.adGroupId, params.campaignId, params.bidModifier); } catch (GoogleAdsException gae) { // GoogleAdsException is the base class for most exceptions thrown by an API request. // Instances of this exception have a message and a GoogleAdsFailure that contains a // collection of GoogleAdsErrors that indicate the underlying causes of the // GoogleAdsException. System.err.printf( "Request ID %s failed due to GoogleAdsException. Underlying errors:%n", gae.getRequestId()); int i = 0; for (GoogleAdsError googleAdsError : gae.getGoogleAdsFailure().getErrorsList()) { System.err.printf(" Error %d: %s%n", i++, googleAdsError); } } } /** * Runs the example. * * @param googleAdsClient the Google Ads API client. * @param customerId the client customer ID. * @param adGroupId the adGroup on which to do the remarketing. * @throws GoogleAdsException if an API request failed with one or more service errors. */ private void runExample( GoogleAdsClient googleAdsClient, long customerId, long adGroupId, long campaignId, double bidModifier) { String userList = createUserList(googleAdsClient, customerId); String adGroupCriterionResourceName = targetAdsInAdGroupToUserList(googleAdsClient, customerId, adGroupId, userList); modifyAdGroupBids(googleAdsClient, customerId, adGroupCriterionResourceName, bidModifier); removeExistingListCriteriaFromAdGroup(googleAdsClient, customerId, campaignId); String campaignCriterionResourceName = targetAdsInCampaignToUserList(googleAdsClient, customerId, campaignId, userList); modifyCampaignBids(googleAdsClient, customerId, campaignCriterionResourceName, bidModifier); } /** * Creates a user list targeting users that have visited a given url. * * @param googleAdsClient the Google Ads API client. * @param customerId the client customer ID. * @return the user list resource name. */ private String createUserList(GoogleAdsClient googleAdsClient, long customerId) { // Creates a rule targeting any user that visited a url containing 'example.com'. UserListRuleItemInfo rule = UserListRuleItemInfo.newBuilder() // Uses a built-in parameter to create a domain URL rule. .setName(StringValue.of("url__")) .setStringRuleItem( UserListStringRuleItemInfo.newBuilder() .setOperator(UserListStringRuleItemOperator.CONTAINS) .setValue(StringValue.of("example.com")) .build()) .build(); // Specifies that the user list targets visitors of a page based on the provided rule. ExpressionRuleUserListInfo expressionRuleUserListInfo = ExpressionRuleUserListInfo.newBuilder() .setRule( UserListRuleInfo.newBuilder() .addRuleItemGroups( UserListRuleItemGroupInfo.newBuilder().addRuleItems(rule).build()) .build()) .build(); // Defines a representation of a user list that is generated by a rule. RuleBasedUserListInfo ruleBasedUserListInfo = RuleBasedUserListInfo.newBuilder() // Optional: To include past users in the user list, set the prepopulation_status to // REQUESTED. .setPrepopulationStatus(UserListPrepopulationStatus.REQUESTED) .setExpressionRuleUserList(expressionRuleUserListInfo) .build(); // Creates the user list. UserList userList = UserList.newBuilder() .setName(StringValue.of("All visitors to example.com" + System.currentTimeMillis())) .setDescription(StringValue.of("Any visitor to any page of example.com")) .setMembershipStatus(UserListMembershipStatus.OPEN) .setMembershipLifeSpan(Int64Value.of(365)) .setRuleBasedUserList(ruleBasedUserListInfo) .build(); // Creates the operation. UserListOperation operation = UserListOperation.newBuilder().setCreate(userList).build(); // Creates the user list service client. try (UserListServiceClient userListServiceClient = googleAdsClient.getLatestVersion().createUserListServiceClient()) { // Adds the user list. MutateUserListsResponse response = userListServiceClient.mutateUserLists( Long.toString(customerId), ImmutableList.of(operation)); String userListResourceName = response.getResults(0).getResourceName(); // Prints the result. System.out.printf("Created user list with resource name '%s'.%n", userListResourceName); return userListResourceName; } } /** * Creates an ad group criterion that targets a user list with an ad group. * * @param googleAdsClient the Google Ads API client. * @param customerId the client customer ID. * @param adGroupId the ad group on which the user list will be targeted. * @param userList the resource name of the user list to be targeted. * @return the ad group criterion resource name. */ private String targetAdsInAdGroupToUserList( GoogleAdsClient googleAdsClient, long customerId, long adGroupId, String userList) { // Creates the ad group criterion targeting members of the user list. AdGroupCriterion adGroupCriterion = AdGroupCriterion.newBuilder() .setAdGroup(StringValue.of(ResourceNames.adGroup(customerId, adGroupId))) .setUserList(UserListInfo.newBuilder().setUserList(StringValue.of(userList)).build()) .build(); // Creates the operation. AdGroupCriterionOperation operation = AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterion).build(); // Creates the ad group criterion service. try (AdGroupCriterionServiceClient adGroupCriterionServiceClient = googleAdsClient.getLatestVersion().createAdGroupCriterionServiceClient()) { // Adds the ad group criterion. MutateAdGroupCriteriaResponse response = adGroupCriterionServiceClient.mutateAdGroupCriteria( Long.toString(customerId), ImmutableList.of(operation)); // Gets and prints the results. String adGroupCriterionResourceName = response.getResults(0).getResourceName(); System.out.printf( "Successfully created ad group criterion with resource name '%s' " + "targeting user list with resource name '%s' with ad group with ID %d.%n", adGroupCriterionResourceName, userList, adGroupId); return adGroupCriterionResourceName; } } /** * Updates the bid modifier on an ad group criterion. * * @param googleAdsClient the Google Ads API client. * @param customerId the client customer ID. * @param adGroupCriterionResourceName the ad group criterion to update. * @param bidModifier the bid modifier. */ private void modifyAdGroupBids( GoogleAdsClient googleAdsClient, long customerId, String adGroupCriterionResourceName, double bidModifier) { // Creates the ad group criterion with a bid modifier. You may alternatively set the bid for // the ad group criterion directly. AdGroupCriterion adGroupCriterion = AdGroupCriterion.newBuilder() .setResourceName(adGroupCriterionResourceName) .setBidModifier(DoubleValue.of(bidModifier)) .build(); // Creates the update operation. AdGroupCriterionOperation operation = AdGroupCriterionOperation.newBuilder() .setUpdate(adGroupCriterion) .setUpdateMask(FieldMasks.allSetFieldsOf(adGroupCriterion)) .build(); // Creates the ad group criterion service. try (AdGroupCriterionServiceClient adGroupCriterionServiceClient = googleAdsClient.getLatestVersion().createAdGroupCriterionServiceClient()) { // Updates the ad group criterion. MutateAdGroupCriteriaResponse response = adGroupCriterionServiceClient.mutateAdGroupCriteria( Long.toString(customerId), ImmutableList.of(operation)); // Prints the results. System.out.printf( "Successfully updated the bid for ad group criterion with resource name '%s'.%n", response.getResults(0).getResourceName()); } } /** * Removes all ad group criteria targeting a user list under a given campaign. This is a necessary * step before targeting a user list at the campaign level. * * @param googleAdsClient the Google Ads API client. * @param customerId the client customer ID. * @param campaignId the campaign under which to remove the ad group criteria. */ private void removeExistingListCriteriaFromAdGroup( GoogleAdsClient googleAdsClient, long customerId, long campaignId) { // Retrieves all of the ad group criteria under a campaign. List<String> adGroupCriteria = getUserListAdGroupCriterion(googleAdsClient, customerId, campaignId); List<AdGroupCriterionOperation> operations = new ArrayList<>(); // Creates a list of remove operations. for (String adGroupCriterion : adGroupCriteria) { operations.add(AdGroupCriterionOperation.newBuilder().setRemove(adGroupCriterion).build()); } // Creates the ad group criterion service. try (AdGroupCriterionServiceClient adGroupCriterionServiceClient = googleAdsClient.getLatestVersion().createAdGroupCriterionServiceClient()) { // Removes the ad group criterion. MutateAdGroupCriteriaResponse response = adGroupCriterionServiceClient.mutateAdGroupCriteria( Long.toString(customerId), operations); // Gets and prints the results. System.out.printf("Removed %d ad group criteria.%n", response.getResultsCount()); for (MutateAdGroupCriterionResult result : response.getResultsList()) { System.out.printf( "Successfully removed ad group criterion with resource name '%s'.%n", result.getResourceName()); } } } /** * Finds all of user list ad group criteria under a campaign. * * @param googleAdsClient the Google Ads API client. * @param customerId the client customer ID. * @param campaignId the campaign under which to search the ad group criteria. * @return a list of the ad group criteria resource names. */ private List<String> getUserListAdGroupCriterion( GoogleAdsClient googleAdsClient, long customerId, long campaignId) { List<String> userListCriteria = new ArrayList<>(); // Creates the Google Ads service client. try (GoogleAdsServiceClient googleAdsServiceClient = googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) { // Creates a request that will retrieve all of the ad group criteria under a campaign. SearchGoogleAdsRequest request = SearchGoogleAdsRequest.newBuilder() .setCustomerId(Long.toString(customerId)) .setPageSize(PAGE_SIZE) .setQuery( "SELECT ad_group_criterion.criterion_id" + " FROM ad_group_criterion" + " WHERE campaign.id = " + campaignId + " AND ad_group_criterion.type = 'USER_LIST'") .build(); // Issues the search request. SearchPagedResponse searchPagedResponse = googleAdsServiceClient.search(request); // Iterates over all rows in all pages. Prints the results and adds the ad group criteria // resource names to the list. for (GoogleAdsRow googleAdsRow : searchPagedResponse.iterateAll()) { String adGroupCriterionResourceName = googleAdsRow.getAdGroupCriterion().getResourceName(); System.out.printf( "Ad group criterion with resource name '%s' was found.%n", adGroupCriterionResourceName); userListCriteria.add(adGroupCriterionResourceName); } } return userListCriteria; } /** * Creates a campaign criterion that targets a user list with a campaign. * * @param googleAdsClient the Google Ads API client. * @param customerId the client customer ID. * @param campaignId the campaign on which the user list will be targeted. * @param userList the resource name of the user list to be targeted. * @return the campaign criterion resource name. */ private String targetAdsInCampaignToUserList( GoogleAdsClient googleAdsClient, long customerId, long campaignId, String userList) { // Creates the campaign criterion. CampaignCriterion campaignCriterion = CampaignCriterion.newBuilder() .setCampaign(StringValue.of(ResourceNames.campaign(customerId, campaignId))) .setUserList(UserListInfo.newBuilder().setUserList(StringValue.of(userList)).build()) .build(); // Creates the operation. CampaignCriterionOperation operation = CampaignCriterionOperation.newBuilder().setCreate(campaignCriterion).build(); // Creates the campaign criterion service client. try (CampaignCriterionServiceClient campaignCriterionServiceClient = googleAdsClient.getLatestVersion().createCampaignCriterionServiceClient()) { // Adds the campaign criterion. MutateCampaignCriteriaResponse response = campaignCriterionServiceClient.mutateCampaignCriteria( Long.toString(customerId), ImmutableList.of(operation)); // Gets and prints the campaign criterion resource name. String campaignCriterionResourceName = response.getResults(0).getResourceName(); System.out.printf( "Successfully created campaign criterion with resource name '%s' " + "targeting user list with resource name '%s' with campaign with ID %d.%n", campaignCriterionResourceName, userList, campaignId); return campaignCriterionResourceName; } } /** * Updates the bid modifier on a campaign criterion. * * @param googleAdsClient the Google Ads API client. * @param customerId the client customer ID. * @param campaignCriterionResourceName the campaign criterion to update. * @param bidModifier the bid modifier. */ private void modifyCampaignBids( GoogleAdsClient googleAdsClient, long customerId, String campaignCriterionResourceName, double bidModifier) { // Creates the campaign criterion to update. CampaignCriterion campaignCriterion = CampaignCriterion.newBuilder() .setResourceName(campaignCriterionResourceName) .setBidModifier(FloatValue.of((float) bidModifier)) .build(); // Creates the update operation. CampaignCriterionOperation operation = CampaignCriterionOperation.newBuilder() .setUpdate(campaignCriterion) .setUpdateMask(FieldMasks.allSetFieldsOf(campaignCriterion)) .build(); // Creates the campaign criterion service client. try (CampaignCriterionServiceClient campaignCriterionServiceClient = googleAdsClient.getLatestVersion().createCampaignCriterionServiceClient()) { // Updates the campaign criterion. MutateCampaignCriteriaResponse response = campaignCriterionServiceClient.mutateCampaignCriteria( Long.toString(customerId), ImmutableList.of(operation)); System.out.printf( "Successfully updated the bid for campaign criterion with resource name '%s'.%n", response.getResults(0).getResourceName()); } } }