Extensions Samples

The code samples below provide examples of common extension functions using the AdWords API. Client Library.

Add Google My Business location extensions

// 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.v201705.extensions;

import adwords.axis.auth.GetRefreshToken;
import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.v201705.cm.ApiException;
import com.google.api.ads.adwords.axis.v201705.cm.ConstantOperand;
import com.google.api.ads.adwords.axis.v201705.cm.ConstantOperandConstantType;
import com.google.api.ads.adwords.axis.v201705.cm.CustomerFeed;
import com.google.api.ads.adwords.axis.v201705.cm.CustomerFeedOperation;
import com.google.api.ads.adwords.axis.v201705.cm.CustomerFeedReturnValue;
import com.google.api.ads.adwords.axis.v201705.cm.CustomerFeedServiceInterface;
import com.google.api.ads.adwords.axis.v201705.cm.Feed;
import com.google.api.ads.adwords.axis.v201705.cm.FeedOperation;
import com.google.api.ads.adwords.axis.v201705.cm.FeedOrigin;
import com.google.api.ads.adwords.axis.v201705.cm.FeedReturnValue;
import com.google.api.ads.adwords.axis.v201705.cm.FeedServiceInterface;
import com.google.api.ads.adwords.axis.v201705.cm.Function;
import com.google.api.ads.adwords.axis.v201705.cm.FunctionArgumentOperand;
import com.google.api.ads.adwords.axis.v201705.cm.FunctionOperator;
import com.google.api.ads.adwords.axis.v201705.cm.OAuthInfo;
import com.google.api.ads.adwords.axis.v201705.cm.Operator;
import com.google.api.ads.adwords.axis.v201705.cm.PlacesLocationFeedData;
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.annotation.Nullable;

/**
 * This example adds a feed that syncs feed items from a Google
 * My Business (GMB) account and associates the feed with a customer.
 *
 * <p>Credentials and properties in {@code fromFile()} are pulled from
 * the "ads.properties" file. See README for more info.
 */
public class AddGoogleMyBusinessLocationExtensions {

  /**
   * The placeholder type for location extensions.
   *
   * <p>See the Placeholder reference page for a list of all the placeholder types and fields.
   * https://developers.google.com/adwords/api/docs/appendix/placeholders
   */
  private static final int PLACEHOLDER_LOCATION = 7;

  /**
   * The maximum number of CustomerFeed ADD operation attempts to make before throwing
   * an exception.
   */
  private static final int MAX_CUSTOMER_FEED_ADD_ATTEMPTS = 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();

    // The email address of either an owner or a manager of the GMB account.
    String gmbEmailAddress = "INSERT_GMB_EMAIL_ADDRESS_HERE";

    // If the gmbEmailAddress above is the same user you used to generate your AdWords API
    // refresh token, leave the assignment below unchanged.
    // Otherwise, to obtain an access token for your GMB account, run the GetRefreshToken example.
    // Make sure you are logged in as the same user as gmbEmailAddress above when you follow the
    // link provided by the example, then call Credential.getAccessToken() on the generated
    // Credential object and copy and paste the value into the assignment below.
    String gmbAccessToken = oAuth2Credential.getAccessToken();

    // If the gmbEmailAddress above is for a GMB manager instead of the GMB account owner,
    // then set businessAccountIdentifier to the +Page ID of a location for which the
    // manager has access. See the location extensions guide at
    // https://developers.google.com/adwords/api/docs/guides/feed-services-locations
    // for details.
    String businessAccountIdentifier = null;
    
    runExample(adWordsServices, session, gmbEmailAddress, gmbAccessToken,
        businessAccountIdentifier);
  }

  private static void runExample(AdWordsServicesInterface adWordsServices, AdWordsSession session,
      String gmbEmailAddress, String gmbAccessToken, @Nullable String businessAccountIdentifier)
      throws ApiException, RemoteException, InterruptedException {

    FeedServiceInterface feedService = adWordsServices.get(session, FeedServiceInterface.class);

    // Create a feed that will sync to the Google My Business account specified
    // by gmbEmailAddress. Do not add FeedAttributes to this object,
    // as AdWords will add them automatically because this will be a
    // system generated feed.
    Feed gmbFeed = new Feed();
    gmbFeed.setName("Google My Business feed #" + System.currentTimeMillis());

    PlacesLocationFeedData feedData = new PlacesLocationFeedData();
    feedData.setEmailAddress(gmbEmailAddress);
    feedData.setBusinessAccountIdentifier(businessAccountIdentifier);
    
    // Optional: specify labels to filter Google My Business listings. If
    // specified, only listings that have any of the labels set are
    // synchronized into FeedItems.
    feedData.setLabelFilters(new String[] {"Stores in New York City"});

    OAuthInfo oAuthInfo = new OAuthInfo();
    oAuthInfo.setHttpMethod("GET");
    oAuthInfo.setHttpRequestUrl(GetRefreshToken.ADWORDS_API_SCOPE);
    oAuthInfo.setHttpAuthorizationHeader(String.format("Bearer %s", gmbAccessToken));
    
    feedData.setOAuthInfo(oAuthInfo);

    gmbFeed.setSystemFeedGenerationData(feedData);
    
    // Since this feed's feed items will be managed by AdWords,
    // you must set its origin to ADWORDS.
    gmbFeed.setOrigin(FeedOrigin.ADWORDS);

    // Create an operation to add the feed.
    FeedOperation feedOperation = new FeedOperation();
    feedOperation.setOperand(gmbFeed);
    feedOperation.setOperator(Operator.ADD);

    // Add the feed. Since it is a system generated feed, AdWords will automatically:
    // 1. Set up the FeedAttributes on the feed.
    // 2. Set up a FeedMapping that associates the FeedAttributes of the feed
    // with the placeholder fields of the LOCATION placeholder type.
    FeedReturnValue addFeedResult = feedService.mutate(new FeedOperation[] {feedOperation});
    Feed addedFeed = addFeedResult.getValue(0);
    System.out.printf("Added GMB feed with ID %d%n", addedFeed.getId());

    // Add a CustomerFeed that associates the feed with this customer for
    // the LOCATION placeholder type.
    CustomerFeed customerFeed = new CustomerFeed();
    customerFeed.setFeedId(addedFeed.getId());
    customerFeed.setPlaceholderTypes(new int[] {PLACEHOLDER_LOCATION});

    // Create a matching function that will always evaluate to true.
    Function customerMatchingFunction = new Function();
    ConstantOperand constOperand = new ConstantOperand();
    constOperand.setType(ConstantOperandConstantType.BOOLEAN);
    constOperand.setBooleanValue(true);
    customerMatchingFunction.setLhsOperand(new FunctionArgumentOperand[] {constOperand});
    customerMatchingFunction.setOperator(FunctionOperator.IDENTITY);
    customerFeed.setMatchingFunction(customerMatchingFunction);

    // Create an operation to add the customer feed.
    CustomerFeedOperation customerFeedOperation = new CustomerFeedOperation();
    customerFeedOperation.setOperand(customerFeed);
    customerFeedOperation.setOperator(Operator.ADD);

    CustomerFeedServiceInterface customerFeedService =
        adWordsServices.get(session, CustomerFeedServiceInterface.class);

    // After the completion of the Feed ADD operation above the added feed will not be available
    // for usage in a CustomerFeed until the sync between the AdWords and GMB accounts
    // completes. The loop below will retry adding the CustomerFeed up to ten times with an
    // exponential back-off policy.
    CustomerFeed addedCustomerFeed = null;
    int numberOfAttempts = 0;
    do {
      numberOfAttempts++;
      try {
        CustomerFeedReturnValue customerFeedResult =
            customerFeedService.mutate(new CustomerFeedOperation[] {customerFeedOperation});
        addedCustomerFeed = customerFeedResult.getValue(0);
        System.out.printf("Attempt #%d to add the CustomerFeed was successful%n", numberOfAttempts);
      } catch (Exception e) {
        // Wait using exponential backoff policy
        long sleepSeconds = (long) Math.scalb(5, numberOfAttempts);
        System.out.printf("Attempt #%d to add the CustomerFeed was not successful. "
            + "Waiting %d seconds before trying again.%n", numberOfAttempts, sleepSeconds);
        Thread.sleep(sleepSeconds * 1000);
      }
    } while (numberOfAttempts < MAX_CUSTOMER_FEED_ADD_ATTEMPTS && addedCustomerFeed == null);

    if (addedCustomerFeed == null) {
      throw new RuntimeException("Could not create the CustomerFeed after "
          + MAX_CUSTOMER_FEED_ADD_ATTEMPTS + " attempts. Please retry "
          + "the CustomerFeed ADD operation later.");
    }

    System.out.printf("Added CustomerFeed for feed ID %d and placeholder type %d%n",
        addedCustomerFeed.getFeedId(), addedCustomerFeed.getPlaceholderTypes()[0]);

    // OPTIONAL: Create a CampaignFeed to specify which FeedItems to use at the Campaign
    // level. This will be similar to the CampaignFeed in the AddSiteLinks example, except
    // you can also filter based on the business name and category of each FeedItem
    // by using a FeedAttributeOperand in your matching function.

    // OPTIONAL: Create an AdGroupFeed for even more fine grained control over
    // which feed items are used at the AdGroup level.
  }
}

Add prices

// 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.v201705.extensions;

import adwords.axis.v201705.basicoperations.AddCampaigns;
import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.v201705.cm.ApiException;
import com.google.api.ads.adwords.axis.v201705.cm.CustomerExtensionSetting;
import com.google.api.ads.adwords.axis.v201705.cm.CustomerExtensionSettingOperation;
import com.google.api.ads.adwords.axis.v201705.cm.CustomerExtensionSettingReturnValue;
import com.google.api.ads.adwords.axis.v201705.cm.CustomerExtensionSettingServiceInterface;
import com.google.api.ads.adwords.axis.v201705.cm.DayOfWeek;
import com.google.api.ads.adwords.axis.v201705.cm.ExtensionFeedItem;
import com.google.api.ads.adwords.axis.v201705.cm.ExtensionSetting;
import com.google.api.ads.adwords.axis.v201705.cm.FeedItemCampaignTargeting;
import com.google.api.ads.adwords.axis.v201705.cm.FeedItemSchedule;
import com.google.api.ads.adwords.axis.v201705.cm.FeedItemScheduling;
import com.google.api.ads.adwords.axis.v201705.cm.FeedType;
import com.google.api.ads.adwords.axis.v201705.cm.MinuteOfHour;
import com.google.api.ads.adwords.axis.v201705.cm.Money;
import com.google.api.ads.adwords.axis.v201705.cm.MoneyWithCurrency;
import com.google.api.ads.adwords.axis.v201705.cm.Operator;
import com.google.api.ads.adwords.axis.v201705.cm.PriceExtensionPriceQualifier;
import com.google.api.ads.adwords.axis.v201705.cm.PriceExtensionPriceUnit;
import com.google.api.ads.adwords.axis.v201705.cm.PriceExtensionType;
import com.google.api.ads.adwords.axis.v201705.cm.PriceFeedItem;
import com.google.api.ads.adwords.axis.v201705.cm.PriceTableRow;
import com.google.api.ads.adwords.axis.v201705.cm.UrlList;
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.List;

/**
 * This example adds a price extension and associates it with an account. Campaign targeting is
 * also set using the specified campaign ID.
 *
 * <p>To get campaigns, run {@link AddCampaigns}.
 *
 * <p>Credentials and properties in {@code fromFile()} are pulled from the
 * "ads.properties" file. See README for more info.
 */
public class AddPrices {

  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();

    Long campaignId = Long.valueOf("INSERT_CAMPAIGN_ID_HERE");

    runExample(adWordsServices, session, campaignId);
  }

  public static void runExample(
      AdWordsServicesInterface adWordsServices, AdWordsSession session, Long campaignId)
      throws ApiException, RemoteException {
    // Get the CustomerExtensionSettingService.
    CustomerExtensionSettingServiceInterface customerExtensionSettingService =
        adWordsServices.get(session, CustomerExtensionSettingServiceInterface.class);

    // Create the price extension feed item.
    PriceFeedItem priceFeedItem = new PriceFeedItem();
    priceFeedItem.setPriceExtensionType(PriceExtensionType.SERVICES);

    // Price qualifier is optional.
    priceFeedItem.setPriceQualifier(PriceExtensionPriceQualifier.FROM);
    priceFeedItem.setTrackingUrlTemplate("http://tracker.example.com/?u={lpurl}");
    priceFeedItem.setLanguage("en");
    FeedItemCampaignTargeting campaignTargeting = new FeedItemCampaignTargeting();
    campaignTargeting.setTargetingCampaignId(campaignId);
    priceFeedItem.setCampaignTargeting(campaignTargeting);
    priceFeedItem.setScheduling(
        new FeedItemScheduling(
            new FeedItemSchedule[] {
              new FeedItemSchedule(DayOfWeek.SUNDAY, 10, MinuteOfHour.ZERO, 18, MinuteOfHour.ZERO),
              new FeedItemSchedule(DayOfWeek.SATURDAY, 10, MinuteOfHour.ZERO, 22, MinuteOfHour.ZERO)
            }));

    // To create a price extension, at least three table rows are needed.
    List<PriceTableRow> priceTableRows = new ArrayList<>();
    String currencyCode = "USD";
    priceTableRows.add(
        createPriceTableRow(
            "Scrubs",
            "Body Scrub, Salt Scrub",
            "http://www.example.com/scrubs",
            "http://m.example.com/scrubs",
            60000000,
            currencyCode,
            PriceExtensionPriceUnit.PER_HOUR));
    priceTableRows.add(
        createPriceTableRow(
            "Hair Cuts",
            "Once a month",
            "http://www.example.com/haircuts",
            "http://m.example.com/haircuts",
            75000000,
            currencyCode,
            PriceExtensionPriceUnit.PER_MONTH));
    priceTableRows.add(
        createPriceTableRow(
            "Skin Care Package",
            "Four times a month",
            "http://www.example.com/skincarepackage",
            null,
            250000000,
            currencyCode,
            PriceExtensionPriceUnit.PER_MONTH));
    priceFeedItem.setTableRows(priceTableRows.toArray(new PriceTableRow[priceTableRows.size()]));

    // Create your campaign extension settings. This associates the sitelinks
    // to your campaign.
    CustomerExtensionSetting customerExtensionSetting = new CustomerExtensionSetting();
    customerExtensionSetting.setExtensionType(FeedType.PRICE);
    ExtensionSetting extensionSetting = new ExtensionSetting();
    extensionSetting.setExtensions(new ExtensionFeedItem[] {priceFeedItem});
    customerExtensionSetting.setExtensionSetting(extensionSetting);

    CustomerExtensionSettingOperation operation = new CustomerExtensionSettingOperation();
    operation.setOperand(customerExtensionSetting);
    operation.setOperator(Operator.ADD);

    // Add the extensions.
    CustomerExtensionSettingReturnValue returnValue =
        customerExtensionSettingService.mutate(new CustomerExtensionSettingOperation[] {operation});
    if (returnValue.getValue() != null && returnValue.getValue().length > 0) {
      CustomerExtensionSetting newExtensionSetting = returnValue.getValue(0);
      System.out.printf(
          "Extension setting with type '%s' was added.%n",
          newExtensionSetting.getExtensionType().getValue());
    } else {
      System.out.println("No extension settings were created.");
    }
  }

  /**
   * Creates a new {@link PriceTableRow} with the specified attributes.
   *
   * @param header the header for the row
   * @param description the description for the row
   * @param finalUrl the final URL for the row
   * @param finalMobileUrl the final mobile URL for the row, or null if this field should not be set
   * @param priceInMicros the price for the row, in micros
   * @param currencyCode the currency for the row
   * @param priceUnit the price unit for the row
   * @return a new {@link PriceTableRow}
   */
  private static PriceTableRow createPriceTableRow(
      String header,
      String description,
      String finalUrl,
      String finalMobileUrl,
      long priceInMicros,
      String currencyCode,
      PriceExtensionPriceUnit priceUnit) {
    PriceTableRow priceTableRow = new PriceTableRow();
    priceTableRow.setHeader(header);
    priceTableRow.setDescription(description);

    UrlList finalUrls = new UrlList();
    finalUrls.setUrls(new String[] {finalUrl});
    priceTableRow.setFinalUrls(finalUrls);

    if (finalMobileUrl != null) {
      UrlList finalMobileUrls = new UrlList();
      finalMobileUrls.setUrls(new String[] {finalMobileUrl});
      priceTableRow.setFinalMobileUrls(finalMobileUrls);
    }

    MoneyWithCurrency price = new MoneyWithCurrency();
    Money priceMoney = new Money();
    price.setCurrencyCode(currencyCode);
    priceMoney.setMicroAmount(priceInMicros);
    price.setMoney(priceMoney);
    priceTableRow.setPrice(price);
    priceTableRow.setPriceUnit(priceUnit);

    return priceTableRow;
  }

}

Add sitelinks to a 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.v201705.extensions;

import adwords.axis.v201705.basicoperations.AddCampaigns;
import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.v201705.cm.ApiException;
import com.google.api.ads.adwords.axis.v201705.cm.CampaignExtensionSetting;
import com.google.api.ads.adwords.axis.v201705.cm.CampaignExtensionSettingOperation;
import com.google.api.ads.adwords.axis.v201705.cm.CampaignExtensionSettingReturnValue;
import com.google.api.ads.adwords.axis.v201705.cm.CampaignExtensionSettingServiceInterface;
import com.google.api.ads.adwords.axis.v201705.cm.DayOfWeek;
import com.google.api.ads.adwords.axis.v201705.cm.ExtensionFeedItem;
import com.google.api.ads.adwords.axis.v201705.cm.ExtensionSetting;
import com.google.api.ads.adwords.axis.v201705.cm.FeedItemDevicePreference;
import com.google.api.ads.adwords.axis.v201705.cm.FeedItemGeoRestriction;
import com.google.api.ads.adwords.axis.v201705.cm.FeedItemSchedule;
import com.google.api.ads.adwords.axis.v201705.cm.FeedItemScheduling;
import com.google.api.ads.adwords.axis.v201705.cm.FeedType;
import com.google.api.ads.adwords.axis.v201705.cm.GeoRestriction;
import com.google.api.ads.adwords.axis.v201705.cm.Keyword;
import com.google.api.ads.adwords.axis.v201705.cm.KeywordMatchType;
import com.google.api.ads.adwords.axis.v201705.cm.Location;
import com.google.api.ads.adwords.axis.v201705.cm.MinuteOfHour;
import com.google.api.ads.adwords.axis.v201705.cm.Operator;
import com.google.api.ads.adwords.axis.v201705.cm.SitelinkFeedItem;
import com.google.api.ads.adwords.axis.v201705.cm.UrlList;
import com.google.api.ads.adwords.axis.v201705.mcm.Customer;
import com.google.api.ads.adwords.axis.v201705.mcm.CustomerServiceInterface;
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;
import org.joda.time.DateTimeZone;

/**
 * This example adds sitelinks to a campaign. To create a campaign, run {@link AddCampaigns}.
 *
 * <p>Credentials and properties in {@code fromFile()} are pulled from the
 * "ads.properties" file. See README for more info.
 */
public class AddSiteLinks {

  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();

    Long campaignId = Long.valueOf("INSERT_CAMPAIGN_ID_HERE");

    runExample(adWordsServices, session, campaignId);
  }

  public static void runExample(AdWordsServicesInterface adWordsServices, AdWordsSession session,
      Long campaignId) throws ApiException, RemoteException {
    // Get the CustomerService.
    CustomerServiceInterface customerService =
        adWordsServices.get(session, CustomerServiceInterface.class);

    // Find the matching customer and its time zone. The getCustomers method will return
    // a single Customer object corresponding to the session's clientCustomerId.
    Customer customer = customerService.getCustomers()[0];
    DateTimeZone customerTimeZone = DateTimeZone.forID(customer.getDateTimeZone());
    System.out.printf(
        "Found customer ID %d with time zone '%s'.%n",
        customer.getCustomerId(), customer.getDateTimeZone());

    // Get the CampaignExtensionSettingService.
    CampaignExtensionSettingServiceInterface campaignExtensionSettingService =
        adWordsServices.get(session, CampaignExtensionSettingServiceInterface.class);

    // Create the sitelinks.
    SitelinkFeedItem sitelink1 =
        createSiteLinkFeedItem("Store Hours", "http://www.example.com/storehours");

    // Show the Thanksgiving specials link only from 20 - 27 Nov.
    SitelinkFeedItem sitelink2 =
        createSiteLinkFeedItem("Thanksgiving Specials", "http://www.example.com/thanksgiving");

    // The time zone of the start and end date/times must match the time zone of the customer.
    DateTime startTime = new DateTime(DateTime.now().getYear(), 11, 20, 0, 0, 0, customerTimeZone);
    if (startTime.isBeforeNow()) {
      // Move the startTime to next year if the current date is past November 20th.
      startTime = startTime.plusYears(1);
    }
    sitelink2.setStartTime(startTime.toString("yyyyMMdd HHmmss ZZZ"));
    // Use the same year as startTime when creating endTime.
    DateTime endTime = new DateTime(startTime.getYear(), 11, 27, 23, 59, 59, customerTimeZone);
    sitelink2.setEndTime(endTime.toString("yyyyMMdd HHmmss ZZZ"));

    // Target this sitelink for United States only. See
    // https://developers.google.com/adwords/api/docs/appendix/geotargeting
    // for valid geolocation codes.
    Location unitedStates = new Location();
    unitedStates.setId(2840L);
    sitelink2.setGeoTargeting(unitedStates);

    // Restrict targeting only to people physically within the United States.
    // Otherwise, this could also show to people interested in the United States
    // but not physically located there.
    FeedItemGeoRestriction geoTargetingRestriction = new FeedItemGeoRestriction();
    geoTargetingRestriction.setGeoRestriction(GeoRestriction.LOCATION_OF_PRESENCE);
    sitelink2.setGeoTargetingRestriction(geoTargetingRestriction);

    // Show the wifi details primarily for high end mobile users.
    SitelinkFeedItem sitelink3 =
        createSiteLinkFeedItem("Wifi available", "http://www.example.com/mobile/wifi");
    // See https://developers.google.com/adwords/api/docs/appendix/platforms for device criteria
    // IDs.
    FeedItemDevicePreference devicePreference = new FeedItemDevicePreference(30001L);
    sitelink3.setDevicePreference(devicePreference);

    // Target this sitelink for the keyword "free wifi".
    Keyword wifiKeyword = new Keyword();
    wifiKeyword.setText("free wifi");
    wifiKeyword.setMatchType(KeywordMatchType.BROAD);
    sitelink3.setKeywordTargeting(wifiKeyword);

    // Show the happy hours link only during Mon - Fri 6PM to 9PM.
    SitelinkFeedItem sitelink4 =
        createSiteLinkFeedItem("Happy hours", "http://www.example.com/happyhours");
    sitelink4.setScheduling(new FeedItemScheduling(new FeedItemSchedule[] {
        new FeedItemSchedule(DayOfWeek.MONDAY, 18, MinuteOfHour.ZERO, 21, MinuteOfHour.ZERO),
        new FeedItemSchedule(DayOfWeek.TUESDAY, 18, MinuteOfHour.ZERO, 21, MinuteOfHour.ZERO),
        new FeedItemSchedule(DayOfWeek.WEDNESDAY, 18, MinuteOfHour.ZERO, 21, MinuteOfHour.ZERO),
        new FeedItemSchedule(DayOfWeek.THURSDAY, 18, MinuteOfHour.ZERO, 21, MinuteOfHour.ZERO),
        new FeedItemSchedule(DayOfWeek.FRIDAY, 18, MinuteOfHour.ZERO, 21, MinuteOfHour.ZERO)}));

    // Create your campaign extension settings. This associates the sitelinks
    // to your campaign.
    CampaignExtensionSetting campaignExtensionSetting = new CampaignExtensionSetting();
    campaignExtensionSetting.setCampaignId(campaignId);
    campaignExtensionSetting.setExtensionType(FeedType.SITELINK);
    ExtensionSetting extensionSetting = new ExtensionSetting();
    extensionSetting.setExtensions(
        new ExtensionFeedItem[] {sitelink1, sitelink2, sitelink3, sitelink4});
    campaignExtensionSetting.setExtensionSetting(extensionSetting);

    CampaignExtensionSettingOperation operation = new CampaignExtensionSettingOperation();
    operation.setOperand(campaignExtensionSetting);
    operation.setOperator(Operator.ADD);

    // Add the extensions.
    CampaignExtensionSettingReturnValue returnValue =
        campaignExtensionSettingService.mutate(new CampaignExtensionSettingOperation[] {operation});
    if (returnValue.getValue() != null && returnValue.getValue().length > 0) {
      CampaignExtensionSetting newExtensionSetting = returnValue.getValue(0);
      System.out.printf("Extension setting with type '%s' was added to campaign ID %d.%n",
          newExtensionSetting.getExtensionType().getValue(), newExtensionSetting.getCampaignId());
    } else {
      System.out.println("No extension settings were created.");
    }
  }

  /**
   * Creates a new {@link SitelinkFeedItem} with the specified attributes.
   *
   * @param sitelinkText the text for the sitelink
   * @param sitelinkUrl the URL for the sitelink
   * @return a new SitelinkFeedItem
   */
  private static SitelinkFeedItem createSiteLinkFeedItem(String sitelinkText, String sitelinkUrl) {
    SitelinkFeedItem sitelinkFeedItem = new SitelinkFeedItem();
    sitelinkFeedItem.setSitelinkText(sitelinkText);
    sitelinkFeedItem.setSitelinkFinalUrls(new UrlList(new String[] {sitelinkUrl}));
    return sitelinkFeedItem;
  }

}

Add sitelinks to a campaign using feeds

// 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.v201705.extensions;

import adwords.axis.v201705.basicoperations.AddCampaigns;
import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.v201705.cm.AttributeFieldMapping;
import com.google.api.ads.adwords.axis.v201705.cm.CampaignFeed;
import com.google.api.ads.adwords.axis.v201705.cm.CampaignFeedOperation;
import com.google.api.ads.adwords.axis.v201705.cm.CampaignFeedReturnValue;
import com.google.api.ads.adwords.axis.v201705.cm.CampaignFeedServiceInterface;
import com.google.api.ads.adwords.axis.v201705.cm.Feed;
import com.google.api.ads.adwords.axis.v201705.cm.FeedAttribute;
import com.google.api.ads.adwords.axis.v201705.cm.FeedAttributeType;
import com.google.api.ads.adwords.axis.v201705.cm.FeedItem;
import com.google.api.ads.adwords.axis.v201705.cm.FeedItemAttributeValue;
import com.google.api.ads.adwords.axis.v201705.cm.FeedItemGeoRestriction;
import com.google.api.ads.adwords.axis.v201705.cm.FeedItemOperation;
import com.google.api.ads.adwords.axis.v201705.cm.FeedItemReturnValue;
import com.google.api.ads.adwords.axis.v201705.cm.FeedItemServiceInterface;
import com.google.api.ads.adwords.axis.v201705.cm.FeedMapping;
import com.google.api.ads.adwords.axis.v201705.cm.FeedMappingOperation;
import com.google.api.ads.adwords.axis.v201705.cm.FeedMappingReturnValue;
import com.google.api.ads.adwords.axis.v201705.cm.FeedMappingServiceInterface;
import com.google.api.ads.adwords.axis.v201705.cm.FeedOperation;
import com.google.api.ads.adwords.axis.v201705.cm.FeedOrigin;
import com.google.api.ads.adwords.axis.v201705.cm.FeedReturnValue;
import com.google.api.ads.adwords.axis.v201705.cm.FeedServiceInterface;
import com.google.api.ads.adwords.axis.v201705.cm.Function;
import com.google.api.ads.adwords.axis.v201705.cm.GeoRestriction;
import com.google.api.ads.adwords.axis.v201705.cm.Location;
import com.google.api.ads.adwords.axis.v201705.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.common.lib.auth.OfflineCredentials;
import com.google.api.ads.common.lib.auth.OfflineCredentials.Api;
import com.google.api.client.auth.oauth2.Credential;
import com.google.common.base.Joiner;
import java.util.ArrayList;
import java.util.List;

/**
 * This example adds a sitelinks feed and associates it with a campaign. To create a campaign,
 * run {@link AddCampaigns}. To add sitelinks using the simpler ExtensionSetting services, see
 * {@link AddSiteLinks}.
 *
 * <p>Credentials and properties in {@code fromFile()} are pulled from the
 * "ads.properties" file. See README for more info.
 */
public class AddSiteLinksUsingFeeds {

  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();

    Long campaignId = Long.valueOf("INSERT_CAMPAIGN_ID_HERE");
    String feedName = "INSERT_FEED_NAME_HERE";

    runExample(adWordsServices, session, campaignId, feedName);
  }

  public static void runExample(AdWordsServicesInterface adWordsServices, AdWordsSession session,
      Long campaignId, String feedName) throws Exception {
    SiteLinksDataHolder siteLinksData = new SiteLinksDataHolder();
    createSiteLinksFeed(adWordsServices, session, siteLinksData, feedName);
    createSiteLinksFeedItems(adWordsServices, session, siteLinksData);
    createSiteLinksFeedMapping(adWordsServices, session, siteLinksData);
    createSiteLinksCampaignFeed(adWordsServices, session, siteLinksData, campaignId);
  }

  private static void createSiteLinksFeed(
      AdWordsServicesInterface adWordsServices,
      AdWordsSession session,
      SiteLinksDataHolder siteLinksData,
      String feedName)
      throws Exception {
    // Get the FeedService.
    FeedServiceInterface feedService = adWordsServices.get(session, FeedServiceInterface.class);

    // Create attributes.
    FeedAttribute textAttribute = new FeedAttribute();
    textAttribute.setType(FeedAttributeType.STRING);
    textAttribute.setName("Link Text");
    FeedAttribute finalUrlAttribute = new FeedAttribute();
    finalUrlAttribute.setType(FeedAttributeType.URL_LIST);
    finalUrlAttribute.setName("Link Final URLs");
    FeedAttribute line2Attribute = new FeedAttribute();
    line2Attribute.setType(FeedAttributeType.STRING);
    line2Attribute.setName("Line 2");
    FeedAttribute line3Attribute = new FeedAttribute();
    line3Attribute.setType(FeedAttributeType.STRING);
    line3Attribute.setName("Line 3");

    // Create the feed.
    Feed siteLinksFeed = new Feed();
    siteLinksFeed.setName(feedName);
    siteLinksFeed.setAttributes(
        new FeedAttribute[] {textAttribute, finalUrlAttribute, line2Attribute, line3Attribute});
    siteLinksFeed.setOrigin(FeedOrigin.USER);

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

    // Add the feed.
    FeedReturnValue result = feedService.mutate(new FeedOperation[] {operation});

    Feed savedFeed = result.getValue()[0];
    siteLinksData.siteLinksFeedId = savedFeed.getId();
    FeedAttribute[] savedAttributes = savedFeed.getAttributes();
    siteLinksData.linkTextFeedAttributeId = savedAttributes[0].getId();
    siteLinksData.linkFinalUrlFeedAttributeId = savedAttributes[1].getId();
    siteLinksData.line2FeedAttributeId = savedAttributes[2].getId();
    siteLinksData.line3FeedAttributeId = savedAttributes[3].getId();
    System.out.printf("Feed with name '%s' and ID %d with linkTextAttributeId %d"
        + " and linkFinalUrlAttributeId %d and line2AttributeId %d"
        + " and line3AttributeId %d was created.%n",
        savedFeed.getName(),
        savedFeed.getId(),
        savedAttributes[0].getId(),
        savedAttributes[1].getId(),
        savedAttributes[2].getId(),
        savedAttributes[3].getId());
  }

  private static void createSiteLinksFeedItems(AdWordsServicesInterface adWordsServices,
      AdWordsSession session, SiteLinksDataHolder siteLinksData) throws Exception {
    // Get the FeedItemService.
    FeedItemServiceInterface feedItemService =
        adWordsServices.get(session, FeedItemServiceInterface.class);

    // Create operations to add FeedItems.
    FeedItemOperation home = newSiteLinkFeedItemAddOperation(siteLinksData, "Home",
        "http://www.example.com", "Home line 2", "Home line 3");
    FeedItemOperation stores = newSiteLinkFeedItemAddOperation(siteLinksData, "Stores",
        "http://www.example.com/stores", "Stores line 2", "Stores line 3");
    FeedItemOperation onSale = newSiteLinkFeedItemAddOperation(siteLinksData, "On Sale",
        "http://www.example.com/sale", "On Sale line 2", "On Sale line 3");
    FeedItemOperation support = newSiteLinkFeedItemAddOperation(siteLinksData, "Support",
        "http://www.example.com/support", "Support line 2", "Support line 3");
    FeedItemOperation products = newSiteLinkFeedItemAddOperation(siteLinksData, "Products",
        "http://www.example.com/prods", "Products line 2", "Products line 3");
    // This site link is using geographical targeting by specifying the
    // criterion ID for California.
    FeedItemOperation aboutUs = newSiteLinkFeedItemAddOperation(siteLinksData, "About Us",
        "http://www.example.com/about", "About Us line 2", "About Us line 3", 21137L);

    FeedItemOperation[] operations =
        new FeedItemOperation[] {home, stores, onSale, support, products, aboutUs};

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


  // See the Placeholder reference page for a list of all the placeholder types and fields.
  // https://developers.google.com/adwords/api/docs/appendix/placeholders
  private static final int PLACEHOLDER_SITELINKS = 1;

  // See the Placeholder reference page for a list of all the placeholder types and fields.
  // https://developers.google.com/adwords/api/docs/appendix/placeholders
  private static final int PLACEHOLDER_FIELD_SITELINK_LINK_TEXT = 1;
  private static final int PLACEHOLDER_FIELD_SITELINK_FINAL_URL = 5;
  private static final int PLACEHOLDER_FIELD_LINE_2_TEXT = 3;
  private static final int PLACEHOLDER_FIELD_LINE_3_TEXT = 4;

  private static void createSiteLinksFeedMapping(AdWordsServicesInterface adWordsServices,
      AdWordsSession session, SiteLinksDataHolder siteLinksData) throws Exception {
    // Get the FeedItemService.
    FeedMappingServiceInterface feedMappingService =
        adWordsServices.get(session, FeedMappingServiceInterface.class);

    // Map the FeedAttributeIds to the fieldId constants.
    AttributeFieldMapping linkTextFieldMapping = new AttributeFieldMapping();
    linkTextFieldMapping.setFeedAttributeId(siteLinksData.linkTextFeedAttributeId);
    linkTextFieldMapping.setFieldId(PLACEHOLDER_FIELD_SITELINK_LINK_TEXT);
    AttributeFieldMapping linkFinalUrlFieldMapping = new AttributeFieldMapping();
    linkFinalUrlFieldMapping.setFeedAttributeId(siteLinksData.linkFinalUrlFeedAttributeId);
    linkFinalUrlFieldMapping.setFieldId(PLACEHOLDER_FIELD_SITELINK_FINAL_URL);
    AttributeFieldMapping line2FieldMapping = new AttributeFieldMapping();
    line2FieldMapping.setFeedAttributeId(siteLinksData.line2FeedAttributeId);
    line2FieldMapping.setFieldId(PLACEHOLDER_FIELD_LINE_2_TEXT);
    AttributeFieldMapping line3FieldMapping = new AttributeFieldMapping();
    line3FieldMapping.setFeedAttributeId(siteLinksData.line3FeedAttributeId);
    line3FieldMapping.setFieldId(PLACEHOLDER_FIELD_LINE_3_TEXT);


    // Create the FeedMapping and operation.
    FeedMapping feedMapping = new FeedMapping();
    feedMapping.setPlaceholderType(PLACEHOLDER_SITELINKS);
    feedMapping.setFeedId(siteLinksData.siteLinksFeedId);
    feedMapping.setAttributeFieldMappings(new AttributeFieldMapping[] {linkTextFieldMapping,
        linkFinalUrlFieldMapping, line2FieldMapping, line3FieldMapping});
    FeedMappingOperation operation = new FeedMappingOperation();
    operation.setOperand(feedMapping);
    operation.setOperator(Operator.ADD);

    // Save the field mapping.
    FeedMappingReturnValue result =
        feedMappingService.mutate(new FeedMappingOperation[] {operation});
    for (FeedMapping savedFeedMapping : result.getValue()) {
      System.out.printf(
          "Feed mapping with ID %d and placeholderType %d was saved for feed with ID %d.%n",
          savedFeedMapping.getFeedMappingId(), savedFeedMapping.getPlaceholderType(),
          savedFeedMapping.getFeedId());
    }
  }

  private static void createSiteLinksCampaignFeed(AdWordsServicesInterface adWordsServices,
      AdWordsSession session, SiteLinksDataHolder siteLinksData, Long campaignId) throws Exception {
    // Get the CampaignFeedService.
    CampaignFeedServiceInterface campaignFeedService =
        adWordsServices.get(session, CampaignFeedServiceInterface.class);

    // Construct a matching function that associates the sitelink feed items to the campaign, and
    // sets the device preference to mobile. See the matching function guide at
    // https://developers.google.com/adwords/api/docs/guides/feed-matching-functions
    // for more details.
    String matchingFunctionString = String.format(
        "AND( IN(FEED_ITEM_ID, {%s}), EQUALS(CONTEXT.DEVICE, 'Mobile') )",
        Joiner.on(',').join(siteLinksData.siteLinkFeedItemIds));

    CampaignFeed campaignFeed = new CampaignFeed();
    campaignFeed.setFeedId(siteLinksData.siteLinksFeedId);
    campaignFeed.setCampaignId(campaignId);

    Function matchingFunction = new Function();
    matchingFunction.setFunctionString(matchingFunctionString);

    campaignFeed.setMatchingFunction(matchingFunction);
    // Specifying placeholder types on the CampaignFeed allows the same feed
    // to be used for different placeholders in different Campaigns.
    campaignFeed.setPlaceholderTypes(new int[] {PLACEHOLDER_SITELINKS});

    CampaignFeedOperation operation = new CampaignFeedOperation();
    operation.setOperand(campaignFeed);
    operation.setOperator(Operator.ADD);
    CampaignFeedReturnValue result =
        campaignFeedService.mutate(new CampaignFeedOperation[] {operation});
    for (CampaignFeed savedCampaignFeed : result.getValue()) {
      System.out.printf("Campaign with ID %d was associated with feed with ID %d.%n",
          savedCampaignFeed.getCampaignId(), savedCampaignFeed.getFeedId());
    }
  }

  private static FeedItemOperation newSiteLinkFeedItemAddOperation(
      SiteLinksDataHolder siteLinksData, String text, String finalUrl, String line2, String line3) {
    return newSiteLinkFeedItemAddOperation(siteLinksData, text, finalUrl, line2, line3, null);
  }

  private static FeedItemOperation newSiteLinkFeedItemAddOperation(
      SiteLinksDataHolder siteLinksData, String text, String finalUrl, String line2, String line3,
      Long locationId) {
    // Create the FeedItemAttributeValues for our text values.
    FeedItemAttributeValue linkTextAttributeValue = new FeedItemAttributeValue();
    linkTextAttributeValue.setFeedAttributeId(siteLinksData.linkTextFeedAttributeId);
    linkTextAttributeValue.setStringValue(text);
    FeedItemAttributeValue linkFinalUrlAttributeValue = new FeedItemAttributeValue();
    linkFinalUrlAttributeValue.setFeedAttributeId(siteLinksData.linkFinalUrlFeedAttributeId);
    linkFinalUrlAttributeValue.setStringValues(new String[] {finalUrl});
    FeedItemAttributeValue line2TextAttributeValue = new FeedItemAttributeValue();
    line2TextAttributeValue.setFeedAttributeId(siteLinksData.line2FeedAttributeId);
    line2TextAttributeValue.setStringValue(line2);
    FeedItemAttributeValue line3TextAttributeValue = new FeedItemAttributeValue();
    line3TextAttributeValue.setFeedAttributeId(siteLinksData.line3FeedAttributeId);
    line3TextAttributeValue.setStringValue(line3);

    // Create the feed item and operation.
    FeedItem item = new FeedItem();
    item.setFeedId(siteLinksData.siteLinksFeedId);
    item.setAttributeValues(new FeedItemAttributeValue[] {linkTextAttributeValue,
        linkFinalUrlAttributeValue, line2TextAttributeValue, line3TextAttributeValue});

    // OPTIONAL: Use geographical targeting on a feed item.
    // IDs can be found in the documentation or retrieved with the
    // LocationCriterionService.
    if (locationId != null) {
      Location location = new Location();
      location.setId(locationId);
      item.setGeoTargeting(location);
      // OPTIONAL: Restrict targeting only to people physically within the location.
      FeedItemGeoRestriction geoTargetingRestriction = new FeedItemGeoRestriction();
      geoTargetingRestriction.setGeoRestriction(GeoRestriction.LOCATION_OF_PRESENCE);
      item.setGeoTargetingRestriction(geoTargetingRestriction);
    }

    // Optional: use item.setStartTime() and item.setEndTime() to specify the
    // time period for the feed to deliver.  The example below will make the feed
    // start now and stop in one month.
    // Make sure you specify the DateTime in the customer's time zone.  You can
    // retrieve this from customer.getDateTimeZone().
    //   item.setStartTime(new DateTime(customerTimeZone).toString("yyyyMMdd HHmmss"));
    //   item.setEndTime(new DateTime(customerTimeZone).plusMonths(1).toString("yyyyMMdd HHmmss"));

    // Optional: use item.setScheduling() to specify time and days of the week for feed to deliver.
    FeedItemOperation operation = new FeedItemOperation();
    operation.setOperand(item);
    operation.setOperator(Operator.ADD);
    return operation;
  }

  private static class SiteLinksDataHolder {
    private Long siteLinksFeedId;
    private Long linkTextFeedAttributeId;
    private Long linkFinalUrlFeedAttributeId;
    private Long line2FeedAttributeId;
    private Long line3FeedAttributeId;
    private List<Long> siteLinkFeedItemIds = new ArrayList<Long>();
  }
}

Send feedback about...

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