Advanced Operations Samples

The code samples below provide examples of common advanced operations using the AdWords API. Client Library.

Add an ad customizer

// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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.

package adwords.axis.v201710.advancedoperations;

import com.beust.jcommander.Parameter;
import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.v201710.cm.AdCustomizerFeed;
import com.google.api.ads.adwords.axis.v201710.cm.AdCustomizerFeedAttribute;
import com.google.api.ads.adwords.axis.v201710.cm.AdCustomizerFeedAttributeType;
import com.google.api.ads.adwords.axis.v201710.cm.AdCustomizerFeedOperation;
import com.google.api.ads.adwords.axis.v201710.cm.AdCustomizerFeedServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAd;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdOperation;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdReturnValue;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.ExpandedTextAd;
import com.google.api.ads.adwords.axis.v201710.cm.FeedItem;
import com.google.api.ads.adwords.axis.v201710.cm.FeedItemAdGroupTargeting;
import com.google.api.ads.adwords.axis.v201710.cm.FeedItemAttributeValue;
import com.google.api.ads.adwords.axis.v201710.cm.FeedItemOperation;
import com.google.api.ads.adwords.axis.v201710.cm.FeedItemReturnValue;
import com.google.api.ads.adwords.axis.v201710.cm.FeedItemServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.Operator;
import com.google.api.ads.adwords.lib.client.AdWordsSession;
import com.google.api.ads.adwords.lib.factory.AdWordsServicesInterface;
import com.google.api.ads.adwords.lib.utils.examples.ArgumentNames;
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.utils.examples.CodeSampleParams;
import com.google.api.client.auth.oauth2.Credential;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.joda.time.DateTime;

/**
 * This example adds an ad customizer feed and associates it with the customer. Then it adds an ad
 * that uses the feed to populate dynamic data.
 *
 * <p>Credentials and properties in {@code fromFile()} are pulled from the
 * "ads.properties" file. See README for more info.
 */
public class AddAdCustomizer {

  private static class AddAdCustomizerParams extends CodeSampleParams {
    @Parameter(names = ArgumentNames.AD_GROUP_ID, required = true)
    private List<Long> adGroupIds = new ArrayList<>();

    @Parameter(names = ArgumentNames.FEED_NAME, required = true)
    private String feedName;
  }

  public static void main(String[] args) throws Exception {
    // Generate a refreshable OAuth2 credential.
    Credential oAuth2Credential = new OfflineCredentials.Builder()
        .forApi(Api.ADWORDS)
        .fromFile()
        .build()
        .generateCredential();

    // Construct an AdWordsSession.
    AdWordsSession session = new AdWordsSession.Builder()
        .fromFile()
        .withOAuth2Credential(oAuth2Credential)
        .build();

    AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance();

    AddAdCustomizerParams params = new AddAdCustomizerParams();
    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.adGroupIds = Arrays.asList(
          Long.valueOf("INSERT_AD_GROUP_ID_HERE"),
          Long.valueOf("INSERT_AD_GROUP_ID_HERE"));
      params.feedName = "INSERT_FEED_NAME_HERE";
    }

    runExample(adWordsServices, session, params.adGroupIds, params.feedName);
  }

  public static void runExample(AdWordsServicesInterface adWordsServices, AdWordsSession session,
      List<Long> adGroupIds, String feedName) throws Exception {
    // Create a customizer feed. One feed per account can be used for all ads.
    AdCustomizerFeed adCustomizerFeed = createCustomizerFeed(adWordsServices, session, feedName);

    // Add feed items containing the values we'd like to place in ads.
    createCustomizerFeedItems(adWordsServices, session, adGroupIds, adCustomizerFeed);

    // All set! We can now create ads with customizations.
    createAdsWithCustomizations(adWordsServices, session, adGroupIds, feedName);
  }

  /**
   * Creates a new AdCustomizerFeed.
   *
   * @param feedName the name of the new AdCustomizerFeed
   * @return The new AdCustomizerFeed
   */
  private static AdCustomizerFeed createCustomizerFeed(AdWordsServicesInterface adWordsServices,
      AdWordsSession session, String feedName) throws Exception {
    // Get the AdCustomizerFeedService.
    AdCustomizerFeedServiceInterface adCustomizerFeedService =
        adWordsServices.get(session, AdCustomizerFeedServiceInterface.class);
    AdCustomizerFeed customizerFeed = new AdCustomizerFeed();
    customizerFeed.setFeedName(feedName);

    AdCustomizerFeedAttribute nameAttribute = new AdCustomizerFeedAttribute();
    nameAttribute.setName("Name");
    nameAttribute.setType(AdCustomizerFeedAttributeType.STRING);

    AdCustomizerFeedAttribute priceAttribute = new AdCustomizerFeedAttribute();
    priceAttribute.setName("Price");
    priceAttribute.setType(AdCustomizerFeedAttributeType.STRING);

    AdCustomizerFeedAttribute dateAttribute = new AdCustomizerFeedAttribute();
    dateAttribute.setName("Date");
    dateAttribute.setType(AdCustomizerFeedAttributeType.DATE_TIME);

    customizerFeed.setFeedAttributes(
        new AdCustomizerFeedAttribute[] {nameAttribute, priceAttribute, dateAttribute});

    AdCustomizerFeedOperation feedOperation = new AdCustomizerFeedOperation();
    feedOperation.setOperand(customizerFeed);
    feedOperation.setOperator(Operator.ADD);

    AdCustomizerFeed addedFeed = adCustomizerFeedService.mutate(
        new AdCustomizerFeedOperation[] {feedOperation}).getValue()[0];

    System.out.printf(
        "Created ad customizer feed with ID %d, name '%s' and attributes:%n",
        addedFeed.getFeedId(), addedFeed.getFeedName());
    for (AdCustomizerFeedAttribute feedAttribute : addedFeed.getFeedAttributes()) {
      System.out.printf(
          "  ID: %d, name: '%s', type: %s%n",
          feedAttribute.getId(), feedAttribute.getName(), feedAttribute.getType());
    }
    return addedFeed;
  }

  /**
   * Creates FeedItems with the values to use in ad customizations for each ad group in
   * <code>adGroupIds</code>.
   */
  private static void createCustomizerFeedItems(AdWordsServicesInterface adWordsServices,
      AdWordsSession session, List<Long> adGroupIds, AdCustomizerFeed adCustomizerFeed)
      throws Exception {
    // Get the FeedItemService.
    FeedItemServiceInterface feedItemService =
        adWordsServices.get(session, FeedItemServiceInterface.class);

    List<FeedItemOperation> feedItemOperations = new ArrayList<>();

    DateTime now = new DateTime();

    DateTime marsDate = new DateTime(now.getYear(), now.getMonthOfYear(), 1, 0, 0);
    feedItemOperations.add(createFeedItemAddOperation("Mars", "$1234.56",
        marsDate.toString("yyyyMMdd HHmmss"), adGroupIds.get(0), adCustomizerFeed));

    DateTime venusDate = new DateTime(now.getYear(), now.getMonthOfYear(), 15, 0, 0);
    feedItemOperations.add(createFeedItemAddOperation("Venus", "$1450.00",
        venusDate.toString("yyyyMMdd HHmmss"), adGroupIds.get(1), adCustomizerFeed));

    FeedItemReturnValue feedItemReturnValue = feedItemService.mutate(
        feedItemOperations.toArray(new FeedItemOperation[feedItemOperations.size()]));

    for (FeedItem addedFeedItem : feedItemReturnValue.getValue()) {
      System.out.printf("Added feed item with ID %d.%n", addedFeedItem.getFeedItemId());
    }
  }

  /**
   * Creates a FeedItemOperation that will create a FeedItem with the specified values and ad group
   * target when sent to FeedItemService.mutate.
   *
   * @param name the value for the name attribute of the FeedItem
   * @param price the value for the price attribute of the FeedItem
   * @param date the value for the date attribute of the FeedItem
   * @param adGroupId the ID of the ad group to target with the FeedItem
   * @param adCustomizerFeed the customizer feed
   * @return a new FeedItemOperation for adding a FeedItem
   */
  private static FeedItemOperation createFeedItemAddOperation(String name, String price,
      String date, Long adGroupId, AdCustomizerFeed adCustomizerFeed) {
    FeedItem feedItem = new FeedItem();
    feedItem.setFeedId(adCustomizerFeed.getFeedId());

    List<FeedItemAttributeValue> attributeValues = new ArrayList<>();

    // FeedAttributes appear in the same order as they were created - Name, Price, Date.
    // See the createCustomizerFeed method for details.
    FeedItemAttributeValue nameAttributeValue = new FeedItemAttributeValue();
    nameAttributeValue.setFeedAttributeId(adCustomizerFeed.getFeedAttributes(0).getId());
    nameAttributeValue.setStringValue(name);
    attributeValues.add(nameAttributeValue);

    FeedItemAttributeValue priceAttributeValue = new FeedItemAttributeValue();
    priceAttributeValue.setFeedAttributeId(adCustomizerFeed.getFeedAttributes(1).getId());
    priceAttributeValue.setStringValue(price);
    attributeValues.add(priceAttributeValue);

    FeedItemAttributeValue dateAttributeValue = new FeedItemAttributeValue();
    dateAttributeValue.setFeedAttributeId(adCustomizerFeed.getFeedAttributes(2).getId());
    dateAttributeValue.setStringValue(date);
    attributeValues.add(dateAttributeValue);

    feedItem.setAttributeValues(
        attributeValues.toArray(new FeedItemAttributeValue[attributeValues.size()]));

    feedItem.setAdGroupTargeting(new FeedItemAdGroupTargeting(adGroupId));

    FeedItemOperation feedItemOperation = new FeedItemOperation();
    feedItemOperation.setOperand(feedItem);
    feedItemOperation.setOperator(Operator.ADD);

    return feedItemOperation;
  }

  /**
   * Creates expanded text ads that use ad customizations for the specified ad group IDs.
   */
  private static void createAdsWithCustomizations(AdWordsServicesInterface adWordsServices,
      AdWordsSession session, List<Long> adGroupIds, String feedName) throws Exception {
    // Get the AdGroupAdService.
    AdGroupAdServiceInterface adGroupAdService =
        adWordsServices.get(session, AdGroupAdServiceInterface.class);

    ExpandedTextAd textAd = new ExpandedTextAd();
    textAd.setHeadlinePart1(String.format("Luxury Cruise to {=%s.Name}", feedName));
    textAd.setHeadlinePart2(String.format("Only {=%s.Price}", feedName));
    textAd.setDescription(String.format("Offer ends in {=countdown(%s.Date)}!", feedName));
    textAd.setFinalUrls(new String[] {"http://www.example.com"});

    // We add the same ad to both ad groups. When they serve, they will show different values, since
    // they match different feed items.
    List<AdGroupAdOperation> adGroupAdOperations = new ArrayList<>();
    for (Long adGroupId : adGroupIds) {
      AdGroupAd adGroupAd = new AdGroupAd();
      adGroupAd.setAdGroupId(adGroupId);
      adGroupAd.setAd(textAd);

      AdGroupAdOperation adGroupAdOperation = new AdGroupAdOperation();
      adGroupAdOperation.setOperand(adGroupAd);
      adGroupAdOperation.setOperator(Operator.ADD);

      adGroupAdOperations.add(adGroupAdOperation);
    }

    AdGroupAdReturnValue adGroupAdReturnValue = adGroupAdService.mutate(
        adGroupAdOperations.toArray(new AdGroupAdOperation[adGroupAdOperations.size()]));

    for (AdGroupAd addedAd : adGroupAdReturnValue.getValue()) {
      System.out.printf("Created an ad with ID %d, type '%s' and status '%s'.%n",
          addedAd.getAd().getId(), addedAd.getAd().getAdType(), addedAd.getStatus());
    }
  }
}

Add an ad group bid modifier

// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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.

package adwords.axis.v201710.advancedoperations;

import com.beust.jcommander.Parameter;
import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupBidModifier;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupBidModifierOperation;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupBidModifierReturnValue;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupBidModifierServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.Operator;
import com.google.api.ads.adwords.axis.v201710.cm.Platform;
import com.google.api.ads.adwords.lib.client.AdWordsSession;
import com.google.api.ads.adwords.lib.factory.AdWordsServicesInterface;
import com.google.api.ads.adwords.lib.utils.examples.ArgumentNames;
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.utils.examples.CodeSampleParams;
import com.google.api.client.auth.oauth2.Credential;

/**
 * This example illustrates how to add ad group level mobile bid modifier override for a campaign.
 *
 * <p>Credentials and properties in {@code fromFile()} are pulled from the
 * "ads.properties" file. See README for more info.
 */
public class AddAdGroupBidModifier {

  private static final double BID_MODIFIER = 1.5;

  private static class AddAdGroupBidModifierParams extends CodeSampleParams {
    @Parameter(names = ArgumentNames.AD_GROUP_ID, required = true)
    private Long adGroupId;
  }

  public static void main(String[] args) throws Exception {
    // Generate a refreshable OAuth2 credential.
    Credential oAuth2Credential = new OfflineCredentials.Builder()
        .forApi(Api.ADWORDS)
        .fromFile()
        .build()
        .generateCredential();

    // Construct an AdWordsSession.
    AdWordsSession session = new AdWordsSession.Builder()
        .fromFile()
        .withOAuth2Credential(oAuth2Credential)
        .build();

    AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance();

    AddAdGroupBidModifierParams params = new AddAdGroupBidModifierParams();
    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.adGroupId = Long.parseLong("INSERT_AD_GROUP_ID_HERE");
    }

    runExample(adWordsServices, session, params.adGroupId);
  }

  public static void runExample(AdWordsServicesInterface adWordsServices, AdWordsSession session,
      Long adGroupId) throws Exception {
    // Get the AdGroupBidModifierService.
    AdGroupBidModifierServiceInterface adGroupBidModifierService =
        adWordsServices.get(session, AdGroupBidModifierServiceInterface.class);

    // Create mobile platform. The ID can be found in the documentation.
    // https://developers.google.com/adwords/api/docs/appendix/platforms
    Platform mobile = new Platform();
    mobile.setId(30001L);

    AdGroupBidModifier adGroupBidModifier = new AdGroupBidModifier();
    adGroupBidModifier.setAdGroupId(adGroupId);
    adGroupBidModifier.setBidModifier(BID_MODIFIER);
    adGroupBidModifier.setCriterion(mobile);

    // Create ADD operation.
    AdGroupBidModifierOperation operation = new AdGroupBidModifierOperation();
    operation.setOperand(adGroupBidModifier);
    // Use 'ADD' to add a new modifier and 'SET' to update an existing one. A
    // modifier can be removed with the 'REMOVE' operator.
    operation.setOperator(Operator.ADD);

    // Update ad group bid modifier.
    AdGroupBidModifierReturnValue result =
        adGroupBidModifierService.mutate(new AdGroupBidModifierOperation[] {operation});
    for (AdGroupBidModifier bidModifierResult : result.getValue()) {
      System.out.printf(
          "Campaign ID %d, ad group ID %d was updated with ad group level modifier: %.4f%n",
          bidModifierResult.getCampaignId(), bidModifierResult.getAdGroupId(),
          bidModifierResult.getBidModifier());
    }
  }
}

Add a click-to-download ad

// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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.

package adwords.axis.v201710.advancedoperations;

import com.beust.jcommander.Parameter;
import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAd;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdOperation;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdReturnValue;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdStatus;
import com.google.api.ads.adwords.axis.v201710.cm.Image;
import com.google.api.ads.adwords.axis.v201710.cm.Operator;
import com.google.api.ads.adwords.axis.v201710.cm.TemplateAd;
import com.google.api.ads.adwords.axis.v201710.cm.TemplateElement;
import com.google.api.ads.adwords.axis.v201710.cm.TemplateElementField;
import com.google.api.ads.adwords.axis.v201710.cm.TemplateElementFieldType;
import com.google.api.ads.adwords.lib.client.AdWordsSession;
import com.google.api.ads.adwords.lib.factory.AdWordsServicesInterface;
import com.google.api.ads.adwords.lib.utils.examples.ArgumentNames;
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.utils.examples.CodeSampleParams;
import com.google.api.client.auth.oauth2.Credential;

/**
 * This example adds a click-to-download templateAd to given ad group. To get
 * adGroupId, run AddAdGroup.java.
 *
 * <p>Credentials and properties in {@code fromFile()} are pulled from the
 * "ads.properties" file. See README for more info.
 */
public class AddClickToDownloadAd {

  private static class AddClickToDownloadAdParams extends CodeSampleParams {
    @Parameter(names = ArgumentNames.AD_GROUP_ID, required = true)
    private Long adGroupId;
  }

  public static void main(String[] args) throws Exception {
    // Generate a refreshable OAuth2 credential.
    Credential oAuth2Credential = new OfflineCredentials.Builder()
        .forApi(Api.ADWORDS)
        .fromFile()
        .build()
        .generateCredential();

    // Construct an AdWordsSession.
    AdWordsSession session = new AdWordsSession.Builder()
        .fromFile()
        .withOAuth2Credential(oAuth2Credential)
        .build();

    AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance();

    AddClickToDownloadAdParams params = new AddClickToDownloadAdParams();
    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.adGroupId = Long.parseLong("INSERT_AD_GROUP_ID_HERE");
    }

    runExample(adWordsServices, session, params.adGroupId);
  }

  public static void runExample(
      AdWordsServicesInterface adWordsServices, AdWordsSession session, long adGroupId)
      throws Exception {
    // Get the AdGroupAdService.
    AdGroupAdServiceInterface adGroupAdService =
        adWordsServices.get(session, AdGroupAdServiceInterface.class);

    // Create the template ad.
    TemplateAd clickToDownloadAppAd = new TemplateAd();
    clickToDownloadAppAd.setName("Ad for jupiter adventure game");
    clickToDownloadAppAd.setTemplateId(353L);

    clickToDownloadAppAd.setFinalUrls(
        new String[] {"http://play.google.com/store/apps/details?id=com.example.jupiteradventure"});
    clickToDownloadAppAd.setDisplayUrl("play.google.com");

    // Create the template elements for the ad. You can refer to
    // https://developers.google.com/adwords/api/docs/appendix/templateads
    // for the list of available template fields.
    TemplateElementField headline = new TemplateElementField();
    headline.setName("headline");
    headline.setFieldText("Enjoy a Jupiter Adventure");
    headline.setType(TemplateElementFieldType.TEXT);

    TemplateElementField description1 = new TemplateElementField();
    description1.setName("description1");
    description1.setFieldText("Realistic physics simulation");
    description1.setType(TemplateElementFieldType.TEXT);

    TemplateElementField description2 = new TemplateElementField();
    description2.setName("description2");
    description2.setFieldText("Race against players online");
    description2.setType(TemplateElementFieldType.TEXT);

    TemplateElementField appId = new TemplateElementField();
    appId.setName("appId");
    appId.setFieldText("com.example.jupiteradventure");
    appId.setType(TemplateElementFieldType.TEXT);

    TemplateElementField appStore = new TemplateElementField();
    appStore.setName("appStore");
    appStore.setFieldText("2");
    appStore.setType(TemplateElementFieldType.ENUM);

    // Optionally specify a landscape image. The image needs to be in a BASE64
    // encoded form. Here we download a demo image and encode it for this ad.
    byte[] imageData =
        com.google.api.ads.common.lib.utils.Media.getMediaDataFromUrl("https://goo.gl/9JmyKk");
    Image image = new Image();
    image.setData(imageData);
    TemplateElementField landscapeImage = new TemplateElementField();
    landscapeImage.setName("landscapeImage");
    landscapeImage.setFieldMedia(image);
    landscapeImage.setType(TemplateElementFieldType.IMAGE);

    TemplateElement adData = new TemplateElement();
    adData.setUniqueName("adData");
    adData.setFields(
        new TemplateElementField[] {
          headline, description1, description2, appId, appStore, landscapeImage
        });

    clickToDownloadAppAd.setTemplateElements(new TemplateElement[] {adData});

    // Create the AdGroupAd.
    AdGroupAd clickToDownloadAppAdGroupAd = new AdGroupAd();
    clickToDownloadAppAdGroupAd.setAdGroupId(adGroupId);
    clickToDownloadAppAdGroupAd.setAd(clickToDownloadAppAd);

    // Optional: Set the status.
    clickToDownloadAppAdGroupAd.setStatus(AdGroupAdStatus.PAUSED);

    // Create the operation.
    AdGroupAdOperation operation = new AdGroupAdOperation();
    operation.setOperator(Operator.ADD);
    operation.setOperand(clickToDownloadAppAdGroupAd);

    // Create the ads.
    AdGroupAdReturnValue result = adGroupAdService.mutate(new AdGroupAdOperation[] {operation});

    for (AdGroupAd adGroupAd : result.getValue()) {
      System.out.printf("New click-to-download ad with ID %d and url %s was created.%n",
          adGroupAd.getAd().getId(), adGroupAd.getAd().getFinalUrls(0));
    }
  }
}

Add a page feed specifying URLs for a DSA campaign

// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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.

package adwords.axis.v201710.advancedoperations;

import com.beust.jcommander.Parameter;
import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.utils.v201710.SelectorBuilder;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupCriterionOperation;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupCriterionServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.ApiException;
import com.google.api.ads.adwords.axis.v201710.cm.AttributeFieldMapping;
import com.google.api.ads.adwords.axis.v201710.cm.BiddableAdGroupCriterion;
import com.google.api.ads.adwords.axis.v201710.cm.BiddingStrategyConfiguration;
import com.google.api.ads.adwords.axis.v201710.cm.Bids;
import com.google.api.ads.adwords.axis.v201710.cm.Campaign;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignOperation;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignPage;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.CpcBid;
import com.google.api.ads.adwords.axis.v201710.cm.DynamicSearchAdsSetting;
import com.google.api.ads.adwords.axis.v201710.cm.Feed;
import com.google.api.ads.adwords.axis.v201710.cm.FeedAttribute;
import com.google.api.ads.adwords.axis.v201710.cm.FeedAttributeType;
import com.google.api.ads.adwords.axis.v201710.cm.FeedItem;
import com.google.api.ads.adwords.axis.v201710.cm.FeedItemAttributeValue;
import com.google.api.ads.adwords.axis.v201710.cm.FeedItemOperation;
import com.google.api.ads.adwords.axis.v201710.cm.FeedItemReturnValue;
import com.google.api.ads.adwords.axis.v201710.cm.FeedItemServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.FeedMapping;
import com.google.api.ads.adwords.axis.v201710.cm.FeedMappingOperation;
import com.google.api.ads.adwords.axis.v201710.cm.FeedMappingServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.FeedOperation;
import com.google.api.ads.adwords.axis.v201710.cm.FeedOrigin;
import com.google.api.ads.adwords.axis.v201710.cm.FeedServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.Money;
import com.google.api.ads.adwords.axis.v201710.cm.Operator;
import com.google.api.ads.adwords.axis.v201710.cm.PageFeed;
import com.google.api.ads.adwords.axis.v201710.cm.Selector;
import com.google.api.ads.adwords.axis.v201710.cm.Setting;
import com.google.api.ads.adwords.axis.v201710.cm.Webpage;
import com.google.api.ads.adwords.axis.v201710.cm.WebpageCondition;
import com.google.api.ads.adwords.axis.v201710.cm.WebpageConditionOperand;
import com.google.api.ads.adwords.axis.v201710.cm.WebpageParameter;
import com.google.api.ads.adwords.lib.client.AdWordsSession;
import com.google.api.ads.adwords.lib.factory.AdWordsServicesInterface;
import com.google.api.ads.adwords.lib.selectorfields.v201710.cm.CampaignField;
import com.google.api.ads.adwords.lib.utils.examples.ArgumentNames;
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.utils.examples.CodeSampleParams;
import com.google.api.client.auth.oauth2.Credential;
import java.rmi.RemoteException;

/**
 * This code example adds a page feed to specify precisely which URLs to use with your Dynamic
 * Search Ads campaign. To create a Dynamic Search Ads campaign, run
 * AddDynamicSearchAdsCampaign.java. To get campaigns, run GetCampaigns.java.
 *
 * <p>Credentials and properties in {@code fromFile()} are pulled from the "ads.properties" file.
 * See README for more info.
 */
public class AddDynamicPageFeed {

  // The criterion type to be used for DSA page feeds. DSA page feeds use criterionType field
  // instead of the placeholderType field unlike most other feed types.
  private static final int DSA_PAGE_FEED_CRITERION_TYPE = 61;

  // ID that corresponds to the page URLs.
  private static final int DSA_PAGE_URLS_FIELD_ID = 1;

  // ID that corresponds to the labels.
  private static final int DSA_LABEL_FIELD_ID = 2;

  /** Class to keep track of DSA page feed details. */
  private static class DSAFeedDetails {
    private Long feedId;
    private Long urlAttributeId;
    private Long labelAttributeId;
  }

  private static class AddDynamicPageFeedParams extends CodeSampleParams {
    @Parameter(names = ArgumentNames.CAMPAIGN_ID, required = true)
    private Long campaignId;

    @Parameter(names = ArgumentNames.AD_GROUP_ID, required = true)
    private Long adGroupId;
  }

  public static void main(String[] args) throws Exception {
    // Generate a refreshable OAuth2 credential.
    Credential oAuth2Credential =
        new OfflineCredentials.Builder()
            .forApi(Api.ADWORDS)
            .fromFile()
            .build()
            .generateCredential();

    // Construct an AdWordsSession.
    AdWordsSession session =
        new AdWordsSession.Builder().fromFile().withOAuth2Credential(oAuth2Credential).build();

    AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance();

    AddDynamicPageFeedParams params = new AddDynamicPageFeedParams();
    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.campaignId = Long.parseLong("INSERT_CAMPAIGN_ID_HERE");
      params.adGroupId = Long.parseLong("INSERT_AD_GROUP_ID_HERE");
    }

    runExample(adWordsServices, session, params.campaignId, params.adGroupId);
  }

  public static void runExample(
      AdWordsServicesInterface adWordsServices,
      AdWordsSession session,
      Long campaignId,
      Long adGroupId)
      throws Exception {
    String dsaPageUrlLabel = "discounts";

    // Get the page feed details. This code example creates a new feed, but you can
    // fetch and re-use an existing feed.
    DSAFeedDetails feedDetails = createFeed(adWordsServices, session);
    createFeedMapping(adWordsServices, session, feedDetails);
    createFeedItems(adWordsServices, session, feedDetails, dsaPageUrlLabel);

    // Associate the page feed with the campaign.
    updateCampaignDsaSetting(adWordsServices, session, campaignId, feedDetails);

    // Optional: Target web pages matching the feed's label in the ad group.
    addDsaTargeting(adWordsServices, session, adGroupId, dsaPageUrlLabel);

    System.out.printf("Dynamic page feed setup is complete for campaign ID %s.%n", campaignId);
  }

  /** Creates the feed for DSA page URLs. */
  private static DSAFeedDetails createFeed(
      AdWordsServicesInterface adWordsServices, AdWordsSession session)
      throws ApiException, RemoteException {
    // Get the FeedService.
    FeedServiceInterface feedService = adWordsServices.get(session, FeedServiceInterface.class);

    // Create attributes.
    FeedAttribute urlAttribute = new FeedAttribute();
    urlAttribute.setType(FeedAttributeType.URL_LIST);
    urlAttribute.setName("Page URL");

    FeedAttribute labelAttribute = new FeedAttribute();
    labelAttribute.setType(FeedAttributeType.STRING_LIST);
    labelAttribute.setName("Label");

    // Create the feed.
    Feed dsaPageFeed = new Feed();
    dsaPageFeed.setName("DSA Feed #" + System.currentTimeMillis());
    dsaPageFeed.setAttributes(new FeedAttribute[] {urlAttribute, labelAttribute});
    dsaPageFeed.setOrigin(FeedOrigin.USER);

    // Create operation.
    FeedOperation operation = new FeedOperation();
    operation.setOperand(dsaPageFeed);
    operation.setOperator(Operator.ADD);

    // Add the feed.
    Feed newFeed = feedService.mutate(new FeedOperation[] {operation}).getValue(0);

    DSAFeedDetails feedDetails = new DSAFeedDetails();
    feedDetails.feedId = newFeed.getId();
    FeedAttribute[] savedAttributes = newFeed.getAttributes();
    feedDetails.urlAttributeId = savedAttributes[0].getId();
    feedDetails.labelAttributeId = savedAttributes[1].getId();
    System.out.printf(
        "Feed with name '%s' and ID %d with urlAttributeId %d"
            + " and labelAttributeId %d was created.%n",
        newFeed.getName(),
        feedDetails.feedId,
        feedDetails.urlAttributeId,
        feedDetails.labelAttributeId);
    return feedDetails;
  }

  /** Creates the feed mapping for the DSA page feeds. */
  private static void createFeedMapping(
      AdWordsServicesInterface adWordsServices, AdWordsSession session, DSAFeedDetails feedDetails)
      throws Exception {
    // Get the FeedMappingService.
    FeedMappingServiceInterface feedMappingService =
        adWordsServices.get(session, FeedMappingServiceInterface.class);

    // Map the FeedAttributeIds to the fieldId constants.
    AttributeFieldMapping urlFieldMapping = new AttributeFieldMapping();
    urlFieldMapping.setFeedAttributeId(feedDetails.urlAttributeId);
    urlFieldMapping.setFieldId(DSA_PAGE_URLS_FIELD_ID);
    AttributeFieldMapping labelFieldMapping = new AttributeFieldMapping();
    labelFieldMapping.setFeedAttributeId(feedDetails.labelAttributeId);
    labelFieldMapping.setFieldId(DSA_LABEL_FIELD_ID);

    // Create the FeedMapping and operation.
    FeedMapping feedMapping = new FeedMapping();
    feedMapping.setCriterionType(DSA_PAGE_FEED_CRITERION_TYPE);
    feedMapping.setFeedId(feedDetails.feedId);
    feedMapping.setAttributeFieldMappings(
        new AttributeFieldMapping[] {urlFieldMapping, labelFieldMapping});
    FeedMappingOperation operation = new FeedMappingOperation();
    operation.setOperand(feedMapping);
    operation.setOperator(Operator.ADD);

    // Add the field mapping.
    FeedMapping newFeedMapping =
        feedMappingService.mutate(new FeedMappingOperation[] {operation}).getValue(0);
    System.out.printf(
        "Feed mapping with ID %d and criterionType %d was saved for feed with ID %d.%n",
        newFeedMapping.getFeedMappingId(),
        newFeedMapping.getCriterionType(),
        newFeedMapping.getFeedId());
  }

  /** Creates the page URLs in the DSA page feed. */
  private static void createFeedItems(
      AdWordsServicesInterface adWordsServices,
      AdWordsSession session,
      DSAFeedDetails feedDetails,
      String labelName)
      throws Exception {
    // Get the FeedItemService.
    FeedItemServiceInterface feedItemService =
        adWordsServices.get(session, FeedItemServiceInterface.class);

    // Create operations to add FeedItems.
    FeedItemOperation[] operations =
        new FeedItemOperation[] {
          createDsaUrlAddOperation(
              feedDetails, "http://www.example.com/discounts/rental-cars", labelName),
          createDsaUrlAddOperation(
              feedDetails, "http://www.example.com/discounts/hotel-deals", labelName),
          createDsaUrlAddOperation(
              feedDetails, "http://www.example.com/discounts/flight-deals", labelName),
        };

    FeedItemReturnValue result = feedItemService.mutate(operations);
    for (FeedItem item : result.getValue()) {
      System.out.printf("Feed item with feed item ID %d was added.%n", item.getFeedItemId());
    }
  }

  /** Creates a {@link FeedItemOperation} to add the DSA URL. */
  private static FeedItemOperation createDsaUrlAddOperation(
      DSAFeedDetails feedDetails, String url, String labelName) {
    // Create the FeedItemAttributeValues for the URL and label.
    FeedItemAttributeValue urlAttributeValue = new FeedItemAttributeValue();
    urlAttributeValue.setFeedAttributeId(feedDetails.urlAttributeId);

    // Optional: Add the {feeditem} valuetrack parameter to track which page feed items lead
    // to each click.
    url = url + "?id={feeditem}";
    urlAttributeValue.setStringValues(new String[] {url});

    FeedItemAttributeValue labelAttributeValue = new FeedItemAttributeValue();
    labelAttributeValue.setFeedAttributeId(feedDetails.labelAttributeId);
    labelAttributeValue.setStringValues(new String[] {labelName});

    // Create the feed item and operation.
    FeedItem feedItem = new FeedItem();
    feedItem.setFeedId(feedDetails.feedId);

    feedItem.setAttributeValues(
        new FeedItemAttributeValue[] {urlAttributeValue, labelAttributeValue});

    FeedItemOperation operation = new FeedItemOperation();
    operation.setOperand(feedItem);
    operation.setOperator(Operator.ADD);

    return operation;
  }

  /** Updates the campaign DSA setting to add DSA pagefeeds. */
  private static void updateCampaignDsaSetting(
      AdWordsServicesInterface adWordsServices,
      AdWordsSession session,
      Long campaignId,
      DSAFeedDetails feedDetails)
      throws ApiException, RemoteException {
    // Get the CampaignService.
    CampaignServiceInterface campaignService =
        adWordsServices.get(session, CampaignServiceInterface.class);

    Selector selector =
        new SelectorBuilder()
            .fields(CampaignField.Id, CampaignField.Settings)
            .equalsId(campaignId)
            .build();

    CampaignPage campaignPage = campaignService.get(selector);
    if (campaignPage.getEntries() == null || campaignPage.getTotalNumEntries() == 0) {
      throw new IllegalArgumentException("No campaign found with ID: " + campaignId);
    }
    Campaign campaign = campaignPage.getEntries(0);

    if (campaign.getSettings() == null) {
      throw new IllegalArgumentException(
          "Campaign with ID " + campaignId + " is not a DSA campaign.");
    }

    DynamicSearchAdsSetting dsaSetting = null;
    for (Setting setting : campaign.getSettings()) {
      if (setting instanceof DynamicSearchAdsSetting) {
        dsaSetting = (DynamicSearchAdsSetting) setting;
        break;
      }
    }

    if (dsaSetting == null) {
      throw new IllegalArgumentException(
          "Campaign with ID " + campaignId + " is not a DSA campaign.");
    }

    // Use a page feed to specify precisely which URLs to use with your
    // Dynamic Search Ads.
    PageFeed pageFeed = new PageFeed();
    pageFeed.setFeedIds(new long[] {feedDetails.feedId});
    dsaSetting.setPageFeed(pageFeed);

    // Optional: Specify whether only the supplied URLs should be used with your
    // Dynamic Search Ads.
    dsaSetting.setUseSuppliedUrlsOnly(true);

    Campaign updatedCampaign = new Campaign();
    updatedCampaign.setId(campaignId);
    updatedCampaign.setSettings(campaign.getSettings());

    CampaignOperation operation = new CampaignOperation();
    operation.setOperand(updatedCampaign);
    operation.setOperator(Operator.SET);

    updatedCampaign = campaignService.mutate(new CampaignOperation[] {operation}).getValue(0);
    System.out.printf(
        "DSA page feed for campaign ID %d was updated with feed ID %d.%n",
        updatedCampaign.getId(), feedDetails.feedId);
  }

  /**
   * Sets custom targeting for the page feed URLs based on a list of labels.
   *
   * @param adWordsServices
   * @param session
   * @param adGroupId
   * @param dsaPageUrlLabel
   */
  private static void addDsaTargeting(
      AdWordsServicesInterface adWordsServices,
      AdWordsSession session,
      Long adGroupId,
      String dsaPageUrlLabel)
      throws ApiException, RemoteException {
    // Get the AdGroupCriterionService.
    AdGroupCriterionServiceInterface adGroupCriterionService =
        adWordsServices.get(session, AdGroupCriterionServiceInterface.class);

    // Create a webpage criterion.
    Webpage webpage = new Webpage();

    WebpageParameter parameter = new WebpageParameter();
    parameter.setCriterionName("Test criterion");
    webpage.setParameter(parameter);

    // Add a condition for label=specified_label_name.
    WebpageCondition condition = new WebpageCondition();
    condition.setOperand(WebpageConditionOperand.CUSTOM_LABEL);
    condition.setArgument(dsaPageUrlLabel);
    parameter.setConditions(new WebpageCondition[] {condition});

    BiddableAdGroupCriterion criterion = new BiddableAdGroupCriterion();
    criterion.setAdGroupId(adGroupId);
    criterion.setCriterion(webpage);

    // Set a custom bid for this criterion.
    BiddingStrategyConfiguration biddingStrategyConfiguration = new BiddingStrategyConfiguration();

    CpcBid cpcBid = new CpcBid();
    Money money = new Money();
    money.setMicroAmount(1_500_000L);
    cpcBid.setBid(money);
    biddingStrategyConfiguration.setBids(new Bids[] {cpcBid});

    criterion.setBiddingStrategyConfiguration(biddingStrategyConfiguration);

    AdGroupCriterionOperation operation = new AdGroupCriterionOperation();
    operation.setOperand(criterion);
    operation.setOperator(Operator.ADD);

    BiddableAdGroupCriterion newCriterion =
        (BiddableAdGroupCriterion)
            adGroupCriterionService.mutate(new AdGroupCriterionOperation[] {operation}).getValue(0);
    System.out.printf(
        "Web page criterion with ID %d and status '%s' was created.%n",
        newCriterion.getCriterion().getId(), newCriterion.getUserStatus());
  }
}

Add a DSA campaign

// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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.

package adwords.axis.v201710.advancedoperations;

import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroup;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAd;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdOperation;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdStatus;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupCriterion;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupCriterionOperation;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupCriterionServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupOperation;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupStatus;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupType;
import com.google.api.ads.adwords.axis.v201710.cm.AdvertisingChannelType;
import com.google.api.ads.adwords.axis.v201710.cm.ApiException;
import com.google.api.ads.adwords.axis.v201710.cm.BiddableAdGroupCriterion;
import com.google.api.ads.adwords.axis.v201710.cm.BiddingStrategyConfiguration;
import com.google.api.ads.adwords.axis.v201710.cm.BiddingStrategyType;
import com.google.api.ads.adwords.axis.v201710.cm.Bids;
import com.google.api.ads.adwords.axis.v201710.cm.Budget;
import com.google.api.ads.adwords.axis.v201710.cm.BudgetBudgetDeliveryMethod;
import com.google.api.ads.adwords.axis.v201710.cm.BudgetOperation;
import com.google.api.ads.adwords.axis.v201710.cm.BudgetServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.Campaign;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignOperation;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignStatus;
import com.google.api.ads.adwords.axis.v201710.cm.CpcBid;
import com.google.api.ads.adwords.axis.v201710.cm.DynamicSearchAdsSetting;
import com.google.api.ads.adwords.axis.v201710.cm.ExpandedDynamicSearchAd;
import com.google.api.ads.adwords.axis.v201710.cm.Money;
import com.google.api.ads.adwords.axis.v201710.cm.Operator;
import com.google.api.ads.adwords.axis.v201710.cm.Setting;
import com.google.api.ads.adwords.axis.v201710.cm.UserStatus;
import com.google.api.ads.adwords.axis.v201710.cm.Webpage;
import com.google.api.ads.adwords.axis.v201710.cm.WebpageCondition;
import com.google.api.ads.adwords.axis.v201710.cm.WebpageConditionOperand;
import com.google.api.ads.adwords.axis.v201710.cm.WebpageParameter;
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.client.auth.oauth2.Credential;
import java.rmi.RemoteException;
import org.joda.time.DateTime;

/**
 * This code example adds a Dynamic Search Ads campaign. To get campaigns, run GetCampaigns.java.
 *
 * <p>Credentials and properties in {@code fromFile()} are pulled from the "ads.properties" file.
 * See README for more info.
 */
public class AddDynamicSearchAdsCampaign {

  public static void main(String[] args) throws Exception {
    // Generate a refreshable OAuth2 credential.
    Credential oAuth2Credential =
        new OfflineCredentials.Builder()
            .forApi(Api.ADWORDS)
            .fromFile()
            .build()
            .generateCredential();

    // Construct an AdWordsSession.
    AdWordsSession session =
        new AdWordsSession.Builder().fromFile().withOAuth2Credential(oAuth2Credential).build();

    AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance();

    runExample(adWordsServices, session);
  }

  public static void runExample(AdWordsServicesInterface adWordsServices, AdWordsSession session)
      throws Exception {
    Budget budget = createBudget(adWordsServices, session);

    Campaign campaign = createCampaign(adWordsServices, session, budget);
    AdGroup adGroup = createAdGroup(adWordsServices, session, campaign);
    createExpandedDSA(adWordsServices, session, adGroup);
    addWebPageCriteria(adWordsServices, session, adGroup);
  }

  /** Creates the campaign. */
  private static Campaign createCampaign(
      AdWordsServicesInterface adWordsServices, AdWordsSession session, Budget budget)
      throws RemoteException, ApiException {
    // Get the CampaignService.
    CampaignServiceInterface campaignService =
        adWordsServices.get(session, CampaignServiceInterface.class);

    // Create campaign.
    Campaign campaign = new Campaign();
    campaign.setName("Interplanetary Cruise #" + System.currentTimeMillis());
    campaign.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.
    campaign.setStatus(CampaignStatus.PAUSED);

    BiddingStrategyConfiguration biddingStrategyConfiguration = new BiddingStrategyConfiguration();
    biddingStrategyConfiguration.setBiddingStrategyType(BiddingStrategyType.MANUAL_CPC);
    campaign.setBiddingStrategyConfiguration(biddingStrategyConfiguration);

    // Only the budgetId should be sent, all other fields will be ignored by CampaignService.
    Budget campaignBudget = new Budget();
    campaignBudget.setBudgetId(budget.getBudgetId());
    campaign.setBudget(campaignBudget);

    // Required: Set the campaign's Dynamic Search Ads settings.
    DynamicSearchAdsSetting dynamicSearchAdsSetting = new DynamicSearchAdsSetting();
    // Required: Set the domain name and language.
    dynamicSearchAdsSetting.setDomainName("example.com");
    dynamicSearchAdsSetting.setLanguageCode("en");

    // Set the campaign settings.
    campaign.setSettings(new Setting[] {dynamicSearchAdsSetting});

    // Optional: Set the start date.
    campaign.setStartDate(new DateTime().plusDays(1).toString("yyyyMMdd"));
    // Optional: Set the end date.
    campaign.setEndDate(new DateTime().plusYears(1).toString("yyyyMMdd"));

    // Create the operation.
    CampaignOperation operation = new CampaignOperation();
    operation.setOperand(campaign);
    operation.setOperator(Operator.ADD);

    // Add the campaign.
    Campaign newCampaign = campaignService.mutate(new CampaignOperation[] {operation}).getValue(0);

    // Display the results.
    System.out.printf(
        "Campaign with name '%s' and ID %d was added.%n",
        newCampaign.getName(), newCampaign.getId());

    return newCampaign;
  }

  /** Creates the budget. */
  private static Budget createBudget(
      AdWordsServicesInterface adWordsServices, AdWordsSession session)
      throws RemoteException, ApiException {
    // Get the BudgetService.
    BudgetServiceInterface budgetService =
        adWordsServices.get(session, BudgetServiceInterface.class);

    // Create 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(50000000L);
    sharedBudget.setAmount(budgetAmount);
    sharedBudget.setDeliveryMethod(BudgetBudgetDeliveryMethod.STANDARD);

    BudgetOperation budgetOperation = new BudgetOperation();
    budgetOperation.setOperand(sharedBudget);
    budgetOperation.setOperator(Operator.ADD);

    // Add the budget
    Budget budget = budgetService.mutate(new BudgetOperation[] {budgetOperation}).getValue(0);
    return budget;
  }

  /** Creates the ad group. */
  private static AdGroup createAdGroup(
      AdWordsServicesInterface adWordsServices, AdWordsSession session, Campaign campaign)
      throws ApiException, RemoteException {
    // Get the AdGroupService.
    AdGroupServiceInterface adGroupService =
        adWordsServices.get(session, AdGroupServiceInterface.class);

    // Create the ad group.
    AdGroup adGroup = new AdGroup();

    // Required: Set the ad group's type to Dynamic Search Ads.
    adGroup.setAdGroupType(AdGroupType.SEARCH_DYNAMIC_ADS);

    adGroup.setName("Earth to Mars Cruises #" + System.currentTimeMillis());
    adGroup.setCampaignId(campaign.getId());
    adGroup.setStatus(AdGroupStatus.PAUSED);

    // Recommended: Set a tracking URL template for your ad group if you want to use URL
    // tracking software.
    adGroup.setTrackingUrlTemplate("http://tracker.example.com/traveltracker/{escapedlpurl}");
    
    // Set the ad group bids.
    BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration();

    CpcBid cpcBid = new CpcBid();
    cpcBid.setBid(new Money());
    cpcBid.getBid().setMicroAmount(3000000L);

    biddingConfig.setBids(new Bids[] {cpcBid});

    adGroup.setBiddingStrategyConfiguration(biddingConfig);

    // Create the operation.
    AdGroupOperation operation = new AdGroupOperation();
    operation.setOperand(adGroup);
    operation.setOperator(Operator.ADD);

    AdGroup newAdGroup = adGroupService.mutate(new AdGroupOperation[] {operation}).getValue(0);
    System.out.printf(
        "Ad group with name '%s' and ID %d was added.%n", newAdGroup.getName(), newAdGroup.getId());
    return newAdGroup;
  }

  /** Creates the expanded Dynamic Search Ad. */
  private static void createExpandedDSA(
      AdWordsServicesInterface adWordsServices, AdWordsSession session, AdGroup adGroup)
      throws ApiException, RemoteException {
    // Get the AdGroupAdService.
    AdGroupAdServiceInterface adGroupAdService =
        adWordsServices.get(session, AdGroupAdServiceInterface.class);

    // Create the expanded Dynamic Search Ad. This ad will have its headline and final URL
    // auto-generated at serving time according to domain name specific information provided
    // by DynamicSearchAdsSetting at the campaign level.
    ExpandedDynamicSearchAd expandedDSA = new ExpandedDynamicSearchAd();
    // Set the ad description.
    expandedDSA.setDescription("Buy your tickets now!");

    // Create the ad group ad.
    AdGroupAd adGroupAd = new AdGroupAd();
    adGroupAd.setAdGroupId(adGroup.getId());
    adGroupAd.setAd(expandedDSA);

    // Optional: Set the status.
    adGroupAd.setStatus(AdGroupAdStatus.PAUSED);

    // Create the operation.
    AdGroupAdOperation operation = new AdGroupAdOperation();
    operation.setOperator(Operator.ADD);
    operation.setOperand(adGroupAd);

    // Create the ad.
    AdGroupAd newAdGroupAd =
        adGroupAdService.mutate(new AdGroupAdOperation[] {operation}).getValue(0);
    ExpandedDynamicSearchAd newExpandedDSA = (ExpandedDynamicSearchAd) newAdGroupAd.getAd();
    System.out.printf(
        "Expanded Dynamic Search Ad with ID %d and description '%s' was added.%n",
        newExpandedDSA.getId(), newExpandedDSA.getDescription());
  }

  /** Adds a web page criteria to target Dynamic Search Ads. */
  private static void addWebPageCriteria(
      AdWordsServicesInterface adWordsServices, AdWordsSession session, AdGroup adGroup)
      throws ApiException, RemoteException {
    // Get the AdGroupCriterionService.
    AdGroupCriterionServiceInterface adGroupCriterionService =
        adWordsServices.get(session, AdGroupCriterionServiceInterface.class);

    // Create a webpage criterion for special offers.
    WebpageParameter param = new WebpageParameter();
    param.setCriterionName("Special offers");

    WebpageCondition urlCondition = new WebpageCondition();
    urlCondition.setOperand(WebpageConditionOperand.URL);
    urlCondition.setArgument("/specialoffers");

    WebpageCondition titleCondition = new WebpageCondition();
    titleCondition.setOperand(WebpageConditionOperand.PAGE_TITLE);
    titleCondition.setArgument("Special Offer");

    param.setConditions(new WebpageCondition[] {urlCondition, titleCondition});

    Webpage webpage = new Webpage();
    webpage.setParameter(param);

    // Create biddable ad group criterion.
    BiddableAdGroupCriterion biddableAdGroupCriterion = new BiddableAdGroupCriterion();
    biddableAdGroupCriterion.setAdGroupId(adGroup.getId());
    biddableAdGroupCriterion.setCriterion(webpage);
    biddableAdGroupCriterion.setUserStatus(UserStatus.PAUSED);

    // Optional: set a custom bid.
    BiddingStrategyConfiguration biddingStrategyConfiguration = new BiddingStrategyConfiguration();
    CpcBid bid = new CpcBid();
    bid.setBid(new Money());
    bid.getBid().setMicroAmount(10000000L);
    biddingStrategyConfiguration.setBids(new Bids[] {bid});
    biddableAdGroupCriterion.setBiddingStrategyConfiguration(biddingStrategyConfiguration);

    // Create operations.
    AdGroupCriterionOperation operation = new AdGroupCriterionOperation();
    operation.setOperator(Operator.ADD);
    operation.setOperand(biddableAdGroupCriterion);

    // Create the criterion.
    AdGroupCriterion newAdGroupCriterion =
        adGroupCriterionService.mutate(new AdGroupCriterionOperation[] {operation}).getValue(0);

    System.out.printf(
        "Webpage criterion with ID %d was added to ad group ID %d.%n",
        newAdGroupCriterion.getCriterion().getId(), newAdGroupCriterion.getAdGroupId());
  }
}

Add an expanded text ad with Upgraded URLs

// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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.

package adwords.axis.v201710.advancedoperations;

import com.beust.jcommander.Parameter;
import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAd;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdOperation;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdStatus;
import com.google.api.ads.adwords.axis.v201710.cm.CustomParameter;
import com.google.api.ads.adwords.axis.v201710.cm.CustomParameters;
import com.google.api.ads.adwords.axis.v201710.cm.ExpandedTextAd;
import com.google.api.ads.adwords.axis.v201710.cm.Operator;
import com.google.api.ads.adwords.lib.client.AdWordsSession;
import com.google.api.ads.adwords.lib.factory.AdWordsServicesInterface;
import com.google.api.ads.adwords.lib.utils.examples.ArgumentNames;
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.utils.examples.CodeSampleParams;
import com.google.api.client.auth.oauth2.Credential;

/**
 * This example adds an expanded text ad that uses advanced features of upgraded URLs.
 *
 * <p>Credentials and properties in {@code fromFile()} are pulled from the
 * "ads.properties" file. See README for more info.
 */
public class AddExpandedTextAdWithUpgradedUrls {

  private static class AddExpandedTextAdWithUpgradedUrlsParams extends CodeSampleParams {
    @Parameter(names = ArgumentNames.AD_GROUP_ID, required = true)
    private Long adGroupId;
  }

  public static void main(String[] args) throws Exception {
    // Generate a refreshable OAuth2 credential.
    Credential oAuth2Credential = new OfflineCredentials.Builder()
        .forApi(Api.ADWORDS)
        .fromFile()
        .build()
        .generateCredential();

    // Construct an AdWordsSession.
    AdWordsSession session = new AdWordsSession.Builder()
        .fromFile()
        .withOAuth2Credential(oAuth2Credential)
        .build();

    AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance();

    AddExpandedTextAdWithUpgradedUrlsParams params = new AddExpandedTextAdWithUpgradedUrlsParams();
    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.adGroupId = Long.parseLong("INSERT_AD_GROUP_ID_HERE");
    }

    runExample(adWordsServices, session, params.adGroupId);
  }

  public static void runExample(
      AdWordsServicesInterface adWordsServices, AdWordsSession session, long adGroupId)
      throws Exception {
    // Get the AdGroupAdService.
    AdGroupAdServiceInterface adGroupAdService =
        adWordsServices.get(session, AdGroupAdServiceInterface.class);

    // Create expanded text ad with a tracking template and custom parameters.
    ExpandedTextAd expandedTextAd = new ExpandedTextAd();
    expandedTextAd.setHeadlinePart1("Luxury Cruise to Mars");
    expandedTextAd.setHeadlinePart2("Visit the Red Planet in style.");
    expandedTextAd.setDescription("Low-gravity fun for everyone!");
    
    // Specify a tracking url for 3rd party tracking provider. You may
    // specify one at customer, campaign, ad group, ad, criterion or
    // feed item levels.
    expandedTextAd.setTrackingUrlTemplate(
        "http://tracker.example.com/?season={_season}&promocode={_promocode}&u={lpurl}");
    
    // Since your tracking url has two custom parameters, provide their
    // values too. This can be provided at campaign, ad group, ad, criterion
    // or feed item levels.
    CustomParameter seasonParameter = new CustomParameter();
    seasonParameter.setKey("season");
    seasonParameter.setValue("christmas");

    CustomParameter promoCodeParameter = new CustomParameter();
    promoCodeParameter.setKey("promocode");
    promoCodeParameter.setValue("NYC123");

    CustomParameters trackingUrlParameters = new CustomParameters();
    trackingUrlParameters.setParameters(
        new CustomParameter[] {seasonParameter, promoCodeParameter});
    expandedTextAd.setUrlCustomParameters(trackingUrlParameters);
    
    // Specify a list of final urls. This field cannot be set if url field is
    // set. This may be specified at ad, criterion, and feed item levels.
    expandedTextAd.setFinalUrls(new String[] {"http://www.example.com/cruise/space/",
        "http://www.example.com/locations/mars/"});
    
    // Specify a list of final mobile urls. This field cannot be set if url field is
    // set or finalUrls is not set. This may be specified at ad, criterion, and feed
    // item levels.
    expandedTextAd.setFinalMobileUrls(new String[] {"http://mobile.example.com/cruise/space/",
        "http://mobile.example.com/locations/mars/"});

    // Create ad group ad.
    AdGroupAd textAdGroupAd = new AdGroupAd();
    textAdGroupAd.setAdGroupId(adGroupId);
    textAdGroupAd.setAd(expandedTextAd);

    // Optional: Set status.
    textAdGroupAd.setStatus(AdGroupAdStatus.PAUSED);

    // Create operation.
    AdGroupAdOperation textAdGroupAdOperation = new AdGroupAdOperation();
    textAdGroupAdOperation.setOperand(textAdGroupAd);
    textAdGroupAdOperation.setOperator(Operator.ADD);

    AdGroupAdOperation[] operations =
        new AdGroupAdOperation[] {textAdGroupAdOperation};

    // Add ad.
    AdGroupAd adGroupAdResult = adGroupAdService.mutate(operations).getValue(0);

    // Display ad.
    System.out.printf("Ad with ID %d and tracking URL template '%s' was added.",
        adGroupAdResult.getAd().getId(), adGroupAdResult.getAd().getTrackingUrlTemplate());
  }
}

Add an HTML 5 ad to an ad group

// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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.

package adwords.axis.v201710.advancedoperations;

import com.beust.jcommander.Parameter;
import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAd;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdOperation;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdReturnValue;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdStatus;
import com.google.api.ads.adwords.axis.v201710.cm.Dimensions;
import com.google.api.ads.adwords.axis.v201710.cm.MediaBundle;
import com.google.api.ads.adwords.axis.v201710.cm.MediaMediaType;
import com.google.api.ads.adwords.axis.v201710.cm.Operator;
import com.google.api.ads.adwords.axis.v201710.cm.TemplateAd;
import com.google.api.ads.adwords.axis.v201710.cm.TemplateElement;
import com.google.api.ads.adwords.axis.v201710.cm.TemplateElementField;
import com.google.api.ads.adwords.axis.v201710.cm.TemplateElementFieldType;
import com.google.api.ads.adwords.lib.client.AdWordsSession;
import com.google.api.ads.adwords.lib.factory.AdWordsServicesInterface;
import com.google.api.ads.adwords.lib.utils.examples.ArgumentNames;
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.utils.examples.CodeSampleParams;
import com.google.api.client.auth.oauth2.Credential;

/**
 * This example adds an HTML5 ad to given ad group. To get
 * ad groups, run GetAdGroups.java.
 *
 * <p>Credentials and properties in {@code fromFile()} are pulled from the
 * "ads.properties" file. See README for more info.
 */
public class AddHtml5Ad {

  private static class AddHtml5AdParams extends CodeSampleParams {
    @Parameter(names = ArgumentNames.AD_GROUP_ID, required = true)
    private Long adGroupId;
  }

  public static void main(String[] args) throws Exception {
    // Generate a refreshable OAuth2 credential.
    Credential oAuth2Credential = new OfflineCredentials.Builder()
        .forApi(Api.ADWORDS)
        .fromFile()
        .build()
        .generateCredential();

    // Construct an AdWordsSession.
    AdWordsSession session = new AdWordsSession.Builder()
        .fromFile()
        .withOAuth2Credential(oAuth2Credential)
        .build();

    AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance();

    AddHtml5AdParams params = new AddHtml5AdParams();
    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.adGroupId = Long.parseLong("INSERT_AD_GROUP_ID_HERE");
    }

    runExample(adWordsServices, session, params.adGroupId);
  }

  public static void runExample(
      AdWordsServicesInterface adWordsServices, AdWordsSession session, long adGroupId)
      throws Exception {
    // Get the AdGroupAdService.
    AdGroupAdServiceInterface adGroupAdService =
        adWordsServices.get(session, AdGroupAdServiceInterface.class);

    // Create the template ad.
    TemplateAd html5Ad = new TemplateAd();
    html5Ad.setName("Ad for HTML5");
    html5Ad.setTemplateId(419L);
    html5Ad.setFinalUrls(new String[] {"http://example.com/html5"});
    html5Ad.setDisplayUrl("example.com/html5");

    Dimensions dimensions = new Dimensions();
    dimensions.setWidth(300);
    dimensions.setHeight(250);
    html5Ad.setDimensions(dimensions);

    // The HTML5 zip file contains all the HTML, CSS, and images needed for the
    // HTML5 ad. For help on creating an HTML5 zip file, check out Google Web
    // Designer (https://www.google.com/webdesigner/).
    byte[] html5Zip =
        com.google.api.ads.common.lib.utils.Media.getMediaDataFromUrl("https://goo.gl/9Y7qI2");

    // Create a media bundle containing the zip file with all the HTML5 components.
    // NOTE: You may also upload an HTML5 zip using MediaService.upload()
    // and simply set the mediaId field below. See UploadMediaBundle.java for an example.
    MediaBundle mediaBundle = new MediaBundle();
    mediaBundle.setData(html5Zip);
    mediaBundle.setEntryPoint("carousel/index.html");
    mediaBundle.setType(MediaMediaType.MEDIA_BUNDLE);

    // Create the template elements for the ad. You can refer to
    // https://developers.google.com/adwords/api/docs/appendix/templateads
    // for the list of available template fields.
    TemplateElementField media = new TemplateElementField();
    media.setName("Custom_layout");
    media.setFieldMedia(mediaBundle);
    media.setType(TemplateElementFieldType.MEDIA_BUNDLE);

    TemplateElementField layout = new TemplateElementField();
    layout.setName("layout");
    layout.setFieldText("Custom");
    layout.setType(TemplateElementFieldType.ENUM);

    TemplateElement adData = new TemplateElement();
    adData.setUniqueName("adData");
    adData.setFields(new TemplateElementField[] {media, layout});

    html5Ad.setTemplateElements(new TemplateElement[] {adData});

    // Create the AdGroupAd.
    AdGroupAd html5AdGroupAd = new AdGroupAd();
    html5AdGroupAd.setAdGroupId(adGroupId);
    html5AdGroupAd.setAd(html5Ad);

    // Optional: Set the status.
    html5AdGroupAd.setStatus(AdGroupAdStatus.PAUSED);

    // Create the operation.
    AdGroupAdOperation operation = new AdGroupAdOperation();
    operation.setOperator(Operator.ADD);
    operation.setOperand(html5AdGroupAd);

    // Create the ads.
    AdGroupAdReturnValue result = adGroupAdService.mutate(new AdGroupAdOperation[] {operation});

    for (AdGroupAd adGroupAd : result.getValue()) {
      System.out.printf("New HTML5 ad with ID %d and display url '%s' was created.%n",
          adGroupAd.getAd().getId(), adGroupAd.getAd().getDisplayUrl());
    }
  }
}

Add responsive ads

// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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.

package adwords.axis.v201710.advancedoperations;

import com.beust.jcommander.Parameter;
import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAd;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdOperation;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdReturnValue;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupAdStatus;
import com.google.api.ads.adwords.axis.v201710.cm.DynamicSettings;
import com.google.api.ads.adwords.axis.v201710.cm.Image;
import com.google.api.ads.adwords.axis.v201710.cm.Media;
import com.google.api.ads.adwords.axis.v201710.cm.MediaMediaType;
import com.google.api.ads.adwords.axis.v201710.cm.MediaServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.Operator;
import com.google.api.ads.adwords.axis.v201710.cm.ResponsiveDisplayAd;
import com.google.api.ads.adwords.lib.client.AdWordsSession;
import com.google.api.ads.adwords.lib.factory.AdWordsServicesInterface;
import com.google.api.ads.adwords.lib.utils.examples.ArgumentNames;
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.utils.examples.CodeSampleParams;
import com.google.api.client.auth.oauth2.Credential;
import java.io.IOException;

/**
 * This example adds an image representing the ad using the MediaService and then adds a responsive
 * display ad to a given ad group. To get ad groups, run GetAdGroups.java.
 *
 * <p>Credentials and properties in {@code fromFile()} are pulled from the
 * "ads.properties" file. See README for more info.
 */
public class AddResponsiveDisplayAd {

  private static class AddResponsiveDisplayAdParams extends CodeSampleParams {
    @Parameter(names = ArgumentNames.AD_GROUP_ID, required = true)
    private Long adGroupId;
  }

  public static void main(String[] args) throws Exception {
    // Generate a refreshable OAuth2 credential.
    Credential oAuth2Credential = new OfflineCredentials.Builder()
        .forApi(Api.ADWORDS)
        .fromFile()
        .build()
        .generateCredential();

    // Construct an AdWordsSession.
    AdWordsSession session = new AdWordsSession.Builder()
        .fromFile()
        .withOAuth2Credential(oAuth2Credential)
        .build();

    AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance();

    AddResponsiveDisplayAdParams params = new AddResponsiveDisplayAdParams();
    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.adGroupId = Long.parseLong("INSERT_AD_GROUP_ID_HERE");
    }

    runExample(adWordsServices, session, params.adGroupId);
  }

  public static void runExample(
      AdWordsServicesInterface adWordsServices, AdWordsSession session, long adGroupId)
      throws Exception {
    // Get the MediaService.
    MediaServiceInterface mediaService = adWordsServices.get(session, MediaServiceInterface.class);

    // Get the AdGroupAdService.
    AdGroupAdServiceInterface adGroupAdService =
        adWordsServices.get(session, AdGroupAdServiceInterface.class);

    // Create a responsive display ad.
    ResponsiveDisplayAd responsiveDisplayAd = new ResponsiveDisplayAd();

    // This ad format does not allow the creation of an image using the
    // Image.data field. An image must first be created using the MediaService,
    // and Image.mediaId must be populated when creating the ad.
    long marketingImageMediaId = uploadImage(mediaService, "https://goo.gl/3b9Wfh");
    Image marketingImage = new Image();
    marketingImage.setMediaId(marketingImageMediaId);
    responsiveDisplayAd.setMarketingImage(marketingImage);

    responsiveDisplayAd.setShortHeadline("Travel");
    responsiveDisplayAd.setLongHeadline("Travel the World");
    responsiveDisplayAd.setDescription("Take to the air!");
    responsiveDisplayAd.setBusinessName("Interplanetary Cruises");
    responsiveDisplayAd.setFinalUrls(new String[] {"http://www.example.com/"});

    // Optional: Create a square marketing image using MediaService, and set it
    // to the ad.
    long squareMarketingImageMediaId = uploadImage(mediaService, "https://goo.gl/mtt54n");
    Image squareMarketingImage = new Image();
    squareMarketingImage.setMediaId(squareMarketingImageMediaId);
    responsiveDisplayAd.setSquareMarketingImage(squareMarketingImage);

    // Optional: set call to action text.
    responsiveDisplayAd.setCallToActionText("Shop Now");

    // Optional: Set dynamic display ad settings, composed of landscape logo
    // image, promotion text, and price prefix.
    DynamicSettings dynamicDisplayAdSettings = createDynamicDisplayAdSettings(mediaService);
    responsiveDisplayAd.setDynamicDisplayAdSettings(dynamicDisplayAdSettings);

    // Whitelisted accounts only: Set color settings using hexadecimal values.
    // Set allowFlexibleColor to false if you want your ads to render by always
    // using your colors strictly.
    /*
    responsiveDisplayAd.setMainColor("#0000ff");
    responsiveDisplayAd.setAccentColor("#ffff00");
    responsiveDisplayAd.setAllowFlexibleColor(false);
    */

    // Whitelisted accounts only: Set the format setting that the ad will be
    // served in.
    /*
    responsiveDisplayAd.setFormatSetting(
        com.google.api.ads.adwords.axis.v201710.cm.DisplayAdFormatSetting.NON_NATIVE);
    */

    // Create ad group ad for the responsive display ad.
    AdGroupAd adGroupAd = new AdGroupAd();
    adGroupAd.setAdGroupId(adGroupId);
    adGroupAd.setAd(responsiveDisplayAd);

    // Optional: set the status.
    adGroupAd.setStatus(AdGroupAdStatus.PAUSED);

    // Create the operation.
    AdGroupAdOperation adGroupAdOperation = new AdGroupAdOperation();
    adGroupAdOperation.setOperand(adGroupAd);
    adGroupAdOperation.setOperator(Operator.ADD);

    // Make the mutate request.
    AdGroupAdReturnValue result =
        adGroupAdService.mutate(new AdGroupAdOperation[] {adGroupAdOperation});

    // Display ads.
    for (AdGroupAd adGroupAdResult : result.getValue()) {
      ResponsiveDisplayAd newAd = (ResponsiveDisplayAd) adGroupAdResult.getAd();
      System.out.printf(
          "Responsive display ad with ID %d and short headline '%s' was added.%n",
          newAd.getId(), newAd.getShortHeadline());
    }
  }

  private static DynamicSettings createDynamicDisplayAdSettings(MediaServiceInterface mediaService)
      throws IOException {
    long logoImageMediaId = uploadImage(mediaService, "https://goo.gl/dEvQeF");
    Image logo = new Image();
    logo.setMediaId(logoImageMediaId);

    DynamicSettings dynamicSettings = new DynamicSettings();
    dynamicSettings.setLandscapeLogoImage(logo);
    dynamicSettings.setPricePrefix("as low as");
    dynamicSettings.setPromoText("Free shipping!");
    return dynamicSettings;
  }

  /**
   * Uploads the image from the specified {@code url} via {@code MediaService}.
   *
   * @return the {@code mediaId} of the uploaded image.
   */
  private static long uploadImage(MediaServiceInterface mediaService, String url)
      throws IOException {
    // Create image.
    Image image = new Image();
    image.setType(MediaMediaType.IMAGE);
    image.setData(com.google.api.ads.common.lib.utils.Media.getMediaDataFromUrl(url));

    // Upload image.
    Image uploadedImage = (Image) mediaService.upload(new Media[] {image})[0];
    return uploadedImage.getMediaId();
  }
}

Add a universal app campaign

// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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.

package adwords.axis.v201710.advancedoperations;

import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.v201710.cm.AdvertisingChannelSubType;
import com.google.api.ads.adwords.axis.v201710.cm.AdvertisingChannelType;
import com.google.api.ads.adwords.axis.v201710.cm.ApiException;
import com.google.api.ads.adwords.axis.v201710.cm.BiddingStrategyConfiguration;
import com.google.api.ads.adwords.axis.v201710.cm.BiddingStrategyType;
import com.google.api.ads.adwords.axis.v201710.cm.Budget;
import com.google.api.ads.adwords.axis.v201710.cm.BudgetBudgetDeliveryMethod;
import com.google.api.ads.adwords.axis.v201710.cm.BudgetOperation;
import com.google.api.ads.adwords.axis.v201710.cm.BudgetServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.Campaign;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignCriterion;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignCriterionOperation;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignCriterionReturnValue;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignCriterionServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignOperation;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignReturnValue;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignStatus;
import com.google.api.ads.adwords.axis.v201710.cm.Criterion;
import com.google.api.ads.adwords.axis.v201710.cm.GeoTargetTypeSetting;
import com.google.api.ads.adwords.axis.v201710.cm.GeoTargetTypeSettingNegativeGeoTargetType;
import com.google.api.ads.adwords.axis.v201710.cm.GeoTargetTypeSettingPositiveGeoTargetType;
import com.google.api.ads.adwords.axis.v201710.cm.Language;
import com.google.api.ads.adwords.axis.v201710.cm.Location;
import com.google.api.ads.adwords.axis.v201710.cm.Money;
import com.google.api.ads.adwords.axis.v201710.cm.Operator;
import com.google.api.ads.adwords.axis.v201710.cm.Setting;
import com.google.api.ads.adwords.axis.v201710.cm.TargetCpaBiddingScheme;
import com.google.api.ads.adwords.axis.v201710.cm.UniversalAppBiddingStrategyGoalType;
import com.google.api.ads.adwords.axis.v201710.cm.UniversalAppCampaignSetting;
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.client.auth.oauth2.Credential;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.joda.time.DateTime;

/**
 * This example adds a universal app campaign. To get campaigns, run GetCampaigns.java. To upload
 * image assets for this campaign, run UploadImage.java.
 *
 * <p>Credentials and properties in {@code fromFile()} are pulled from the "ads.properties" file.
 * See README for more info.
 */
public class AddUniversalAppCampaign {

  public static void main(String[] args) throws Exception {
    // Generate a refreshable OAuth2 credential.
    Credential oAuth2Credential =
        new OfflineCredentials.Builder()
            .forApi(Api.ADWORDS)
            .fromFile()
            .build()
            .generateCredential();

    // Construct an AdWordsSession.
    AdWordsSession session =
        new AdWordsSession.Builder().fromFile().withOAuth2Credential(oAuth2Credential).build();

    AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance();

    runExample(adWordsServices, session);
  }

  public static void runExample(AdWordsServicesInterface adWordsServices, AdWordsSession session)
      throws Exception {

    // Get the CampaignService.
    CampaignServiceInterface campaignService =
        adWordsServices.get(session, CampaignServiceInterface.class);

    // Create the campaign.
    Campaign campaign = new Campaign();
    campaign.setName("Interplanetary Cruise App #" + 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);

    // Set the advertising channel and subchannel types for universal app campaigns.
    campaign.setAdvertisingChannelType(AdvertisingChannelType.MULTI_CHANNEL);
    campaign.setAdvertisingChannelSubType(AdvertisingChannelSubType.UNIVERSAL_APP_CAMPAIGN);

    // Set the campaign's bidding strategy. universal app campaigns
    // only support TARGET_CPA bidding strategy.
    BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration();
    biddingConfig.setBiddingStrategyType(BiddingStrategyType.TARGET_CPA);

    // Set the target CPA to $1 / app install.
    TargetCpaBiddingScheme biddingScheme = new TargetCpaBiddingScheme();
    biddingScheme.setTargetCpa(new Money());
    biddingScheme.getTargetCpa().setMicroAmount(1000000L);

    biddingConfig.setBiddingScheme(biddingScheme);
    campaign.setBiddingStrategyConfiguration(biddingConfig);

    // Set the campaign's budget.
    campaign.setBudget(new Budget());
    campaign.getBudget().setBudgetId(createBudget(adWordsServices, session));

    // Optional: Set the start date.
    campaign.setStartDate(new DateTime().plusDays(1).toString("yyyyMMdd"));

    // Optional: Set the end date.
    campaign.setEndDate(new DateTime().plusYears(1).toString("yyyyMMdd"));

    // Set the campaign's assets and ad text ideas. These values will be used to
    // generate ads.
    UniversalAppCampaignSetting universalAppSetting = new UniversalAppCampaignSetting();
    universalAppSetting.setAppId("com.labpixies.colordrips");
    universalAppSetting.setDescription1("A cool puzzle game");
    universalAppSetting.setDescription2("Remove connected blocks");
    universalAppSetting.setDescription3("3 difficulty levels");
    universalAppSetting.setDescription4("4 colorful fun skins");

    // Optional: You can set up to 20 image assets for your campaign.
    // See UploadImage.java for an example on how to upload images.
    //
    // universalAppSetting.setImageMediaIds(new long[] { INSERT_IMAGE_MEDIA_ID_HERE });

    // Optimize this campaign for getting new users for your app.
    universalAppSetting.setUniversalAppBiddingStrategyGoalType(
        UniversalAppBiddingStrategyGoalType.OPTIMIZE_FOR_INSTALL_CONVERSION_VOLUME);

    // If you select the OPTIMIZE_FOR_IN_APP_CONVERSION_VOLUME goal type, then also specify
    // your in-app conversion types so AdWords can focus your campaign on people who are
    // most likely to complete the corresponding in-app actions.
    // Conversion type IDs can be retrieved using ConversionTrackerService.get.
    //
    // campaign.selectiveOptimization = new SelectiveOptimization();
    // campaign.selectiveOptimization.conversionTypeIds =
    //    new long[] { INSERT_CONVERSION_TYPE_ID_1_HERE, INSERT_CONVERSION_TYPE_ID_2_HERE };

    // Optional: Set the campaign settings for Advanced location options.
    GeoTargetTypeSetting geoSetting = new GeoTargetTypeSetting();
    geoSetting.setPositiveGeoTargetType(
        GeoTargetTypeSettingPositiveGeoTargetType.LOCATION_OF_PRESENCE);
    geoSetting.setNegativeGeoTargetType(GeoTargetTypeSettingNegativeGeoTargetType.DONT_CARE);

    campaign.setSettings(new Setting[] {universalAppSetting, geoSetting});

    // Create the operation.
    CampaignOperation operation = new CampaignOperation();
    operation.setOperand(campaign);
    operation.setOperator(Operator.ADD);

    CampaignOperation[] operations = new CampaignOperation[] {operation};

    // Add the campaign.
    CampaignReturnValue result = campaignService.mutate(operations);

    // Display the results.
    for (Campaign newCampaign : result.getValue()) {
      System.out.printf(
          "Universal app campaign with name '%s' and ID %d was added.%n",
          newCampaign.getName(), newCampaign.getId());

      // Optional: Set the campaign's location and language targeting. No other targeting
      // criteria can be used for universal app campaigns.
      setCampaignTargetingCriteria(newCampaign, adWordsServices, session);
    }
  }

  /**
   * Creates the budget for the campaign.
   *
   * @return the new budget.
   */
  private static Long createBudget(AdWordsServicesInterface adWordsServices, AdWordsSession session)
      throws RemoteException, ApiException {
    // Get the BudgetService.
    BudgetServiceInterface budgetService =
        adWordsServices.get(session, BudgetServiceInterface.class);

    // Create the campaign budget.
    Budget budget = new Budget();
    budget.setName("Interplanetary Cruise App Budget #" + System.currentTimeMillis());
    Money budgetAmount = new Money();
    budgetAmount.setMicroAmount(50000000L);
    budget.setAmount(budgetAmount);
    budget.setDeliveryMethod(BudgetBudgetDeliveryMethod.STANDARD);

    // Universal app campaigns don't support shared budgets.
    budget.setIsExplicitlyShared(false);
    BudgetOperation budgetOperation = new BudgetOperation();
    budgetOperation.setOperand(budget);
    budgetOperation.setOperator(Operator.ADD);

    // Add the budget
    Budget addedBudget = budgetService.mutate(new BudgetOperation[] {budgetOperation}).getValue(0);
    System.out.printf(
        "Budget with name '%s' and ID %d was created.%n",
        addedBudget.getName(), addedBudget.getBudgetId());
    return addedBudget.getBudgetId();
  }

  /** Sets the campaign's targeting criteria. */
  private static void setCampaignTargetingCriteria(
      Campaign campaign, AdWordsServicesInterface adWordsServices, AdWordsSession session)
      throws ApiException, RemoteException {
    // Get the CampaignCriterionService.
    CampaignCriterionServiceInterface campaignCriterionService =
        adWordsServices.get(session, CampaignCriterionServiceInterface.class);

    // Create locations. The IDs can be found in the documentation or
    // retrieved with the LocationCriterionService.
    Location california = new Location();
    california.setId(21137L);

    Location mexico = new Location();
    mexico.setId(2484L);

    // Create languages. The IDs can be found in the documentation or
    // retrieved with the ConstantDataService.
    Language english = new Language();
    english.setId(1000L);

    Language spanish = new Language();
    spanish.setId(1003L);

    List<Criterion> criteria = new ArrayList<>(Arrays.asList(california, mexico, english, spanish));

    // Create operations to add each of the criteria above.
    List<CampaignCriterionOperation> operations = new ArrayList<>();
    for (Criterion criterion : criteria) {
      CampaignCriterionOperation operation = new CampaignCriterionOperation();

      CampaignCriterion campaignCriterion = new CampaignCriterion();
      campaignCriterion.setCampaignId(campaign.getId());
      campaignCriterion.setCriterion(criterion);
      operation.setOperand(campaignCriterion);

      operation.setOperator(Operator.ADD);

      operations.add(operation);
    }

    // Set the campaign targets.
    CampaignCriterionReturnValue returnValue =
        campaignCriterionService.mutate(
            operations.toArray(new CampaignCriterionOperation[operations.size()]));

    if (returnValue != null && returnValue.getValue() != null) {
      // Display added campaign targets.
      for (CampaignCriterion campaignCriterion : returnValue.getValue()) {
        System.out.printf(
            "Campaign criteria of type '%s' and ID %d was added.%n",
            campaignCriterion.getCriterion().getCriterionType(),
            campaignCriterion.getCriterion().getId());
      }
    }
  }
}

Create and attach a shared keyword set

// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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.

package adwords.axis.v201710.advancedoperations;

import com.beust.jcommander.Parameter;
import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignSharedSet;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignSharedSetOperation;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignSharedSetServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.Keyword;
import com.google.api.ads.adwords.axis.v201710.cm.KeywordMatchType;
import com.google.api.ads.adwords.axis.v201710.cm.Operator;
import com.google.api.ads.adwords.axis.v201710.cm.SharedCriterion;
import com.google.api.ads.adwords.axis.v201710.cm.SharedCriterionOperation;
import com.google.api.ads.adwords.axis.v201710.cm.SharedCriterionReturnValue;
import com.google.api.ads.adwords.axis.v201710.cm.SharedCriterionServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.SharedSet;
import com.google.api.ads.adwords.axis.v201710.cm.SharedSetOperation;
import com.google.api.ads.adwords.axis.v201710.cm.SharedSetServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.SharedSetType;
import com.google.api.ads.adwords.lib.client.AdWordsSession;
import com.google.api.ads.adwords.lib.factory.AdWordsServicesInterface;
import com.google.api.ads.adwords.lib.utils.examples.ArgumentNames;
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.utils.examples.CodeSampleParams;
import com.google.api.client.auth.oauth2.Credential;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * This example creates a shared list of negative broad match keywords, then attaches them to a
 * campaign.
 *
 * <p>Credentials and properties in {@code fromFile()} are pulled from the
 * "ads.properties" file. See README for more info.
 */
public class CreateAndAttachSharedKeywordSet {

  private static class CreateAndAttachSharedKeywordSetParams extends CodeSampleParams {
    @Parameter(names = ArgumentNames.CAMPAIGN_ID, required = true)
    private Long campaignId;
  }

  public static void main(String[] args) throws Exception {
    // Generate a refreshable OAuth2 credential.
    Credential oAuth2Credential = new OfflineCredentials.Builder()
        .forApi(Api.ADWORDS)
        .fromFile()
        .build()
        .generateCredential();

    // Construct an AdWordsSession.
    AdWordsSession session = new AdWordsSession.Builder()
        .fromFile()
        .withOAuth2Credential(oAuth2Credential)
        .build();

    AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance();

    CreateAndAttachSharedKeywordSetParams params = new CreateAndAttachSharedKeywordSetParams();
    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.campaignId = Long.parseLong("INSERT_CAMPAIGN_ID_HERE");
    }

    runExample(adWordsServices, session, params.campaignId);
  }

  public static void runExample(AdWordsServicesInterface adWordsServices, AdWordsSession session,
      Long campaignId) throws Exception {
    // Get the SharedSetService.
    SharedSetServiceInterface sharedSetService =
        adWordsServices.get(session, SharedSetServiceInterface.class);

    // Keywords to include in the shared set.
    List<String> keywords = Arrays.asList("mars cruise", "mars hotels");

    // Create the shared negative keyword set.
    SharedSet sharedSet = new SharedSet();
    sharedSet.setName("Negative keyword list #" + System.currentTimeMillis());
    sharedSet.setType(SharedSetType.NEGATIVE_KEYWORDS);

    SharedSetOperation sharedSetOperation = new SharedSetOperation();
    sharedSetOperation.setOperator(Operator.ADD);
    sharedSetOperation.setOperand(sharedSet);

    // Add the shared set.
    sharedSet = sharedSetService.mutate(new SharedSetOperation[] {sharedSetOperation}).getValue(0);

    System.out.printf("Shared set with ID %d and name '%s' was successfully added.%n",
        sharedSet.getSharedSetId(), sharedSet.getName());

    // Add negative keywords to the shared set.
    List<SharedCriterionOperation> sharedCriterionOperations = new ArrayList<>();
    for (String keyword : keywords) {
      Keyword keywordCriterion = new Keyword();
      keywordCriterion.setText(keyword);
      keywordCriterion.setMatchType(KeywordMatchType.BROAD);

      SharedCriterion sharedCriterion = new SharedCriterion();
      sharedCriterion.setCriterion(keywordCriterion);
      sharedCriterion.setNegative(true);
      sharedCriterion.setSharedSetId(sharedSet.getSharedSetId());

      SharedCriterionOperation sharedCriterionOperation = new SharedCriterionOperation();
      sharedCriterionOperation.setOperator(Operator.ADD);
      sharedCriterionOperation.setOperand(sharedCriterion);

      sharedCriterionOperations.add(sharedCriterionOperation);
    }

    // Get the SharedCriterionService.
    SharedCriterionServiceInterface sharedCriterionService =
        adWordsServices.get(session, SharedCriterionServiceInterface.class);

    SharedCriterionReturnValue sharedCriterionReturnValue =
        sharedCriterionService.mutate(sharedCriterionOperations.toArray(
            new SharedCriterionOperation[sharedCriterionOperations.size()]));

    for (SharedCriterion addedCriterion : sharedCriterionReturnValue.getValue()) {
      System.out.printf("Added shared criterion ID %d with text '%s' to shared set with ID %d.%n",
          addedCriterion.getCriterion().getId(),
          ((Keyword) addedCriterion.getCriterion()).getText(), addedCriterion.getSharedSetId());
    }

    // Attach the negative keyword shared set to the campaign.
    CampaignSharedSetServiceInterface campaignSharedSetService =
        adWordsServices.get(session, CampaignSharedSetServiceInterface.class);

    CampaignSharedSet campaignSharedSet = new CampaignSharedSet();
    campaignSharedSet.setCampaignId(campaignId);
    campaignSharedSet.setSharedSetId(sharedSet.getSharedSetId());

    CampaignSharedSetOperation campaignSharedSetOperation = new CampaignSharedSetOperation();
    campaignSharedSetOperation.setOperator(Operator.ADD);
    campaignSharedSetOperation.setOperand(campaignSharedSet);

    campaignSharedSet = campaignSharedSetService.mutate(
        new CampaignSharedSetOperation[] {campaignSharedSetOperation}).getValue(0);

    System.out.printf("Shared set ID %d was attached to campaign ID %d.%n",
        campaignSharedSet.getSharedSetId(), campaignSharedSet.getCampaignId());
  }
}

Find and remove criteria from a shared set

// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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.

package adwords.axis.v201710.advancedoperations;

import com.beust.jcommander.Parameter;
import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.utils.v201710.SelectorBuilder;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignSharedSet;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignSharedSetPage;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignSharedSetServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.Criterion;
import com.google.api.ads.adwords.axis.v201710.cm.CriterionType;
import com.google.api.ads.adwords.axis.v201710.cm.Keyword;
import com.google.api.ads.adwords.axis.v201710.cm.Operator;
import com.google.api.ads.adwords.axis.v201710.cm.Placement;
import com.google.api.ads.adwords.axis.v201710.cm.SharedCriterion;
import com.google.api.ads.adwords.axis.v201710.cm.SharedCriterionOperation;
import com.google.api.ads.adwords.axis.v201710.cm.SharedCriterionPage;
import com.google.api.ads.adwords.axis.v201710.cm.SharedCriterionReturnValue;
import com.google.api.ads.adwords.axis.v201710.cm.SharedCriterionServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.SharedSetType;
import com.google.api.ads.adwords.lib.client.AdWordsSession;
import com.google.api.ads.adwords.lib.factory.AdWordsServicesInterface;
import com.google.api.ads.adwords.lib.selectorfields.v201710.cm.CampaignSharedSetField;
import com.google.api.ads.adwords.lib.utils.examples.ArgumentNames;
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.utils.examples.CodeSampleParams;
import com.google.api.client.auth.oauth2.Credential;
import com.google.common.base.Functions;
import com.google.common.collect.Collections2;
import java.util.ArrayList;
import java.util.List;

/**
 * This example demonstrates how to find and remove shared sets and shared set criteria.
 *
 * <p>Credentials and properties in {@code fromFile()} are pulled from the
 * "ads.properties" file. See README for more info.
 */
public class FindAndRemoveCriteriaFromSharedSet {

  private static final int PAGE_SIZE = 100;
  
  private static class FindAndRemoveCriteriaFromSharedSetParams extends CodeSampleParams {
    @Parameter(names = ArgumentNames.CAMPAIGN_ID, required = true)
    private Long campaignId;
  }

  public static void main(String[] args) throws Exception {
    // Generate a refreshable OAuth2 credential.
    Credential oAuth2Credential = new OfflineCredentials.Builder()
        .forApi(Api.ADWORDS)
        .fromFile()
        .build()
        .generateCredential();

    // Construct an AdWordsSession.
    AdWordsSession session = new AdWordsSession.Builder()
        .fromFile()
        .withOAuth2Credential(oAuth2Credential)
        .build();

    AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance();

    FindAndRemoveCriteriaFromSharedSetParams params =
        new FindAndRemoveCriteriaFromSharedSetParams();
    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.campaignId = Long.parseLong("INSERT_CAMPAIGN_ID_HERE");
    }

    runExample(adWordsServices, session, params.campaignId);
  }

  public static void runExample(AdWordsServicesInterface adWordsServices, AdWordsSession session,
      Long campaignId) throws Exception {
    // Get the CampaignSharedSetService.
    CampaignSharedSetServiceInterface campaignSharedSetService =
        adWordsServices.get(session, CampaignSharedSetServiceInterface.class);

    // First, retrieve all shared sets associated with the campaign.
    int offset = 0;
    SelectorBuilder selectorBuilder = new SelectorBuilder()
      .fields(
          CampaignSharedSetField.SharedSetId,
          CampaignSharedSetField.CampaignId,
          CampaignSharedSetField.SharedSetName,
          CampaignSharedSetField.SharedSetType)
      .equals(CampaignSharedSetField.CampaignId, campaignId.toString())
      .in(
          CampaignSharedSetField.SharedSetType,
          SharedSetType.NEGATIVE_KEYWORDS.getValue(),
          SharedSetType.NEGATIVE_PLACEMENTS.getValue())
      .limit(PAGE_SIZE);
    
    List<Long> sharedSetIds = new ArrayList<>();
    CampaignSharedSetPage campaignSharedSetPage;
    do {
      selectorBuilder.offset(offset);
      campaignSharedSetPage = campaignSharedSetService.get(selectorBuilder.build());
      for (CampaignSharedSet campaignSharedSet : campaignSharedSetPage.getEntries()) {
        sharedSetIds.add(campaignSharedSet.getSharedSetId());
        System.out.printf("Campaign shared set ID %d and name '%s' found for campaign ID %d.%n",
            campaignSharedSet.getSharedSetId(), campaignSharedSet.getSharedSetName(),
            campaignSharedSet.getCampaignId());
      }
      offset += PAGE_SIZE;
    } while (offset < campaignSharedSetPage.getTotalNumEntries());

    if (sharedSetIds.isEmpty()) {
      System.out.printf("No shared sets found for campaign ID %d.%n", campaignId);
      return;
    }

    // Next, retrieve criterion IDs for all found shared sets.
    SharedCriterionServiceInterface sharedCriterionService =
        adWordsServices.get(session, SharedCriterionServiceInterface.class);

    // Transform shared set IDs to strings.
    String[] sharedSetIdStrings = Collections2.transform(sharedSetIds, Functions.toStringFunction())
        .toArray(new String[sharedSetIds.size()]);
    
    offset = 0;
    selectorBuilder = new SelectorBuilder()
      .fields("SharedSetId", "Id", "KeywordText", "KeywordMatchType", "PlacementUrl")
      .in("SharedSetId", sharedSetIdStrings)
      .limit(PAGE_SIZE);
    
    List<SharedCriterionOperation> removeCriterionOperations = new ArrayList<>();
    SharedCriterionPage sharedCriterionPage;
    do {
      selectorBuilder.offset(offset);
      sharedCriterionPage = sharedCriterionService.get(selectorBuilder.build());
      for (SharedCriterion sharedCriterion : sharedCriterionPage.getEntries()) {
        if (CriterionType.KEYWORD.equals(sharedCriterion.getCriterion().getType())) {
          Keyword keyword = (Keyword) sharedCriterion.getCriterion();
          System.out.printf("Shared negative keyword with ID %d and text '%s' was found.%n",
              keyword.getId(), keyword.getText());
        } else if (CriterionType.PLACEMENT.equals(sharedCriterion.getCriterion().getType())) {
          Placement placement = (Placement) sharedCriterion.getCriterion();
          System.out.printf("Shared negative placement with ID %d and URL '%s' was found.%n",
              placement.getId(), placement.getUrl());
        } else {
          System.out.printf("Shared criterion with ID %d was found.%n",
              sharedCriterion.getCriterion().getId());
        }

        // Create an operation to remove this criterion.
        SharedCriterionOperation removeCriterionOperation = new SharedCriterionOperation();
        removeCriterionOperation.setOperator(Operator.REMOVE);
        
        SharedCriterion sharedCriterionToRemove = new SharedCriterion();
        
        Criterion criterionToRemove = new Criterion();
        criterionToRemove.setId(sharedCriterion.getCriterion().getId());
        
        sharedCriterionToRemove.setCriterion(criterionToRemove);
        sharedCriterionToRemove.setSharedSetId(sharedCriterion.getSharedSetId());
        
        removeCriterionOperation.setOperand(sharedCriterionToRemove);

        removeCriterionOperations.add(removeCriterionOperation);
      }
      offset += PAGE_SIZE;
    } while (offset < sharedCriterionPage.getTotalNumEntries());

    // Finally, remove the criteria.
    if (removeCriterionOperations.isEmpty()) {
      System.out.printf("No shared criteria to remove.%n");
    } else {
      SharedCriterionReturnValue sharedCriterionReturnValue =
          sharedCriterionService.mutate(removeCriterionOperations.toArray(
              new SharedCriterionOperation[removeCriterionOperations.size()]));
      for (SharedCriterion removedCriterion : sharedCriterionReturnValue.getValue()) {
        System.out.printf(
            "Shared criterion ID %d was successfully removed from shared set ID %d.%n",
            removedCriterion.getCriterion().getId(), removedCriterion.getSharedSetId());
      }
    }
  }
}

Get ad group bid modifiers

// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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.

package adwords.axis.v201710.advancedoperations;

import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.utils.v201710.SelectorBuilder;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupBidModifier;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupBidModifierPage;
import com.google.api.ads.adwords.axis.v201710.cm.AdGroupBidModifierServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.Selector;
import com.google.api.ads.adwords.lib.client.AdWordsSession;
import com.google.api.ads.adwords.lib.factory.AdWordsServicesInterface;
import com.google.api.ads.adwords.lib.selectorfields.v201710.cm.AdGroupBidModifierField;
import com.google.api.ads.common.lib.auth.OfflineCredentials;
import com.google.api.ads.common.lib.auth.OfflineCredentials.Api;
import com.google.api.client.auth.oauth2.Credential;

/**
 * This example illustrates how to retrieve the first 10 ad group level bid modifiers.
 *
 * <p>Credentials and properties in {@code fromFile()} are pulled from the
 * "ads.properties" file. See README for more info.
 */
public class GetAdGroupBidModifier {

  private static final int PAGE_SIZE = 10;

  public static void main(String[] args) throws Exception {
    // Generate a refreshable OAuth2 credential.
    Credential oAuth2Credential = new OfflineCredentials.Builder()
        .forApi(Api.ADWORDS)
        .fromFile()
        .build()
        .generateCredential();

    // Construct an AdWordsSession.
    AdWordsSession session = new AdWordsSession.Builder()
        .fromFile()
        .withOAuth2Credential(oAuth2Credential)
        .build();

    AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance();

    runExample(adWordsServices, session);
  }

  public static void runExample(AdWordsServicesInterface adWordsServices,
      AdWordsSession session) throws Exception {
    // Get the AdGroupBidModifierService.
    AdGroupBidModifierServiceInterface adGroupBidModifierService =
        adWordsServices.get(session, AdGroupBidModifierServiceInterface.class);

    // Create selector.
    Selector selector = new SelectorBuilder()
        .fields(
            AdGroupBidModifierField.CampaignId,
            AdGroupBidModifierField.AdGroupId,
            AdGroupBidModifierField.BidModifier,
            AdGroupBidModifierField.Id)
        .offset(0)
        .limit(PAGE_SIZE)
        .build();

    AdGroupBidModifierPage page = adGroupBidModifierService.get(selector);
    if (page.getEntries() != null) {
      for (AdGroupBidModifier bidModifierResult : page.getEntries()) {
        String bidModifierValue =
            bidModifierResult.getBidModifier() != null
                ? bidModifierResult.getBidModifier().toString()
                : "unset";
        System.out.printf("Campaign ID %d, AdGroup ID %d, Criterion ID %d, "
            + "has ad group level modifier: %s%n",
            bidModifierResult.getCampaignId(),
            bidModifierResult.getAdGroupId(),
            bidModifierResult.getCriterion().getId(),
            bidModifierValue);
      }
    } else {
      System.out.println("No ad group level bid modifiers were found.");
    }
  }
}

Use a portfolio bidding strategy

// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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.

package adwords.axis.v201710.advancedoperations;

import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.v201710.cm.AdvertisingChannelType;
import com.google.api.ads.adwords.axis.v201710.cm.ApiException;
import com.google.api.ads.adwords.axis.v201710.cm.BiddingStrategyConfiguration;
import com.google.api.ads.adwords.axis.v201710.cm.BiddingStrategyOperation;
import com.google.api.ads.adwords.axis.v201710.cm.BiddingStrategyReturnValue;
import com.google.api.ads.adwords.axis.v201710.cm.BiddingStrategyServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.Budget;
import com.google.api.ads.adwords.axis.v201710.cm.BudgetBudgetDeliveryMethod;
import com.google.api.ads.adwords.axis.v201710.cm.BudgetOperation;
import com.google.api.ads.adwords.axis.v201710.cm.BudgetReturnValue;
import com.google.api.ads.adwords.axis.v201710.cm.BudgetServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.Campaign;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignOperation;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignReturnValue;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignServiceInterface;
import com.google.api.ads.adwords.axis.v201710.cm.CampaignStatus;
import com.google.api.ads.adwords.axis.v201710.cm.Money;
import com.google.api.ads.adwords.axis.v201710.cm.NetworkSetting;
import com.google.api.ads.adwords.axis.v201710.cm.Operator;
import com.google.api.ads.adwords.axis.v201710.cm.SharedBiddingStrategy;
import com.google.api.ads.adwords.axis.v201710.cm.TargetSpendBiddingScheme;
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.client.auth.oauth2.Credential;
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;

/**
 * This example adds a portfolio bidding strategy and uses it to construct a campaign.
 */
public class UsePortfolioBiddingStrategy {

  // Optional: If you'd like to use an existing shared budget, assign a
  //           shared budget ID here.
  private static final Long SHARED_BUDGET_ID = null; 
  
  public static void main(String[] args) throws Exception {
    Credential oAuth2Credential = new OfflineCredentials.Builder()
        .forApi(Api.ADWORDS)
        .fromFile()
        .build()
        .generateCredential();

    // Construct an AdWordsSession.
    AdWordsSession session = new AdWordsSession.Builder()
        .fromFile()
        .withOAuth2Credential(oAuth2Credential)
        .build();

    AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance();

    runExample(adWordsServices, session, SHARED_BUDGET_ID);
  }

  public static void runExample(AdWordsServicesInterface adWordsServices, AdWordsSession session,
      Long sharedBudgetId) throws Exception {
    SharedBiddingStrategy portfolioBiddingStrategy =
        createBiddingStrategy(adWordsServices, session);
    if (sharedBudgetId == null) {
      Budget budget = createSharedBudget(adWordsServices, session);
      sharedBudgetId = budget.getBudgetId();
    }
    createCampaignWithBiddingStrategy(adWordsServices, session, portfolioBiddingStrategy.getId(), 
        sharedBudgetId);
  }

  /**
   * Creates the bidding strategy object.
   *
   * @param adWordsServices the user to run the example with
   * @param session the AdWordsSession
   * @throws RemoteException
   * @throws ApiException
   * @throws ServiceException
   */
  private static SharedBiddingStrategy createBiddingStrategy(
      AdWordsServicesInterface adWordsServices, AdWordsSession session)
      throws ApiException, RemoteException, ServiceException {
    // Get the BiddingStrategyService, which loads the required classes.
    BiddingStrategyServiceInterface biddingStrategyService =
        adWordsServices.get(session, BiddingStrategyServiceInterface.class);

    // Create a portfolio bidding strategy.
    SharedBiddingStrategy portfolioBiddingStrategy = new SharedBiddingStrategy();
    portfolioBiddingStrategy.setName("Maximize Clicks" + System.currentTimeMillis());

    TargetSpendBiddingScheme biddingScheme = new TargetSpendBiddingScheme();
    // Optionally set additional bidding scheme parameters.
    biddingScheme.setBidCeiling(new Money(null, 2000000L));
    biddingScheme.setSpendTarget(new Money(null, 20000000L));

    portfolioBiddingStrategy.setBiddingScheme(biddingScheme);

    // Create operation.
    BiddingStrategyOperation operation = new BiddingStrategyOperation();
    operation.setOperand(portfolioBiddingStrategy);
    operation.setOperator(Operator.ADD);

    BiddingStrategyOperation[] operations = new BiddingStrategyOperation[] {operation};
    BiddingStrategyReturnValue result = biddingStrategyService.mutate(operations);

    SharedBiddingStrategy newBiddingStrategy = result.getValue(0);

    System.out.printf(
        "Portfolio bidding strategy with name '%s' and ID %d of type '%s' was created.%n",
        newBiddingStrategy.getName(), newBiddingStrategy.getId(),
        newBiddingStrategy.getBiddingScheme().getBiddingSchemeType());

    return newBiddingStrategy;
  }

  /**
   * Creates an explicit budget to be used only to create the Campaign.
   *
   * @param adWordsServices the user to run the example with
   * @param session the AdWordsSession
   * @throws ServiceException
   * @throws RemoteException
   * @throws ApiException
   */
  private static Budget createSharedBudget(AdWordsServicesInterface adWordsServices,
      AdWordsSession session)
      throws ServiceException, ApiException, RemoteException {
    // Get the BudgetService, which loads the required classes.
    BudgetServiceInterface budgetService =
        adWordsServices.get(session, BudgetServiceInterface.class);

    // Create a shared budget.
    Budget budget = new Budget();
    budget.setName("Shared Interplanetary Budget #" + System.currentTimeMillis());
    budget.setAmount(new Money(null, 50000000L));
    budget.setDeliveryMethod(BudgetBudgetDeliveryMethod.STANDARD);
    budget.setIsExplicitlyShared(true);

    BudgetOperation operation = new BudgetOperation();
    operation.setOperand(budget);
    operation.setOperator(Operator.ADD);

    BudgetOperation[] operations = new BudgetOperation[] {operation};

    // Make the mutate request.
    BudgetReturnValue result = budgetService.mutate(operations);
    Budget newBudget = result.getValue(0);

    System.out.printf("Budget with name '%s', ID %d was created.%n", newBudget.getName(),
        newBudget.getBudgetId());

    return newBudget;
  }

  /**
   * Create a Campaign with a portfolio bidding strategy.
   *
   * @param adWordsServices the user to run the example with
   * @param session the AdWordsSession
   * @param biddingStrategyId the bidding strategy id to use
   * @param sharedBudgetId the shared budget id to use
   * @throws RemoteException
   * @throws ApiException
   * @throws ServiceException
   */
  private static Campaign createCampaignWithBiddingStrategy(
      AdWordsServicesInterface adWordsServices, AdWordsSession session, Long biddingStrategyId,
      Long sharedBudgetId) throws ApiException, RemoteException, ServiceException {
    // Get the CampaignService, which loads the required classes.
    CampaignServiceInterface campaignService =
        adWordsServices.get(session, CampaignServiceInterface.class);

    // Create 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);

    // Set the budget.
    Budget budget = new Budget();
    budget.setBudgetId(sharedBudgetId);
    campaign.setBudget(budget);

    // Set bidding strategy (required).
    BiddingStrategyConfiguration biddingStrategyConfiguration = new BiddingStrategyConfiguration();
    biddingStrategyConfiguration.setBiddingStrategyId(biddingStrategyId);

    campaign.setBiddingStrategyConfiguration(biddingStrategyConfiguration);

    // Set advertising channel type (required).
    campaign.setAdvertisingChannelType(AdvertisingChannelType.SEARCH);

    // Set network targeting (recommended).
    NetworkSetting networkSetting = new NetworkSetting();
    networkSetting.setTargetGoogleSearch(true);
    networkSetting.setTargetSearchNetwork(true);
    networkSetting.setTargetContentNetwork(true);
    campaign.setNetworkSetting(networkSetting);

    // Create operation.
    CampaignOperation operation = new CampaignOperation();
    operation.setOperand(campaign);
    operation.setOperator(Operator.ADD);

    CampaignReturnValue result = campaignService.mutate(new CampaignOperation[] {operation});
    Campaign newCampaign = result.getValue(0);

    System.out.printf("Campaign with name '%s', ID %d and bidding scheme ID %d was created.%n",
        newCampaign.getName(), newCampaign.getId(),
        newCampaign.getBiddingStrategyConfiguration().getBiddingStrategyId());

    return newCampaign;
  }
}

Send feedback about...

AdWords API
AdWords API
Need help? Visit our support page.