Package v201306

Source Code of v201306.UpgradeLegacySitelinks$SiteLinksFeed

// Copyright 2013 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 v201306;

import com.google.api.adwords.lib.AdWordsService;
import com.google.api.adwords.lib.AdWordsServiceLogger;
import com.google.api.adwords.lib.AdWordsUser;
import com.google.api.adwords.v201306.cm.AttributeFieldMapping;
import com.google.api.adwords.v201306.cm.CampaignAdExtension;
import com.google.api.adwords.v201306.cm.CampaignAdExtensionOperation;
import com.google.api.adwords.v201306.cm.CampaignAdExtensionPage;
import com.google.api.adwords.v201306.cm.CampaignAdExtensionServiceInterface;
import com.google.api.adwords.v201306.cm.CampaignAdExtensionStatus;
import com.google.api.adwords.v201306.cm.CampaignFeed;
import com.google.api.adwords.v201306.cm.CampaignFeedOperation;
import com.google.api.adwords.v201306.cm.CampaignFeedServiceInterface;
import com.google.api.adwords.v201306.cm.ConstantOperand;
import com.google.api.adwords.v201306.cm.ConstantOperandConstantType;
import com.google.api.adwords.v201306.cm.Feed;
import com.google.api.adwords.v201306.cm.FeedAttribute;
import com.google.api.adwords.v201306.cm.FeedAttributeType;
import com.google.api.adwords.v201306.cm.FeedItem;
import com.google.api.adwords.v201306.cm.FeedItemAttributeValue;
import com.google.api.adwords.v201306.cm.FeedItemOperation;
import com.google.api.adwords.v201306.cm.FeedItemReturnValue;
import com.google.api.adwords.v201306.cm.FeedItemServiceInterface;
import com.google.api.adwords.v201306.cm.FeedMapping;
import com.google.api.adwords.v201306.cm.FeedMappingOperation;
import com.google.api.adwords.v201306.cm.FeedMappingPage;
import com.google.api.adwords.v201306.cm.FeedMappingServiceInterface;
import com.google.api.adwords.v201306.cm.FeedOperation;
import com.google.api.adwords.v201306.cm.FeedOrigin;
import com.google.api.adwords.v201306.cm.FeedReturnValue;
import com.google.api.adwords.v201306.cm.FeedServiceInterface;
import com.google.api.adwords.v201306.cm.Function;
import com.google.api.adwords.v201306.cm.FunctionArgumentOperand;
import com.google.api.adwords.v201306.cm.FunctionOperator;
import com.google.api.adwords.v201306.cm.Operator;
import com.google.api.adwords.v201306.cm.Predicate;
import com.google.api.adwords.v201306.cm.PredicateOperator;
import com.google.api.adwords.v201306.cm.RequestContextOperand;
import com.google.api.adwords.v201306.cm.RequestContextOperandContextType;
import com.google.api.adwords.v201306.cm.Selector;
import com.google.api.adwords.v201306.cm.Sitelink;
import com.google.api.adwords.v201306.cm.SitelinksExtension;

import java.util.ArrayList;
import java.util.List;

/**
* This example migrates legacy sitelinks to upgraded sitelinks for a given list
* of campaigns. The campaigns must be upgraded to enhanced campaigns before you
* can run this example.
*
* Tags: CampaignAdExtensionService.get, CampaignAdExtensionService.mutate
* Tags: FeedService.mutate, FeedItemService.mutate, FeedMappingService.mutate
* Tags: CampaignFeedService.mutate
*
* @category adx-exclude
* @author thagikura@google.com (Takeshi Hagikura)
*/
public class UpgradeLegacySitelinks {

  /**
   * Data structure to hold details about a sitelink feed.
   */
  private static class SiteLinksFeed {
    /**
     * Feed ID.
     */
    private Long siteLinksFeedId;

    /**
     * Attribute ID for sitelink text.
     */
    private Long linkTextFeedAttributeId;

    /**
     * Attribute ID for sitelink URL.
     */
    private Long linkUrlFeedAttributeId;
  }

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

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

  public static void main(String[] args) throws Exception {
    long[] campaignIds = new long[] {
    Long.parseLong("INSERT_CAMPAIGN_ID_HERE"), };

    // Log SOAP XML request and response.
    AdWordsServiceLogger.log();

    // Get AdWordsUser from "~/adwords.properties".
    AdWordsUser user = new AdWordsUser();
    runExample(user, campaignIds);
  }

  public static void runExample(AdWordsUser user, long[] campaignIds) throws Exception {
    // Get the CampaignAdExtensionService.
    CampaignAdExtensionServiceInterface campaignExtensionService =
        user.getService(AdWordsService.V201306.CAMPAIGN_AD_EXTENSION_SERVICE);
    // Get the FeedMappingService.
    FeedMappingServiceInterface feedMappingService =
        user.getService(AdWordsService.V201306.FEED_MAPPING_SERVICE);
    // Get the FeedService.
    FeedServiceInterface feedService =
        user.getService(AdWordsService.V201306.FEED_SERVICE);
    // Get the FeedItemService.
    FeedItemServiceInterface feedItemService =
        user.getService(AdWordsService.V201306.FEED_ITEM_SERVICE);
    // Get the CampaignFeedService.
    CampaignFeedServiceInterface campaignFeedService =
        user.getService(AdWordsService.V201306.CAMPAIGN_FEED_SERVICE);

    // Try to retrieve an existing feed that has been mapped for use with
    // sitelinks. if multiple such feeds exist, the first matching feed is
    // retrieved. You could modify this code example to retrieve all the feeds
    // and pick the appropriate feed based on user input.
    SiteLinksFeed siteLinksFeed = getExistingFeed(feedMappingService);

    if (siteLinksFeed == null) {
      // Create a feed for storing sitelinks.
      siteLinksFeed = createSiteLinksFeed(feedService);

      // Map the feed for using with sitelinks.
      createSiteLinksFeedMapping(feedMappingService, siteLinksFeed);
    }

    for (long campaignId : campaignIds) {
      // Get legacy sitelinks for the campaign.
      CampaignAdExtension extension =
          getLegacySitelinksForCampaign(campaignExtensionService, campaignId);
      if (extension != null) {
        // Get the sitelinks.
        Sitelink[] legacySitelinks =
            ((SitelinksExtension) extension.getAdExtension()).getSitelinks();

        // Add the sitelinks to the feed.
        List<Long> siteLinkFeedItemIds =
            createSiteLinkFeedItems(feedItemService, siteLinksFeed, legacySitelinks);

        // Associate feed items to the campaign.
        associateSitelinkFeedItemsWithCampaign(
            campaignFeedService, siteLinksFeed, siteLinkFeedItemIds, campaignId);

        // Once the upgraded sitelinks are added to a campaign, the legacy
        // sitelinks will stop serving. You can delete the legacy sitelinks
        // once you have verified that the migration went fine. In case the
        // migration didn't succeed, you can roll back the migration by deleting
        // the CampaignFeed you created in the previous step.
        deleteLegacySitelinks(campaignExtensionService, extension);
      }
    }
  }

  /**
   * Retrieve an existing feed that is mapped to hold sitelinks. The first active sitelinks feed is
   * retrieved by this method.
   *
   * @param feedMappingService The {@link FeedMappingServiceInterface} instance.
   * @return A {@link SiteLinksFeed} if a feed is found, or {@code null} otherwise.
   * @throws Exception if an error occurs when retrieving an existing feed.
   */
  private static SiteLinksFeed getExistingFeed(FeedMappingServiceInterface feedMappingService)
      throws Exception {
    Selector selector = new Selector();
    selector.setFields(new String[] {"FeedId", "FeedMappingId", "PlaceholderType", "Status",
        "AttributeFieldMappings"});

    Predicate placeHolderPredicate = new Predicate();
    placeHolderPredicate.setField("PlaceholderType");
    placeHolderPredicate.setOperator(PredicateOperator.EQUALS);
    placeHolderPredicate.setValues(new String[] {Integer.toString(PLACEHOLDER_SITELINKS)});

    Predicate statusPredicate = new Predicate();
    statusPredicate.setField("Status");
    statusPredicate.setOperator(PredicateOperator.EQUALS);
    statusPredicate.setValues(new String[] {"ACTIVE"});

    selector.setPredicates(new Predicate[] {placeHolderPredicate, statusPredicate});

    FeedMappingPage page = feedMappingService.get(selector);

    if (page != null && page.getEntries() != null && page.getEntries().length > 0) {
      for (FeedMapping feedMapping : page.getEntries()) {
        Long feedId = feedMapping.getFeedId();
        Long textAttributeId = null;
        Long urlAttributeId = null;
        for (AttributeFieldMapping attributeMapping : feedMapping.getAttributeFieldMappings()) {
          if (attributeMapping.getFieldId().intValue() == PLACEHOLDER_FIELD_SITELINK_LINK_TEXT) {
            textAttributeId = attributeMapping.getFeedAttributeId();
          } else if (attributeMapping.getFieldId().intValue() == PLACEHOLDER_FIELD_SITELINK_URL) {
            urlAttributeId = attributeMapping.getFeedAttributeId();
          }
        }

        if (feedId != null && textAttributeId != null && urlAttributeId != null) {
          SiteLinksFeed siteLinksFeed = new SiteLinksFeed();
          siteLinksFeed.siteLinksFeedId = feedId;
          siteLinksFeed.linkTextFeedAttributeId = textAttributeId;
          siteLinksFeed.linkUrlFeedAttributeId = urlAttributeId;
          return siteLinksFeed;
        } else {
          System.out.printf(
              "Feed of ID '%d' is found with an invalid mapping state for sitelinks\n", feedId);
        }
      }
    }
    return null;
  }

  /**
   * Create a feed for holding upgraded sitelinks.
   *
   * @param feedService The {@link FeedServiceInterface} instance.
   * @return A {@link SiteLinksFeed} for holding the sitelinks.
   * @throws Exception if an error occurs when creating the feed.
   */
  private static SiteLinksFeed createSiteLinksFeed(FeedServiceInterface feedService)
      throws Exception {
    SiteLinksFeed siteLinksData = new SiteLinksFeed();

    // Create attributes.
    FeedAttribute textAttribute = new FeedAttribute();
    textAttribute.setType(FeedAttributeType.STRING);

    // Replace the text attribute for your own.
    textAttribute.setName("Link Text");
    FeedAttribute urlAttribute = new FeedAttribute();
    urlAttribute.setType(FeedAttributeType.URL);

    // Replace the URL attribute for your own.
    urlAttribute.setName("Link URL");

    // Create the feed.
    Feed siteLinksFeed = new Feed();

    // Replace the feed name for your own.
    siteLinksFeed.setName("Feed For Sitelinks");
    siteLinksFeed.setAttributes(new FeedAttribute[] {textAttribute, urlAttribute});
    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.linkUrlFeedAttributeId = savedAttributes[1].getId();
    return siteLinksData;
  }

  /**
   * Map the feed for use with sitelinks.
   *
   * @param feedMappingService The {@link FeedMappingServiceInterface} instance.
   * @param siteLinksFeed The feed for holding sitelinks.
   * @throws Exception if an error occurs when mapping the feed for sitelinks.
   */
  private static void createSiteLinksFeedMapping(FeedMappingServiceInterface feedMappingService,
      SiteLinksFeed siteLinksFeed) throws Exception {
    // Map the FeedAttributeIds to the fieldId constants.
    AttributeFieldMapping linkTextFieldMapping = new AttributeFieldMapping();
    linkTextFieldMapping.setFeedAttributeId(siteLinksFeed.linkTextFeedAttributeId);
    linkTextFieldMapping.setFieldId(PLACEHOLDER_FIELD_SITELINK_LINK_TEXT);
    AttributeFieldMapping linkUrlFieldMapping = new AttributeFieldMapping();
    linkUrlFieldMapping.setFeedAttributeId(siteLinksFeed.linkUrlFeedAttributeId);
    linkUrlFieldMapping.setFieldId(PLACEHOLDER_FIELD_SITELINK_URL);

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

    // Save the field mapping.
    feedMappingService.mutate(new FeedMappingOperation[] {operation});
  }

  private static final String EXTENSION_NAME_FOR_SITELINKS = "SITELINKS_EXTENSION";

  /**
   * Get legacy sitelinks for a campaign
   *
   * @param campaignExtensionService The {@link CampaignAdExtensionServiceInterface} instance.
   * @param campaignId ID of the campaign for which legacy sitelinks are retrieved.
   * @return The {@link CampaignAdExtension} that contains the legacy sitelinks, or {@code null} if
   *         there are no legacy sitelinks in this campaign.
   * @throws Exception if an error occurs while retrieving the sitelinks.
   */
  private static CampaignAdExtension getLegacySitelinksForCampaign(
      CampaignAdExtensionServiceInterface campaignExtensionService, long campaignId)
      throws Exception {
    // Create the selector.
    Selector selector = new Selector();
    selector.setFields(new String[] {"AdExtensionId", "DisplayText", "DestinationUrl"});

    // Filter the results for specified campaign id.
    Predicate campaignPredicate = new Predicate();
    campaignPredicate.setOperator(PredicateOperator.EQUALS);
    campaignPredicate.setField("CampaignId");
    campaignPredicate.setValues(new String[] {Long.toString(campaignId)});

    // Filter the results for active campaign ad extensions. You may add
    // additional filtering conditions here as required.
    Predicate statusPredicate = new Predicate();
    statusPredicate.setOperator(PredicateOperator.EQUALS);
    statusPredicate.setField("Status");
    statusPredicate.setValues(new String[] {CampaignAdExtensionStatus.ACTIVE.getValue()});

    // Filter for sitelinks ad extension type.
    Predicate typePredicate = new Predicate();
    typePredicate.setOperator(PredicateOperator.EQUALS);
    typePredicate.setField("AdExtensionType");
    typePredicate.setValues(new String[] {EXTENSION_NAME_FOR_SITELINKS});

    selector.setPredicates(new Predicate[] {campaignPredicate, statusPredicate, typePredicate});

    CampaignAdExtensionPage page = campaignExtensionService.get(selector);
    if (page.getEntries() != null && page.getEntries().length > 0) {
      return page.getEntries()[0];
    } else {
      return null;
    }
  }

  /**
   * Add legacy sitelinks to the sitelinks feed.
   *
   * @param feedItemService The {@link FeedItemServiceInterface} instance.
   * @param siteLinksFeed The feed for adding sitelinks.
   * @param sitelinks The list of legacy sitelinks to be added to the feed.
   * @return The list of feed items that were added to the feed.
   * @throws Exception if an error occurred while adding feed items to the sitelinks feed.
   */
  private static List<Long> createSiteLinkFeedItems(FeedItemServiceInterface feedItemService,
      SiteLinksFeed siteLinksFeed, Sitelink[] sitelinks) throws Exception {
    List<Long> siteLinkFeedItemIds = new ArrayList<Long>();

    // Create operation for adding each legacy sitelink to the sitelinks feed.
    List<FeedItemOperation> feedItemOperations = new ArrayList<FeedItemOperation>();

    for (Sitelink sitelink : sitelinks) {
      FeedItemOperation operation = newSiteLinkFeedItemAddOperation(
          siteLinksFeed, sitelink.getDisplayText(), sitelink.getDestinationUrl());
      feedItemOperations.add(operation);
    }

    FeedItemReturnValue result =
        feedItemService.mutate(feedItemOperations.toArray(new FeedItemOperation[] {}));

    // Retrieve the feed item IDs.
    for (FeedItem item : result.getValue()) {
      siteLinkFeedItemIds.add(item.getFeedItemId());
    }
    return siteLinkFeedItemIds;
  }

  /**
   * Creates a new operation for adding a feed item.
   *
   * @param siteLinksFeed The sitelinks feed.
   * @param text The sitelink text.
   * @param url The sitelink URL.
   * @return A {@link FeedItemOperation} for adding the feed item.
   */
  private static FeedItemOperation newSiteLinkFeedItemAddOperation(
      SiteLinksFeed siteLinksFeed, String text, String url) {
    // Create the FeedItemAttributeValues for our text values.
    FeedItemAttributeValue linkTextAttributeValue = new FeedItemAttributeValue();
    linkTextAttributeValue.setFeedAttributeId(siteLinksFeed.linkTextFeedAttributeId);
    linkTextAttributeValue.setStringValue(text);
    FeedItemAttributeValue linkUrlAttributeValue = new FeedItemAttributeValue();
    linkUrlAttributeValue.setFeedAttributeId(siteLinksFeed.linkUrlFeedAttributeId);
    linkUrlAttributeValue.setStringValue(url);

    // Create the feed item and operation.
    FeedItem item = new FeedItem();
    item.setFeedId(siteLinksFeed.siteLinksFeedId);
    item.setAttributeValues(
        new FeedItemAttributeValue[] {linkTextAttributeValue, linkUrlAttributeValue});
    FeedItemOperation operation = new FeedItemOperation();
    operation.setOperand(item);
    operation.setOperator(Operator.ADD);
    return operation;
  }

  /**
   * Delete legacy sitelinks from a campaign.
   *
   * @param campaignExtensionService The {@link CampaignAdExtensionServiceInterface} instance.
   * @param extensionToDelete The {@link CampaignAdExtension} that holds legacy sitelinks.
   * @throws Exception if an error occurs when deleting the sitelinks.
   */
  private static void deleteLegacySitelinks(
      CampaignAdExtensionServiceInterface campaignExtensionService,
      CampaignAdExtension extensionToDelete) throws Exception {

    CampaignAdExtensionOperation operation = new CampaignAdExtensionOperation();
    operation.setOperator(Operator.REMOVE);
    operation.setOperand(extensionToDelete);

    campaignExtensionService.mutate(new CampaignAdExtensionOperation[] {operation});
  }

  /**
   * Associates sitelink feed items with a campaign.
   *
   * @param campaignFeedService The {@link CampaignFeedServiceInterface} instance.
   * @param siteLinksFeed The feed for holding the sitelinks.
   * @param siteLinkFeedItemIds The list of feed item IDs to be associated with a campaign as
   *        sitelinks.
   * @param campaignId The campaign ID to which upgraded sitelinks are added.
   * @throws Exception if an error occurs when adding upgraded sitelinks to the campaign.
   */
  private static void associateSitelinkFeedItemsWithCampaign(
      CampaignFeedServiceInterface campaignFeedService, SiteLinksFeed siteLinksFeed,
      List<Long> siteLinkFeedItemIds, Long campaignId) throws Exception {
    // Create a custom matching function that matches the given feed items to
    // the campaign.
    RequestContextOperand requestContextOperand = new RequestContextOperand();
    requestContextOperand.setContextType(RequestContextOperandContextType.FEED_ITEM_ID);

    Function function = new Function();
    function.setLhsOperand(new FunctionArgumentOperand[] {requestContextOperand});
    function.setOperator(FunctionOperator.IN);

    List<FunctionArgumentOperand> operands = new ArrayList<FunctionArgumentOperand>();
    for (long feedItemId : siteLinkFeedItemIds) {
      ConstantOperand constantOperand = new ConstantOperand();
      constantOperand.setLongValue(feedItemId);
      constantOperand.setType(ConstantOperandConstantType.LONG);
      operands.add(constantOperand);
    }
    function.setRhsOperand(operands.toArray(new FunctionArgumentOperand[operands.size()]));

    // Create upgraded sitelinks for the campaign. Use the sitelinks feed we
    // created, and restrict feed items by matching function.
    CampaignFeed campaignFeed = new CampaignFeed();
    campaignFeed.setFeedId(siteLinksFeed.siteLinksFeedId);
    campaignFeed.setCampaignId(campaignId);
    campaignFeed.setMatchingFunction(function);
    campaignFeed.setPlaceholderTypes(new int[] {PLACEHOLDER_SITELINKS});

    CampaignFeedOperation operation = new CampaignFeedOperation();
    operation.setOperand(campaignFeed);
    operation.setOperator(Operator.ADD);
    campaignFeedService.mutate(new CampaignFeedOperation[] {operation});
  }
}
TOP

Related Classes of v201306.UpgradeLegacySitelinks$SiteLinksFeed

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.