// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.ads.googleads.migration.createcampaign; import static com.google.api.ads.common.lib.utils.Builder.DEFAULT_CONFIGURATION_FILENAME; import static java.nio.charset.StandardCharsets.UTF_8; import com.beust.jcommander.Parameter; import com.google.ads.googleads.migration.utils.ArgumentNames; import com.google.ads.googleads.migration.utils.CodeSampleParams; import com.google.api.ads.adwords.axis.factory.AdWordsServices; import com.google.api.ads.adwords.axis.v201809.cm.AdGroup; import com.google.api.ads.adwords.axis.v201809.cm.AdGroupAd; import com.google.api.ads.adwords.axis.v201809.cm.AdGroupAdOperation; import com.google.api.ads.adwords.axis.v201809.cm.AdGroupAdReturnValue; import com.google.api.ads.adwords.axis.v201809.cm.AdGroupAdRotationMode; import com.google.api.ads.adwords.axis.v201809.cm.AdGroupAdServiceInterface; import com.google.api.ads.adwords.axis.v201809.cm.AdGroupAdStatus; import com.google.api.ads.adwords.axis.v201809.cm.AdGroupCriterion; import com.google.api.ads.adwords.axis.v201809.cm.AdGroupCriterionOperation; import com.google.api.ads.adwords.axis.v201809.cm.AdGroupCriterionReturnValue; import com.google.api.ads.adwords.axis.v201809.cm.AdGroupCriterionServiceInterface; import com.google.api.ads.adwords.axis.v201809.cm.AdGroupOperation; import com.google.api.ads.adwords.axis.v201809.cm.AdGroupReturnValue; import com.google.api.ads.adwords.axis.v201809.cm.AdGroupServiceInterface; import com.google.api.ads.adwords.axis.v201809.cm.AdGroupStatus; import com.google.api.ads.adwords.axis.v201809.cm.AdRotationMode; import com.google.api.ads.adwords.axis.v201809.cm.AdvertisingChannelType; import com.google.api.ads.adwords.axis.v201809.cm.BiddableAdGroupCriterion; import com.google.api.ads.adwords.axis.v201809.cm.BiddingStrategyConfiguration; import com.google.api.ads.adwords.axis.v201809.cm.BiddingStrategyType; import com.google.api.ads.adwords.axis.v201809.cm.Bids; import com.google.api.ads.adwords.axis.v201809.cm.Budget; import com.google.api.ads.adwords.axis.v201809.cm.BudgetBudgetDeliveryMethod; import com.google.api.ads.adwords.axis.v201809.cm.BudgetOperation; import com.google.api.ads.adwords.axis.v201809.cm.BudgetReturnValue; import com.google.api.ads.adwords.axis.v201809.cm.BudgetServiceInterface; import com.google.api.ads.adwords.axis.v201809.cm.Campaign; import com.google.api.ads.adwords.axis.v201809.cm.CampaignOperation; import com.google.api.ads.adwords.axis.v201809.cm.CampaignReturnValue; import com.google.api.ads.adwords.axis.v201809.cm.CampaignServiceInterface; import com.google.api.ads.adwords.axis.v201809.cm.CampaignStatus; import com.google.api.ads.adwords.axis.v201809.cm.CpcBid; import com.google.api.ads.adwords.axis.v201809.cm.ExpandedTextAd; import com.google.api.ads.adwords.axis.v201809.cm.Keyword; import com.google.api.ads.adwords.axis.v201809.cm.KeywordMatchType; import com.google.api.ads.adwords.axis.v201809.cm.Money; import com.google.api.ads.adwords.axis.v201809.cm.NetworkSetting; import com.google.api.ads.adwords.axis.v201809.cm.Operator; import com.google.api.ads.adwords.axis.v201809.cm.UrlList; import com.google.api.ads.adwords.axis.v201809.cm.UserStatus; import com.google.api.ads.adwords.lib.client.AdWordsSession; import com.google.api.ads.adwords.lib.factory.AdWordsServicesInterface; import com.google.api.ads.common.lib.auth.OfflineCredentials; import com.google.api.ads.common.lib.auth.OfflineCredentials.Api; import com.google.api.ads.common.lib.conf.ConfigurationLoadException; import com.google.api.ads.common.lib.exception.OAuthException; import com.google.api.ads.common.lib.exception.ValidationException; import com.google.api.client.auth.oauth2.Credential; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.joda.time.DateTime; /** * This code example is the first in a series of code examples that shows how to create a Search * campaign using the AdWords API, and then migrate it to the Google Ads API one functionality at a * time. See other examples for code examples in various stages of migration. * * <p>This code example represents the initial state, where the AdWords API is used to create a * campaign budget, a Search campaign, ad groups, keywords and expanded text ads. The user has not * yet migrated any of the functionality to the Google Ads API. */ public class CreateCompleteCampaignAdWordsApiOnly { private static final int NUMBER_OF_ADS = 5; private static final List<String> KEYWORDS_TO_ADD = Arrays.asList("mars cruise", "space hotel"); private static class CreateCompleteCampaignAdWordsApiOnlyParams extends CodeSampleParams { @Parameter(names = ArgumentNames.CUSTOMER_ID, required = true) long customerId; } public static void main(String[] args) { CreateCompleteCampaignAdWordsApiOnlyParams params = new CreateCompleteCampaignAdWordsApiOnlyParams(); 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"); } AdWordsSession session; try { // Generates a refreshable OAuth2 credential for AdWords API. Credential oAuth2Credential = new OfflineCredentials.Builder() .forApi(Api.ADWORDS) .fromFile() .build() .generateCredential(); // Constructs an AdWordsSession. session = new AdWordsSession.Builder().fromFile().withOAuth2Credential(oAuth2Credential).build(); session.setClientCustomerId(Long.toString(params.customerId)); } catch (ConfigurationLoadException cle) { System.err.printf( "Failed to load configuration from the %s file. Exception: %s%n", DEFAULT_CONFIGURATION_FILENAME, cle); return; } catch (ValidationException ve) { System.err.printf( "Invalid configuration in the %s file. Exception: %s%n", DEFAULT_CONFIGURATION_FILENAME, ve); return; } catch (OAuthException oe) { System.err.printf( "Failed to create OAuth credentials. Check OAuth settings in the %s file. " + "Exception: %s%n", DEFAULT_CONFIGURATION_FILENAME, oe); return; } AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance(); try { new CreateCompleteCampaignAdWordsApiOnly().runExample(adWordsServices, session); } catch (RemoteException re) { System.err.printf("Request failed unexpectedly due to RemoteException: %s%n", re); } catch (UnsupportedEncodingException ue) { System.err.printf("Example failed due to encoding exception: %s%n", ue); } } /** * Runs the example. * * @param adWordsServices the Google AdWords services interface. * @param session the client session. * @throws RemoteException if the API request failed due to other errors. * @throws UnsupportedEncodingException if encoding the final URL failed. */ private void runExample(AdWordsServicesInterface adWordsServices, AdWordsSession session) throws RemoteException, UnsupportedEncodingException { Budget budget = createBudget(adWordsServices, session); Campaign campaign = createCampaign(adWordsServices, session, budget); AdGroup adGroup = createAdGroup(adWordsServices, session, campaign); createTextAds(adWordsServices, session, adGroup, NUMBER_OF_ADS); createKeywords(adWordsServices, session, adGroup, KEYWORDS_TO_ADD); } /** * Creates a budget. * * @param adWordsServices the Google AdWords services interface. * @param session the client session. * @throws RemoteException if the API request failed due to other errors. */ private Budget createBudget(AdWordsServicesInterface adWordsServices, AdWordsSession session) throws RemoteException { // Gets the BudgetService. BudgetServiceInterface budgetService = adWordsServices.get(session, BudgetServiceInterface.class); // Creates a budget, which can be shared by multiple campaigns. Budget sharedBudget = new Budget(); sharedBudget.setName("Interplanetary Cruise #" + System.currentTimeMillis()); Money budgetAmount = new Money(); budgetAmount.setMicroAmount(10_000_000L); sharedBudget.setAmount(budgetAmount); sharedBudget.setDeliveryMethod(BudgetBudgetDeliveryMethod.STANDARD); BudgetOperation budgetOperation = new BudgetOperation(); budgetOperation.setOperand(sharedBudget); budgetOperation.setOperator(Operator.ADD); BudgetOperation[] operations = new BudgetOperation[] {budgetOperation}; // Adds the budget. BudgetReturnValue result = budgetService.mutate(operations); Budget budgetResult = result.getValue(0); // Displays the budget. System.out.printf( "Budget with ID %d and name '%s' was created.%n", budgetResult.getBudgetId(), budgetResult.getName()); return budgetResult; } /** * Creates a campaign. * * @param adWordsServices the Google AdWords services interface. * @param session the client session. * @param budget the budget for the campaign. * @throws RemoteException if the API request failed due to other errors. */ private Campaign createCampaign( AdWordsServicesInterface adWordsServices, AdWordsSession session, Budget budget) throws RemoteException { // Gets the CampaignService. CampaignServiceInterface campaignService = adWordsServices.get(session, CampaignServiceInterface.class); // Creates the campaign. Campaign campaign = new Campaign(); campaign.setName("Interplanetary Cruise #" + System.currentTimeMillis()); // 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.setStatus(CampaignStatus.PAUSED); BiddingStrategyConfiguration biddingStrategyConfiguration = new BiddingStrategyConfiguration(); biddingStrategyConfiguration.setBiddingStrategyType(BiddingStrategyType.MANUAL_CPC); campaign.setBiddingStrategyConfiguration(biddingStrategyConfiguration); // You can optionally provide these field(s). campaign.setStartDate(new DateTime().plusDays(1).toString("yyyyMMdd")); campaign.setEndDate(new DateTime().plusDays(30).toString("yyyyMMdd")); // Only the budgetId should be sent, all other fields will be ignored by CampaignService. Budget newBudget = new Budget(); newBudget.setBudgetId(budget.getBudgetId()); campaign.setBudget(newBudget); campaign.setAdvertisingChannelType(AdvertisingChannelType.SEARCH); // Sets the campaign network options to Search and Search Network. NetworkSetting networkSetting = new NetworkSetting(); networkSetting.setTargetGoogleSearch(true); networkSetting.setTargetSearchNetwork(true); networkSetting.setTargetContentNetwork(false); networkSetting.setTargetPartnerSearchNetwork(false); campaign.setNetworkSetting(networkSetting); // Creates the operation. CampaignOperation operation = new CampaignOperation(); operation.setOperand(campaign); operation.setOperator(Operator.ADD); CampaignOperation[] operations = new CampaignOperation[] {operation}; // Adds the campaign. CampaignReturnValue result = campaignService.mutate(operations); Campaign campaignResult = result.getValue(0); // Displays the campaign. System.out.printf( "Campaign with ID %d and name '%s' was created.%n", campaignResult.getId(), campaignResult.getName()); return campaignResult; } /** * Creates an ad group. * * @param adWordsServices the Google AdWords services interface. * @param session the client session. * @param campaign the campaign for the ad group. * @throws RemoteException if the API request failed due to other errors. */ private AdGroup createAdGroup( AdWordsServicesInterface adWordsServices, AdWordsSession session, Campaign campaign) throws RemoteException { // Gets the AdGroupService. AdGroupServiceInterface adGroupService = adWordsServices.get(session, AdGroupServiceInterface.class); // Creates ad group. AdGroup adGroup = new AdGroup(); adGroup.setName("Earth to Mars Cruises #" + System.currentTimeMillis()); adGroup.setStatus(AdGroupStatus.ENABLED); adGroup.setCampaignId(campaign.getId()); // Sets the rotation mode. AdGroupAdRotationMode rotationMode = new AdGroupAdRotationMode(AdRotationMode.OPTIMIZE); adGroup.setAdGroupAdRotationMode(rotationMode); // Creates ad group bid. BiddingStrategyConfiguration biddingStrategyConfiguration = new BiddingStrategyConfiguration(); Money cpcBidMoney = new Money(); cpcBidMoney.setMicroAmount(500_000L); CpcBid bid = new CpcBid(); bid.setBid(cpcBidMoney); biddingStrategyConfiguration.setBids(new Bids[] {bid}); adGroup.setBiddingStrategyConfiguration(biddingStrategyConfiguration); // Creates the operation. AdGroupOperation operation = new AdGroupOperation(); operation.setOperand(adGroup); operation.setOperator(Operator.ADD); AdGroupOperation[] operations = new AdGroupOperation[] {operation}; // Adds the ad group. AdGroupReturnValue result = adGroupService.mutate(operations); AdGroup adGroupResult = result.getValue(0); // Displays the new ad group. System.out.printf( "Ad group with ID %d and name '%s' was created.%n", adGroupResult.getId(), adGroupResult.getName()); return adGroupResult; } /** * Creates text ads. * * @param adWordsServices the Google AdWords services interface. * @param session the client session. * @param adGroup the ad group for the text ad. * @throws RemoteException if the API request failed due to other errors. */ private AdGroupAd[] createTextAds( AdWordsServicesInterface adWordsServices, AdWordsSession session, AdGroup adGroup, int numberOfAds) throws RemoteException { // Gets the AdGroupAdService. AdGroupAdServiceInterface adGroupAdService = adWordsServices.get(session, AdGroupAdServiceInterface.class); List<AdGroupAdOperation> operations = new ArrayList<>(); for (int i = 0; i < numberOfAds; i++) { // Creates the expanded text ad. ExpandedTextAd expandedTextAd = new ExpandedTextAd(); expandedTextAd.setDescription("Buy your tickets now!"); expandedTextAd.setHeadlinePart1(String.format("Cruise #%d to Mars", i)); expandedTextAd.setHeadlinePart2("Best Space Cruise Line"); expandedTextAd.setFinalUrls(new String[] {"http://www.example.com/" + i}); // Creates the ad group ad. AdGroupAd expandedTextAdGroupAd = new AdGroupAd(); expandedTextAdGroupAd.setAdGroupId(adGroup.getId()); expandedTextAdGroupAd.setAd(expandedTextAd); // Optional: sets the status. expandedTextAdGroupAd.setStatus(AdGroupAdStatus.PAUSED); // Creates the operation. AdGroupAdOperation adGroupAdOperation = new AdGroupAdOperation(); adGroupAdOperation.setOperand(expandedTextAdGroupAd); adGroupAdOperation.setOperator(Operator.ADD); operations.add(adGroupAdOperation); } // Adds the ads. AdGroupAdReturnValue result = adGroupAdService.mutate(operations.toArray(new AdGroupAdOperation[0])); // Displays the ads. for (AdGroupAd adGroupAdResult : result.getValue()) { ExpandedTextAd newAd = (ExpandedTextAd) adGroupAdResult.getAd(); System.out.printf( "Expanded text ad with ID %d " + "and headline '%s - %s' was created in ad group with ID %d.%n", newAd.getId(), newAd.getHeadlinePart1(), newAd.getHeadlinePart2(), adGroup.getId()); } return result.getValue(); } /** * Creates keywords ad group criteria. * * @param adWordsServices the Google AdWords services interface. * @param session the client session. * @param adGroup the ad group for the new criteria. * @param keywordsToAdd the keywords to add to the text ads. * @throws RemoteException if the API request failed due to other errors. * @throws UnsupportedEncodingException if encoding the final URL failed. */ private AdGroupCriterion[] createKeywords( AdWordsServicesInterface adWordsServices, AdWordsSession session, AdGroup adGroup, List<String> keywordsToAdd) throws RemoteException, UnsupportedEncodingException { // Gets the AdGroupCriterionService. AdGroupCriterionServiceInterface adGroupCriterionService = adWordsServices.get(session, AdGroupCriterionServiceInterface.class); List<AdGroupCriterionOperation> operations = new ArrayList<>(); for (String keywordToAdd : keywordsToAdd) { // Creates the keyword. Keyword keyword = new Keyword(); keyword.setText(keywordToAdd); keyword.setMatchType(KeywordMatchType.EXACT); // Creates the biddable ad group criterion. BiddableAdGroupCriterion keywordBiddableAdGroupCriterion = new BiddableAdGroupCriterion(); keywordBiddableAdGroupCriterion.setAdGroupId(adGroup.getId()); keywordBiddableAdGroupCriterion.setCriterion(keyword); // You can optionally provide these field(s). keywordBiddableAdGroupCriterion.setUserStatus(UserStatus.PAUSED); String encodedFinalUrl = String.format( "http://example.com/mars/cruise/?kw=%s", URLEncoder.encode(keyword.getText(), UTF_8.name())); keywordBiddableAdGroupCriterion.setFinalUrls(new UrlList(new String[] {encodedFinalUrl})); // Creates the operation. AdGroupCriterionOperation keywordAdGroupCriterionOperation = new AdGroupCriterionOperation(); keywordAdGroupCriterionOperation.setOperand(keywordBiddableAdGroupCriterion); keywordAdGroupCriterionOperation.setOperator(Operator.ADD); operations.add(keywordAdGroupCriterionOperation); } // Adds the keywords. AdGroupCriterionReturnValue result = adGroupCriterionService.mutate(operations.toArray(new AdGroupCriterionOperation[0])); // Displays the results. for (AdGroupCriterion adGroupCriterionResult : result.getValue()) { System.out.printf( "Keyword ad group criterion with ad group ID %d, criterion ID %d, " + "text '%s', and match type '%s' was added.%n", adGroupCriterionResult.getAdGroupId(), adGroupCriterionResult.getCriterion().getId(), ((Keyword) adGroupCriterionResult.getCriterion()).getText(), ((Keyword) adGroupCriterionResult.getCriterion()).getMatchType()); } return result.getValue(); } }