Google Ads API is returning to beta status. Please read our blog post for more details.

Example: Adding and removing real estate listings

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:

  1. Get the mapping from RealEstatePlaceholderField to feed attribute ID using the utility method.
  2. For each attribute of the listing (listing ID, listing name, image URL, etc.), create a FeedItemAttributeValue with its feed_attribute_id set to the ID of the FeedAttribute found in the mapping for the corresponding FeedItemAttributeValue field.
  3. On the FeedItemAttributeValue, set the appropriate value for the attribute's field. For example, for listing ID, set the string_value field because the LISTING_ID field has a data type of STRING.
  4. Once you have all of the FeedItemAttributeValue objects, create a new FeedItem and set its feed to the resource name of your Feed, and its FeedItemAttributeValue objects to the collection of FeedItemAttributeValue objects.
  5. Create a new FeedItemOperation where the create operation is set to the FeedItem.
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:

  1. Create a new FeedItemOperation and set its remove operation to the resource name of the FeedItem you wish to remove.
  2. Like any other mutate operation, pass the FeedItemOperation to the MutateFeedItemsRequest.
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.