Java tutorial
// 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 adwords.axis.v201309.advancedoperations; import com.google.api.ads.adwords.axis.factory.AdWordsServices; import com.google.api.ads.adwords.axis.utils.v201309.SelectorBuilder; import com.google.api.ads.adwords.axis.v201309.cm.AttributeFieldMapping; import com.google.api.ads.adwords.axis.v201309.cm.Feed; import com.google.api.ads.adwords.axis.v201309.cm.FeedAttribute; import com.google.api.ads.adwords.axis.v201309.cm.FeedAttributeType; import com.google.api.ads.adwords.axis.v201309.cm.FeedItem; import com.google.api.ads.adwords.axis.v201309.cm.FeedItemAttributeValue; import com.google.api.ads.adwords.axis.v201309.cm.FeedItemOperation; import com.google.api.ads.adwords.axis.v201309.cm.FeedItemReturnValue; import com.google.api.ads.adwords.axis.v201309.cm.FeedItemServiceInterface; import com.google.api.ads.adwords.axis.v201309.cm.FeedMapping; import com.google.api.ads.adwords.axis.v201309.cm.FeedMappingOperation; import com.google.api.ads.adwords.axis.v201309.cm.FeedMappingReturnValue; import com.google.api.ads.adwords.axis.v201309.cm.FeedMappingServiceInterface; import com.google.api.ads.adwords.axis.v201309.cm.FeedOperation; import com.google.api.ads.adwords.axis.v201309.cm.FeedReturnValue; import com.google.api.ads.adwords.axis.v201309.cm.FeedServiceInterface; import com.google.api.ads.adwords.axis.v201309.cm.Operator; import com.google.api.ads.adwords.axis.v201309.cm.Selector; import com.google.api.ads.adwords.lib.client.AdWordsSession; 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.Functions; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; /** * This example updates an existing sitelinks feed as follows: * * <ol> * <li>Adds FeedItemAttributes for line 1 and line 2 descriptions to the Feed</li> * <li>Populates the new FeedItemAttributes on FeedItems in the Feed</li> * <li>Replaces the Feed's existing FeedMapping with one that contains the new set of * FeedItemAttributes</li> * </ol> * * The end result of this is that any campaign or ad group whose CampaignFeed or AdGroupFeed points * to the Feed's ID will now serve line 1 and line 2 descriptions in its sitelinks. * * Credentials and properties in {@code fromFile()} are pulled from the "ads.properties" file. See * README for more info. * * Tags: FeedItemService.mutate, FeedMappingService.mutate, FeedService.mutate * * Category: adx-exclude * * @author Josh Radcliff */ public class UpdateSiteLinks { public static void main(String[] args) throws Exception { // Generate a refreshable OAuth2 credential similar to a ClientLogin token // and can be used in place of a service account. Credential oAuth2Credential = new OfflineCredentials.Builder().forApi(Api.ADWORDS).fromFile().build() .generateCredential(); // Construct an AdWordsSession. AdWordsSession session = new AdWordsSession.Builder().fromFile().withOAuth2Credential(oAuth2Credential) .build(); AdWordsServices adWordsServices = new AdWordsServices(); Long feedId = Long.valueOf("INSERT_FEED_ID_HERE"); // Populate the map of FeedItem ID to descriptions. Map<Long, String[]> feedItemDescriptions = new HashMap<Long, String[]>(); feedItemDescriptions.put(Long.valueOf("INSERT_FEED_ITEM_A_ID_HERE"), new String[] { "INSERT_FEED_ITEM_A_LINE1_DESC_HERE", "INSERT_FEED_ITEM_A_LINE2_DESC_HERE" }); feedItemDescriptions.put(Long.valueOf("INSERT_FEED_ITEM_B_ID_HERE"), new String[] { "INSERT_FEED_ITEM_B_LINE1_DESC_HERE", "INSERT_FEED_ITEM_B_LINE2_DESC_HERE" }); runExample(adWordsServices, session, feedId, feedItemDescriptions); } public static void runExample(AdWordsServices adWordsServices, AdWordsSession session, Long feedId, Map<Long, String[]> feedItemDescriptions) throws Exception { FeedServiceInterface feedService = adWordsServices.get(session, FeedServiceInterface.class); Selector selector = new SelectorBuilder().fields("Id", "Attributes").equalsId(feedId).build(); Feed feed = feedService.get(selector).getEntries()[0]; // Add new attributes to the feed. FeedAttribute[] newAttributes = addLine1And2FeedAttributes(adWordsServices, session, feed); FeedAttribute line1Attribute = newAttributes[0]; FeedAttribute line2Attribute = newAttributes[1]; // Update feed items. updateFeedItems(adWordsServices, session, feedId, line1Attribute, line2Attribute, feedItemDescriptions); // Update field mappings. updateFeedMapping(adWordsServices, session, feedId, line1Attribute, line2Attribute); } /** * Adds a FeedAttribute for line 1 and line 2 descriptions to the Feed. * * @param adWordsServices service locator for AdWords services * @param session the AdWords session to use for service calls * @param feed the Feed to mutate. This must have its FeedAttributes populated with the existing * attributes * @return a two element array containing the new FeedAttributes for line 1 and line 2 * descriptions * @throws Exception */ private static FeedAttribute[] addLine1And2FeedAttributes(AdWordsServices adWordsServices, AdWordsSession session, Feed feed) throws Exception { // This will be the starting index for the new attributes created below. int nextAttributeIndex = feed.getAttributes().length; FeedAttribute line1Attribute = new FeedAttribute(); FeedAttribute line2Attribute = new FeedAttribute(); line1Attribute.setType(FeedAttributeType.STRING); line1Attribute.setName("Line 1 Description"); line2Attribute.setType(FeedAttributeType.STRING); line2Attribute.setName("Line 2 Description"); // Only include NEW attributes when adding attributes to a feed. feed.setAttributes(new FeedAttribute[] { line1Attribute, line2Attribute }); FeedOperation feedOperation = new FeedOperation(); feedOperation.setOperand(feed); feedOperation.setOperator(Operator.SET); FeedServiceInterface feedService = adWordsServices.get(session, FeedServiceInterface.class); FeedReturnValue mutateFeedResult = feedService.mutate(new FeedOperation[] { feedOperation }); // Get the new attributes from the mutated feed. Feed mutatedFeed = mutateFeedResult.getValue()[0]; line1Attribute = mutatedFeed.getAttributes(nextAttributeIndex); line2Attribute = mutatedFeed.getAttributes(nextAttributeIndex + 1); return new FeedAttribute[] { line1Attribute, line2Attribute }; } /** * Updates FeedItems for the Feed, setting line 1 description and line 2 description from the * contents of the feedItemDescriptions map. * * @param adWordsServices service locator for AdWords services * @param session the AdWords session to use for service calls * @param feedId the ID of the feed to update * @param line1Attribute the FeedAttribute for line 1 description * @param line2Attribute the FeedAttribute for line 2 description * @param feedItemDescriptions a map from feedItemId to a two-element array where item 0 is the * line 1 description and item 1 is the line 2 description * @throws Exception */ private static void updateFeedItems(AdWordsServices adWordsServices, AdWordsSession session, Long feedId, FeedAttribute line1Attribute, FeedAttribute line2Attribute, Map<Long, String[]> feedItemDescriptions) throws Exception { FeedItemServiceInterface feedItemService = adWordsServices.get(session, FeedItemServiceInterface.class); List<String> feedItemIds = Lists .newArrayList(Iterables.transform(feedItemDescriptions.keySet(), Functions.toStringFunction())); Selector itemSelector = new SelectorBuilder().fields("FeedId", "FeedItemId", "AttributeValues") // Limit FeedItems to the feed. .equalsId(feedId) // Limit FeedItems to the items in the feedItemDescriptions map. .in("FeedItemId", feedItemIds.toArray(new String[0])).build(); FeedItem[] feedItems = feedItemService.get(itemSelector).getEntries(); List<FeedItemOperation> itemOperations = Lists.newArrayListWithCapacity(feedItems.length); for (FeedItem feedItem : feedItems) { // Construct a FeedItemOperation that will set the line 1 and line 2 // attribute values for this FeedItem. FeedItemAttributeValue[] itemAttributeValues = new FeedItemAttributeValue[2]; FeedItemAttributeValue line1AttributeValue = new FeedItemAttributeValue(); line1AttributeValue.setFeedAttributeId(line1Attribute.getId()); line1AttributeValue.setStringValue(feedItemDescriptions.get(feedItem.getFeedItemId())[0]); itemAttributeValues[0] = line1AttributeValue; FeedItemAttributeValue line2AttributeValue = new FeedItemAttributeValue(); line2AttributeValue.setFeedAttributeId(line2Attribute.getId()); line2AttributeValue.setStringValue(feedItemDescriptions.get(feedItem.getFeedItemId())[1]); itemAttributeValues[1] = line2AttributeValue; feedItem.setAttributeValues(itemAttributeValues); FeedItemOperation operation = new FeedItemOperation(); operation.setOperator(Operator.SET); operation.setOperand(feedItem); itemOperations.add(operation); } FeedItemReturnValue itemsUpdateReturnValue = feedItemService .mutate(itemOperations.toArray(new FeedItemOperation[0])); System.out.printf("Updated %d items%n", itemsUpdateReturnValue.getValue().length); } // 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_LINE_1_TEXT = 3; private static final int PLACEHOLDER_FIELD_LINE_2_TEXT = 4; /** * Updates the FeedMapping for the Feed to include AttributeFieldMappings for the new line 1 and * line 2 FeedAttributes. * * @param adWordsServices service locator for AdWords services * @param session the AdWords session to use for service calls * @param feedId the ID of the Feed to associate with the updated FeedMapping * @param line1FeedAttribute the FeedAttribute for line 1 description * @param line2FeedAttribute the FeedAttribute for line 2 description * @throws Exception */ private static void updateFeedMapping(AdWordsServices adWordsServices, AdWordsSession session, Long feedId, FeedAttribute line1FeedAttribute, FeedAttribute line2FeedAttribute) throws Exception { FeedMappingServiceInterface mappingService = adWordsServices.get(session, FeedMappingServiceInterface.class); Selector selector = new SelectorBuilder() .fields("FeedId", "FeedMappingId", "PlaceholderType", "AttributeFieldMappings").equalsId(feedId) .build(); FeedMapping feedMapping = mappingService.get(selector).getEntries()[0]; // Remove the existing mapping (FeedMapping is immutable). feedMapping = mappingService .mutate(new FeedMappingOperation[] { new FeedMappingOperation(Operator.REMOVE, null, feedMapping) }) .getValue(0); // Create line 1 and line 2 attribute field mappings. AttributeFieldMapping line1FieldMapping = new AttributeFieldMapping(); line1FieldMapping.setFeedAttributeId(line1FeedAttribute.getId()); line1FieldMapping.setFieldId(PLACEHOLDER_FIELD_LINE_1_TEXT); AttributeFieldMapping line2FieldMapping = new AttributeFieldMapping(); line2FieldMapping.setFeedAttributeId(line2FeedAttribute.getId()); line2FieldMapping.setFieldId(PLACEHOLDER_FIELD_LINE_2_TEXT); // Combine the existing field mappings with the new mappings. List<AttributeFieldMapping> allFieldMappings = new ArrayList<AttributeFieldMapping>(); // Include existing mappings. allFieldMappings.addAll(Arrays.asList(feedMapping.getAttributeFieldMappings())); // Add the new mappings for line 1 and line 2. allFieldMappings.add(line1FieldMapping); allFieldMappings.add(line2FieldMapping); feedMapping.setAttributeFieldMappings(allFieldMappings.toArray(new AttributeFieldMapping[0])); FeedMappingReturnValue mappingReturnValue = mappingService .mutate(new FeedMappingOperation[] { new FeedMappingOperation(Operator.ADD, null, feedMapping) }); FeedMapping mutatedMapping = mappingReturnValue.getValue()[0]; System.out.printf("Updated field mappings for feedId %d and feedMappingId %d to:%n", mutatedMapping.getFeedId(), mutatedMapping.getFeedMappingId()); for (AttributeFieldMapping fieldMapping : mutatedMapping.getAttributeFieldMappings()) { System.out.printf(" feedAttributeId %d --> fieldId %d%n", fieldMapping.getFeedAttributeId(), fieldMapping.getFieldId()); } } }