Let's say you have Dynamic Remarketing ads for your real estate website. New listings get added to inventory, while sold properties get removed. The goal is to update your Dynamic Remarketing ads to reflect your current inventory.
Step 1 - Get information about your listings setup
In order to manage your real estate listings, you'll need to retrieve the
feed.attributes
of your
Feed
. In order to easily access this information later, create
a Map
that contains keys of type
RealEstatePlaceholderField
and values of type FeedAttribute
. Assuming you use the
same Map
object to create your FeedMapping
, as shown
in this example, this map will serve as a convenient mechanism
for creating each FeedItem
in the following step.
private Map<RealEstatePlaceholderField, FeedAttribute> getFeed( GoogleAdsClient googleAdsClient, long customerId, String feedResourceName) { // Constructs the query. String query = "SELECT feed.attributes FROM feed WHERE feed.resource_name = '" + feedResourceName + "'"; // Constructs the request. SearchGoogleAdsRequest request = SearchGoogleAdsRequest.newBuilder() .setCustomerId(String.valueOf(customerId)) .setPageSize(PAGE_SIZE) .setQuery(query) .build(); // Issues the search request. try (GoogleAdsServiceClient googleAdsServiceClient = googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) { SearchPagedResponse searchPagedResponse = googleAdsServiceClient.search(request); // Gets the first result because we only need the single feed item we created previously. GoogleAdsRow googleAdsRow = searchPagedResponse.getPage().getResponse().getResults(0); // Gets the attributes list from the feed and creates a map with keys of each attribute and // values of each corresponding ID. List<FeedAttribute> feedAttributeList = googleAdsRow.getFeed().getAttributesList(); // Creates a map to return. Map<RealEstatePlaceholderField, FeedAttribute> feedAttributes = new HashMap<>(); // Loops through each of the feed attributes and populates the map. for (FeedAttribute feedAttribute : feedAttributeList) { switch(feedAttribute.getName().getValue()) { case "Listing ID": feedAttributes.put(RealEstatePlaceholderField.LISTING_ID, feedAttribute); break; case "Listing Name": feedAttributes.put(RealEstatePlaceholderField.LISTING_NAME, feedAttribute); break; case "Final URLs": feedAttributes.put(RealEstatePlaceholderField.FINAL_URLS, feedAttribute); break; case "Image URL": feedAttributes.put(RealEstatePlaceholderField.IMAGE_URL, feedAttribute); break; case "Contextual Keywords": feedAttributes.put(RealEstatePlaceholderField.CONTEXTUAL_KEYWORDS, feedAttribute); break; // Optionally add other RealEstatePlaceholderFields. default: throw new Error("Invalid attribute name."); } } return feedAttributes; } }
Step 2 - Construct operations to add the new listings
Now that the utility method above is in place, constructing the operations for adding new listings is straightforward. The basic steps for each new listing are:
- Get the mapping from
RealEstatePlaceholderField
to feed attribute ID using the utility method. - For each attribute of the listing (listing ID, listing name, image URL,
etc.), create a
FeedItemAttributeValue
with itsfeed_attribute_id
set to the ID of theFeedAttribute
found in the mapping for the correspondingFeedItemAttributeValue
field. - On the
FeedItemAttributeValue
, set the appropriate value for the attribute's field. For example, for listing ID, set thestring_value
field because theLISTING_ID
field has a data type ofSTRING
. - Once you have all of the
FeedItemAttributeValue
objects, create a newFeedItem
and set itsfeed
to the resource name of yourFeed
, and itsFeedItemAttributeValue
objects to the collection ofFeedItemAttributeValue
objects. - Create a new
FeedItemOperation
where thecreate
operation is set to theFeedItem
.
private void createFeedItems( GoogleAdsClient googleAdsClient, long customerId, Map<RealEstatePlaceholderField, FeedAttribute> feedAttributes, String feedResourceName) { // Creates the listing ID feed attribute value. FeedItemAttributeValue listingId = FeedItemAttributeValue.newBuilder() .setFeedAttributeId( Int64Value.of( feedAttributes.get(RealEstatePlaceholderField.LISTING_ID).getId().getValue())) .setStringValue(StringValue.of("ABC123DEF")) .build(); // Creates the listing name feed attribute value. FeedItemAttributeValue listingName = FeedItemAttributeValue.newBuilder() .setFeedAttributeId( Int64Value.of( feedAttributes.get(RealEstatePlaceholderField.LISTING_NAME).getId().getValue())) .setStringValue(StringValue.of("Two bedroom with magnificent views")) .build(); // Creates the final URLs feed attribute value. FeedItemAttributeValue finalUrls = FeedItemAttributeValue.newBuilder() .setFeedAttributeId( Int64Value.of( feedAttributes.get(RealEstatePlaceholderField.FINAL_URLS).getId().getValue())) .addStringValues(StringValue.of("http://www.example.com/listings/")) .build(); // Optionally insert additional attributes here, such as address, city, description, etc. // Creates the image URL feed attribute value. FeedItemAttributeValue imageUrl = FeedItemAttributeValue.newBuilder() .setFeedAttributeId( Int64Value.of( feedAttributes.get(RealEstatePlaceholderField.IMAGE_URL).getId().getValue())) .setStringValue( StringValue.of("http://www.example.com/listings/images?listing_id=ABC123DEF")) .build(); // Creates the contextual keywords feed attribute value. FeedItemAttributeValue finalUrl = FeedItemAttributeValue.newBuilder() .setFeedAttributeId( Int64Value.of( feedAttributes .get(RealEstatePlaceholderField.CONTEXTUAL_KEYWORDS) .getId() .getValue())) .addStringValues(StringValue.of("beach community")) .addStringValues(StringValue.of("ocean view")) .addStringValues(StringValue.of("two bedroom")) .build(); // Creates the FeedItem, specifying the Feed ID and the attributes created above. FeedItem feedItem = FeedItem.newBuilder() .setFeed(StringValue.of(feedResourceName)) .addAttributeValues(listingId) .addAttributeValues(listingName) .addAttributeValues(finalUrls) // Optionally include additional attributes. .addAttributeValues(imageUrl) .addAttributeValues(finalUrl) .build(); // Creates an operation to add the FeedItem. You can include multiple feed items in a single // operation. FeedItemOperation operation = FeedItemOperation.newBuilder().setCreate(feedItem).build(); // Creates the feed item service client. try (FeedItemServiceClient feedItemServiceClient = googleAdsClient.getLatestVersion().createFeedItemServiceClient()) { // Adds the feed items. MutateFeedItemsResponse response = feedItemServiceClient.mutateFeedItems( Long.toString(customerId), ImmutableList.of(operation)); for (MutateFeedItemResult result : response.getResultsList()) { System.out.printf("Created feed item with resource name '%s'.%n", result.getResourceName()); } } }
Step 3 - Remove sold listings
The process for removing sold listings is even simpler—all you need is
the FeedItem
resource_name
.
If you don't have the resource_name
of a sold listing, you can use the
Google Ads Query Language
to construct a query that retrieves
feed_item
fields from a
feed
with a given resource name.
The basic steps for each listing you want to remove are:
- Create a new
FeedItemOperation
and set itsremove
operation to the resource name of theFeedItem
you wish to remove. - Like any other mutate operation, pass the
FeedItemOperation
to theMutateFeedItemsRequest
.
private void runExample(GoogleAdsClient googleAdsClient, RemoveFeedItemsParams params) { List<FeedItemOperation> operations = new ArrayList<>(); // Creates the remove operations. for (long feedItemId : params.feedItemIds) { String feedItem = ResourceNames.feedItem(params.customerId, params.feedId, feedItemId); FeedItemOperation operation = FeedItemOperation.newBuilder().setRemove(feedItem).build(); operations.add(operation); } // Creates the feed item service client. try (FeedItemServiceClient feedItemServiceClient = googleAdsClient.getLatestVersion().createFeedItemServiceClient()) { // Issues the mutate request. MutateFeedItemsResponse response = feedItemServiceClient.mutateFeedItems(Long.toString(params.customerId), operations); for (MutateFeedItemResult result : response.getResultsList()) { System.out.printf("Removed feed item with resource name '%s'.%n", result.getResourceName()); } } }
Check out this complete code example, which includes the feed creation and mapping.