Dynamic Remarketing

Dynamic Remarketing ads are display ads customized for each impression, showing content related to a user's previous visits to a website.

Dynamic remarketing has many benefits, including:

  • Scalability: You can create ads that scale with your products or services, when paired with your feeds.
  • Simple yet powerful feeds: Once you create the feeds, the Google Ads product recommendation engine will pull products and services, determining the best mix of products for each ad based on popularity and what the visitor viewed on your site.
  • High-performance layouts: Google Ads predicts which dynamic ad layout is likely to perform best for the person, placement and platform where the ads will show.
  • Real-time bid optimization: With enhanced CPC and conversion optimizer, Google Ads calculates the optimal bid for each impression.

There are two types of Dynamic Remarketing campaigns supported using the AdWords API: retail and non-retail. Dynamic Remarketing for retail requires the feed provided by Merchant Center, where as non-retail can be maintained using Feeds, FeedMappings and FeedItems.

Business Type Technologies required Feed configuration
Retail Merchant Center, Google Ads ShoppingSetting
Non-retail Google Ads Feed, FeedMapping, FeedItem

This guide will walk through two examples that use feeds to update Dynamic Remarketing ads.

Prerequisites

Install Global Site Tag and Remarketing Event Snippet

To implement dynamic remarketing, you need to tag your site for remarketing. You can retrieve the googleGlobalSiteTag or googleEventSnippet via the AdWords API using the ConversionTrackerService.

Here are the steps for embedding tags in your website manually:

  1. Get the global site tag and the remarketing event snippet.

    The global site tag sets a new cookie on your site which collects information about the ad click that brought a visitor to your site and adds website visitors to standard remarketing lists in your Google Ads account.

    To make sure the tagging works with dynamic remarketing, select Collect specific attributes or parameter to personalize ads during the step Create the Google Ads tag data source, as shown below:

    Detailed instructions to acquiring the global site tag and remarketing event snippet can be found at this help page

  2. Install the global site tag.

    You must install the global site tag on all the pages of your website that send remarketing information, but you need only one global site tag for each Google Ads account. The event snippet can be used to track additional actions that are to be counted as remarketing events. Install this snippet on site pages you'd like to track, right after the global site tag in the <head></head> section.

    The global site tag also works with other tags such as Google Analytics tags. To read more about how tags work in Google Analytics, you can refer to this guide.

  3. Install an event snippet on site pages you would like to track, with corresponding customer parameter values.

    Custom parameters are elements in your remarketing tag code that allow your tag to send information about specific items or selections on your website to your Google Ads account. Custom parameters are directly related to business data feeds, where you add the values that correspond to the information the tag collects.

    To use dynamic remarketing, you'll need to use the custom parameters marked as "Required" on this page.

    When you add the value of a custom parameter to your remarketing tag, it will sync with your feed to show the same product or service in your ads previously viewed by the same visitor.

    Here is an example of how to install an event snippet for a retail site (note the ecomm_prodid is the Merchant Center Product ID that corresponds to the product on the page):

    gtag('event', 'page_view', {
      ecomm_pagetype: 'product',
      ecomm_prodid: 34592212,
      ecomm_totalvalue: 29.99,
      ecomm_category: 'Home & Garden',
      isSaleItem: false
    });
    

    In addition to the standard business types, dynamic remarketing parameters also support the use of custom feed templates via the dynx_itemid, which provides more control over feed contents. Here is an example: Note: The dynx_itemid corresponds to the feed item ID of an item on the page):

    gtag('event', 'page_view', {
      dynx_itemid: ['CORS9', 'XSS7'],
      dynx_pagetype: 'conversionintent',
      dynx_totalvalue: 78.98
    });
    

    For detailed definitions of the parameters and their valid values, please refer to this guide.

    The event name you use (e.g. page_view in the above example) can be a custom event name of your choosing or one of our recommended standard events.

    It doesn’t need to match any specific value for the purpose of implementing dynamic remarketing, as long as the event data parameters (ecomm_pagetype, ecomm_prodid, ecomm_totalvalue in this example) are correctly set.

    For detailed documentation on custom parameters for different business types and how gtag.js works, refer to Dynamic Remarketing Parameters and gtag.js for Remarketing.

Feed Based Dynamic Remarketing

With feed-based dynamic remarketing, you'll create a feed of all your products or services along with attributes like unique IDs, images, and prices. Using the details from your feed to create responsive ads, dynamic remarketing shows the most relevant information in these ads to people who previously visited your website.

To implement feed based dynamic remarketing, you need the following:

  1. Set up your Dynamic Display Ad feeds through the Google Ads UI, and ensure that you have the corresponding Feed IDs.

    Alternatively, you could use the API to create a Feed, FeedMapping, and FeedItems for use with your Dynamic Remarketing ads. Refer to the Feed Placeholders page for the list of required attributes and placeholder field IDs for each type of remarketing feed.

    Read more about feed services.

    The diagram below shows the relationship among feed components and the related workflow:

  2. When setting up Google Ads tag data source, make sure to select the same business type as your feed, as shown below:

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 FeedMapping for your Feed and the Real Estate vertical's placeholder type. The FeedMapping will tell you the FeedAttribute in your Feed that corresponds to each placeholder field. The code sample below defines a method that retrieves the FeedMapping and builds a map of placeholder fieldId keys to feedAttributeId values.

/**
 * Returns a map from placeholder field ID to feed attribute ID for the given
 * combination of feed ID and placeholder type.
 */
public static Map<Integer, Long> getPlaceholderToAttributeMap(Long feedId,
    Integer placeholderType, AdWordsSession session, AdWordsServices adWordsServices)
    throws ApiException, RemoteException {
  Selector selector = new SelectorBuilder()
    .fields("AttributeFieldMappings")
    .equals("FeedId", feedId.toString())
    .equals("Status", FeedMappingStatus.ENABLED.getValue())
    .equals("PlaceholderType", placeholderType.toString())
    .build();

  // Get the FeedMappingService.
  FeedMappingServiceInterface feedMappingService =
    adWordsServices.get(session, FeedMappingServiceInterface.class);

  // Submit the 'get' request.
  FeedMapping feedMapping = feedMappingService.get(selector).getEntries(0);

  // Build a map from placeholder field ID to feed attribute ID from the FeedMapping.
  Map<Integer, Long> fieldMap = Maps.newHashMap();
  for(AttributeFieldMapping attributeFieldMapping :
      feedMapping.getAttributeFieldMappings()) {
    fieldMap.put(attributeFieldMapping.getFieldId(),
        attributeFieldMapping.getFeedAttributeId());
  }
  return fieldMap;
}

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 placeholder field ID 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 feedAttributeId set to the ID found in the mapping for the corresponding placeholder field.
  3. On the FeedItemAttributeValue, set the appropriate value field for the attribute's placeholder field. For example, for listing ID, set the stringValue 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 feedId to the ID of your Feed, and its attributeValues to the collection of FeedItemAttributeValue objects.
  5. Create a new FeedItemOperation where the operator is set to ADD and the operand is set to the FeedItem.
Long feedId = Long.valueOf("INSERT_FEED_ID_HERE");

List<FeedItemOperation> newFeedItemOperations = Lists.newArrayList();

// First, get the mapping from placeholder field ID to feed attribute ID.
// Note that 16 is the placeholder type ID for the Real Estate vertical.
Map<Integer, Long> fieldMap = getPlaceholderToAttributeMap(feedId,
  16, session, adWordsServices);

FeedItemAttributeValue listingId = new FeedItemAttributeValue();
listingId.setFeedAttributeId(fieldMap.get(1));
listingId.setStringValue("ABC123DEF");

FeedItemAttributeValue listingName = new FeedItemAttributeValue();
listingName.setFeedAttributeId(fieldMap.get(2));
listingName.setStringValue("Two bedroom with magnificent views");

FeedItemAttributeValue finalUrl = new FeedItemAttributeValue();
finalUrl.setFeedAttributeId(fieldMap.get(12));
finalUrl.setStringValues(new String[] {"http://www.example.com/listings/"});

// Insert additional attributes here, such as address, city, description, etc.

FeedItemAttributeValue imageUrl = new FeedItemAttributeValue();
imageUrl.setFeedAttributeId(fieldMap.get(8));
imageUrl.setStringValue("http://www.example.com/listings/images?listing_id=ABC123DEF");

FeedItemAttributeValue contextualKeywords = new FeedItemAttributeValue();
contextualKeywords.setFeedAttributeId(fieldMap.get(11));
contextualKeywords.setStringValues(
    new String[] {"beach community", "ocean view", "two bedroom"});

// Create the FeedItem, specifying the Feed ID and the attributes created above.
FeedItem feedItem = new FeedItem();
feedItem.setFeedId(feedId);
feedItem.setAttributeValues(new FeedItemAttributeValue[]{
    listingId,
    listingName,
    finalUrl,
    // Include additional attributes...
    imageUrl,
    contextualKeywords});

// Create an operation to add each FeedItem.
FeedItemOperation feedItemOperation = new FeedItemOperation();
feedItemOperation.setOperator(Operator.ADD);
feedItemOperation.setOperand(feedItem);
newFeedItemOperations.add(feedItemOperation);

// Repeat the above for additional new listings.

Step 3 - Construct operations to remove sold listings

The process for removing sold listings is even simpler—all you need are the feedId and the feedItemId of each sold listing.

The basic steps for each listing you want to remove are:

  1. Create a new FeedItem and set its feedId to the ID of your Feed, and its feedItemId to the listing's item ID.
  2. Create a new FeedItemOperation where the operator is set to REMOVE and the operand is set to the FeedItem.
Long feedId = Long.valueOf("INSERT_FEED_ID_HERE");

List<Long> feedItemIds = Lists.newArrayList(
    // feed item ID 1,
    // feed item ID 2,
    // ...
    );

List<FeedItemOperation> removeFeedItemOperations = Lists.newArrayList();
for(Long feedItemId : feedItemIds) {
  // When removing you can simply specify the feedId and the feedItemId.
  FeedItem feedItemToRemove = new FeedItem();

  feedItemToRemove.setFeedId(feedId);
  feedItemToRemove.setFeedItemId(feedItemId);

  FeedItemOperation removeOperation = new FeedItemOperation();
  removeOperation.setOperator(Operator.REMOVE);
  removeOperation.setOperand(feedItemToRemove);

  removeFeedItemOperations.add(removeOperation);
}

Step 4 - Submit the add and remove operations

This step is just like any other mutate operation in the API. To actually apply the changes, simply pass the union of the two collections of FeedItemOperations you created above to FeedItemService.mutate().

// Get the FeedItemService
FeedItemServiceInterface feedItemService =
    adWordsServices.get(session, FeedItemServiceInterface.class);

// Combine the lists of operations.
List<FeedItemOperation> allOperations = Lists.newArrayList(newFeedItemOperations);
allOperations.addAll(removeFeedItemOperations);

// Pass the collection of FeedItemOperations to the mutate method.
FeedItemReturnValue itemsUpdateReturnValue =
    feedItemService.mutate(allOperations.toArray(new FeedItemOperation[allOperations.size()]));

System.out.printf("Updated %d items%n", itemsUpdateReturnValue.getValue().length);

Example: Updating flight prices

Assume you have a flight reservation site where you've set up Dynamic Remarketing ads, and you want to update the sale price on some flights and remove the sale price on others. To ensure that your ads display the correct prices for each flight, you'll want to update the price on each flight's corresponding FeedItem.

Step 1 - Construct operations to update the sale prices

This is similar to creating new FeedItems, except you can just specify the FeedItemAttributeValue you want to modify, and the placeholder field IDs will come from the list of fields for the Flights vertical.

The basic steps for each flight entry to modify are:

  1. Get the mapping from placeholder field ID to feed attribute ID using the utility method.
  2. For each attribute of the flight (sale price, flight price, etc.), create a FeedItemAttributeValue with its feedAttributeId set to the ID found in the mapping for the corresponding placeholder field.
  3. On the FeedItemAttributeValue, set the appropriate value field for the attribute's placeholder field.
  4. Once you have all of the FeedItemAttributeValues, create a new FeedItem and set its feedId to the ID of your Feed, its feedItemId to the ID of the flight's feed item ID, and its attributeValues to the collection of FeedItemAttributeValues.
  5. Create a new FeedItemOperation where the operator is set to SET and the operand is set to the FeedItem.
Long feedId = Long.valueOf("INSERT_FEED_ID_HERE");

List<FeedItemOperation> updateFeedItemOperations = Lists.newArrayList();

// First, get the mapping from placeholder field ID to feed attribute ID.
// Note that 13 is the placeholder type ID for the Flights vertical.
Map<Integer, Long> fieldMap = getPlaceholderToAttributeMap(feedId,
  13, session, adWordsServices);

// Update the sale price on the first flight
Long newSalePriceFeedItemId = Long.valueOf("INSERT_FEED_ITEM_ID");
FeedItemAttributeValue salePrice = new FeedItemAttributeValue();
salePrice.setFeedAttributeId(fieldMap.get(12));
salePrice.setStringValue("1,309.89 USD");

FeedItem feedItemForNewSalePrice = new FeedItem();
feedItemForNewSalePrice.setFeedId(feedId);
feedItemForNewSalePrice.setFeedItemId(newSalePriceFeedItemId);
feedItemForNewSalePrice.setAttributeValues(new FeedItemAttributeValue[] {salePrice});

// Clear the sale price on the second flight, and update its regular price
Long removedSalePriceFeedItemId = Long.valueOf("INSERT_FEED_ITEM_ID");
FeedItemAttributeValue removedSalePrice = new FeedItemAttributeValue();
removedSalePrice.setFeedAttributeId(fieldMap.get(12));

FeedItemAttributeValue newFlightPrice = new FeedItemAttributeValue();
newFlightPrice.setFeedAttributeId(fieldMap.get(6));
newFlightPrice.setStringValue("499.99 USD");

FeedItem feedItemForRemovedSalePrice = new FeedItem();
feedItemForRemovedSalePrice.setFeedId(feedId);
feedItemForRemovedSalePrice.setFeedItemId(removedSalePriceFeedItemId);
feedItemForRemovedSalePrice.setAttributeValues(
    new FeedItemAttributeValue[] {removedSalePrice, newFlightPrice});

// Create the FeedItemOperations to update the FeedItems.
for(FeedItem feedItemToUpdate : new FeedItem[]{ feedItemForNewSalePrice,
                                                feedItemForRemovedSalePrice}) {
  FeedItemOperation updateFeedItemOperation = new FeedItemOperation();
  updateFeedItemOperation.setOperator(Operator.SET);
  updateFeedItemOperation.setOperand(feedItemToUpdate);

  updateFeedItemOperations.add(updateFeedItemOperation);
}

Step 2 - Submit the update operations

As with the add and remove operations, to actually apply these changes, simply pass the collection of FeedItemOperations you created above to FeedItemService.mutate().

Merchant center-based dynamic remarketing

To implement merchant center-based dynamic remarketing, you need the following:

  1. Merchant Center account linked to a Google Ads account.
  2. Approved products in your Merchant Center feed.
  3. When setting up a Google Ads tag data source, make sure to select “Retail” as the Business Type.

Read more about creating a product feed in the merchant center.

Additionally, feed creation can be automated via Content API for Shopping.

Example: Creating a dynamic remarketing campaign with Google Merchant Center

So you have a retail site that uploads product listings to Google Merchant Center and you want to remarket groups of products to users who visited the retail site. These users might have visited a product page or placed an item in a basket or checkout, recorded by the triggering of a remarketing tag. You can then create a campaign to target only this group or expand to similar audiences to increase your reach.

Read more about audience list generation best practices.

You will need the following to set up such a campaign:

  1. Remarketing List.
  2. Merchant Center account.
  3. Product Feed from Merchant Center.
  4. Media required for Responsive Ads for Display.

Here is the list of ad creatives that support Merchant Center product feeds: * Responsive Display Ads * Multi-Asset Responsive Display Ads

Step 1 - Create a campaign linked to a Merchant Center product feed

In order to be able to remarket retail products, you'll need to create a campaign targeting the Display Network. This will require the following:

  • A Budget to specify how much the campaign is able to spend.
  • A BiddingStrategyConfiguration to configure how the campaign will be configured to bid.
  • A remarketing list including the list of users to target with the campaign.
  • A ShoppingSetting to specify which Merchant Center account the product feed will be used for the campaign.

The basic steps for configuring the campaign are:

  1. Create a new campaign, setting the AdvertisingChannelType to DISPLAY.
  2. Set the Budget for the campaign. This can be a newly created budget or a shared budget.
  3. Set the BiddingStrategyConfiguration for the campaign. The different types of strategies available for Dynamic Remarketing campaigns can be found here.
  4. Set the ShoppingSetting for the campaign. Note: CampaignService is used here, rather than AdGroupService, since the feed must be attached at campaign level.

  5. Apply the mutate operation to ADD the new campaign to the account.

Code Example:

C#

private static Campaign CreateCampaign(AdWordsUser user, long merchantId, long budgetId)
{
    using (CampaignService campaignService =
        (CampaignService) user.GetService(AdWordsService.v201809.CampaignService))
    {
        Campaign campaign = new Campaign
        {
            name = "Shopping campaign #" + ExampleUtilities.GetRandomString(),
            // Dynamic remarketing campaigns are only available on the Google Display
            // Network.
            advertisingChannelType = AdvertisingChannelType.DISPLAY,
            status = CampaignStatus.PAUSED
        };

        Budget budget = new Budget
        {
            budgetId = budgetId
        };
        campaign.budget = budget;

        // This example uses a Manual CPC bidding strategy, but you should select the
        // strategy that best aligns with your sales goals. More details here:
        //   https://support.google.com/adwords/answer/2472725
        BiddingStrategyConfiguration biddingStrategyConfiguration =
            new BiddingStrategyConfiguration
            {
                biddingStrategyType = BiddingStrategyType.MANUAL_CPC
            };
        campaign.biddingStrategyConfiguration = biddingStrategyConfiguration;

        ShoppingSetting setting = new ShoppingSetting
        {
            // Campaigns with numerically higher priorities take precedence over those with
            // lower priorities.
            campaignPriority = 0,

            // Set the Merchant Center account ID from which to source products.
            merchantId = merchantId,

            // Display Network campaigns do not support partition by country. The only
            // supported value is "ZZ". This signals that products from all countries are
            // available in the campaign. The actual products which serve are based on the
            // products tagged in the user list entry.
            salesCountry = "ZZ",

            // Optional: Enable local inventory ads (items for sale in physical stores.)
            enableLocal = true
        };

        campaign.settings = new Setting[]
        {
            setting
        };

        CampaignOperation op = new CampaignOperation
        {
            operand = campaign,
            @operator = Operator.ADD
        };

        CampaignReturnValue result = campaignService.mutate(new CampaignOperation[]
        {
            op
        });
        return result.value[0];
    }
}

Java

private static Campaign createCampaign(
    AdWordsServicesInterface services, AdWordsSession session, long merchantId, long budgetId)
    throws RemoteException {
  CampaignServiceInterface campaignService =
      services.get(session, CampaignServiceInterface.class);

  Campaign campaign = new Campaign();
  campaign.setName("Shopping campaign #" + System.currentTimeMillis());
  // Dynamic remarketing campaigns are only available on the Google Display Network.
  campaign.setAdvertisingChannelType(AdvertisingChannelType.DISPLAY);
  campaign.setStatus(CampaignStatus.PAUSED);

  Budget budget = new Budget();
  budget.setBudgetId(budgetId);
  campaign.setBudget(budget);

  // This example uses a Manual CPC bidding strategy, but you should select the strategy that best
  // aligns with your sales goals. More details here:
  //   https://support.google.com/adwords/answer/2472725
  BiddingStrategyConfiguration biddingStrategyConfiguration = new BiddingStrategyConfiguration();
  biddingStrategyConfiguration.setBiddingStrategyType(BiddingStrategyType.MANUAL_CPC);
  campaign.setBiddingStrategyConfiguration(biddingStrategyConfiguration);

  ShoppingSetting setting = new ShoppingSetting();
  // Campaigns with numerically higher priorities take precedence over those with lower
  // priorities.
  setting.setCampaignPriority(0);

  // Set the Merchant Center account ID from which to source products.
  setting.setMerchantId(merchantId);

  // Display Network campaigns do not support partition by country. The only supported value is
  // "ZZ". This signals that products from all countries are available in the campaign. The actual
  // products which serve are based on the products tagged in the user list entry.
  setting.setSalesCountry("ZZ");

  // Optional: Enable local inventory ads (items for sale in physical stores.)
  setting.setEnableLocal(true);

  campaign.setSettings(new Setting[] {setting});

  CampaignOperation op = new CampaignOperation();
  op.setOperand(campaign);
  op.setOperator(Operator.ADD);

  CampaignReturnValue result = campaignService.mutate(new CampaignOperation[] {op});
  return result.getValue(0);
}

Python

def CreateCampaign(client, merchant_id, budget_id):
  """Creates a new Display Network campaign.

  Args:
    client: an AdWordsClient instance.
    merchant_id: a int merchant center ID.
    budget_id: a int budget ID.

  Returns:
    The campaign that was successfully created.
  """
  campaign_service = client.GetService('CampaignService', 'v201809')

  campaign = {
      'name': 'Shopping campaign #%d' % uuid.uuid4(),
      # Dynamic remarketing campaigns are only available on the Google Display
      # Network.
      'advertisingChannelType': 'DISPLAY',
      'status': 'PAUSED',
      'budget': {
          'budgetId': budget_id
      },
      # This example uses a Manual CPC bidding strategy, but you should select
      # the strategy that best aligns with your sales goals. More details here:
      # https://support.google.com/adwords/answer/2472725
      'biddingStrategyConfiguration': {
          'biddingStrategyType': 'MANUAL_CPC'
      },
      'settings': [{
          'xsi_type': 'ShoppingSetting',
          # Campaigns with numerically higher priorities take precedence over
          # those with lower priorities.
          'campaignPriority': 0,
          'merchantId': merchant_id,
          # Display network campaigns do not support partition by country. The
          # only supported value is "ZZ". This signals that products from all
          # countries are available in this campaign. The actual products which
          # serve are based on the products tagged in the user list entry.
          'salesCountry': 'ZZ',
          # Optional: Enable local inventory ads (items for sale in physical
          # stores.)
          'enableLocal': True,
      }]
  }

  operations = [{
      'operator': 'ADD',
      'operand': campaign
  }]

  return campaign_service.mutate(operations)['value'][0]

PHP

private static function createCampaign(
    AdWordsServices $adWordsServices,
    AdWordsSession $session,
    $budgetId,
    $merchantId
) {
    $campaignService =
        $adWordsServices->get($session, CampaignService::class);

    // Create a campaign.
    $campaign = new Campaign();
    $campaign->setName('Shopping campaign #' . uniqid());
    // Dynamic remarketing campaigns are only available on the Google
    // Display Network.
    $campaign->setAdvertisingChannelType(AdvertisingChannelType::DISPLAY);

    // Recommendation: Set the campaign to PAUSED when creating it to
    // prevent the ads from immediately serving. Set to ENABLED once you've
    // added targeting and the ads are ready to serve.
    $campaign->setStatus(CampaignStatus::PAUSED);

    // Set shared budget (required).
    $budget = new Budget();
    $budget->setBudgetId($budgetId);
    $campaign->setBudget($budget);

    // This example uses a Manual CPC bidding strategy, but you should
    // select the strategy that best aligns with your sales goals. More
    // details here: https://support.google.com/adwords/answer/2472725.
    $biddingStrategyConfiguration = new BiddingStrategyConfiguration();
    $biddingStrategyConfiguration->setBiddingStrategyType(
        BiddingStrategyType::MANUAL_CPC
    );
    $campaign->setBiddingStrategyConfiguration(
        $biddingStrategyConfiguration
    );

    // All Shopping campaigns need a ShoppingSetting.
    $shoppingSetting = new ShoppingSetting();
    // Campaigns with numerically higher priorities take precedence over
    // those with lower priorities.
    $shoppingSetting->setCampaignPriority(0);

    // Set the Merchant Center account ID from which to source products.
    $shoppingSetting->setMerchantId($merchantId);

    // Display Network campaigns do not support partition by country. The
    // only supported value is "ZZ". This signals that products from all
    // countries are available in the campaign. The actual products which
    // serve are based on the products tagged in the user list entry.
    $shoppingSetting->setSalesCountry('ZZ');

    // Enable local inventory ads (items for sale in physical stores.)
    $shoppingSetting->setEnableLocal(true);

    $campaign->setSettings([$shoppingSetting]);

    // Creates operation.
    $campaignOperation = new CampaignOperation();
    $campaignOperation->setOperand($campaign);
    $campaignOperation->setOperator(Operator::ADD);

    // Makes the mutate request.
    $campaignAddResult = $campaignService->mutate([$campaignOperation]);
    $campaign = $campaignAddResult->getValue()[0];

    return $campaign;
}

Perl

sub _create_campaign {
  my ($client, $merchant_id, $budget_id) = @_;

  my $campaign = Google::Ads::AdWords::v201809::Campaign->new({
      name => sprintf("Shopping campaign #%s", uniqid()),
      # Dynamic remarketing campaigns are only available on the Google Display
      # Network.
      advertisingChannelType => "DISPLAY",
      status                 => "PAUSED",
      budget =>
        Google::Ads::AdWords::v201809::Budget->new({budgetId => $budget_id}),
      # This example uses a Manual CPC bidding strategy, but you should select
      # the strategy that best aligns with your sales goals. More details here:
      # https://support.google.com/adwords/answer/2472725
      biddingStrategyConfiguration =>
        Google::Ads::AdWords::v201809::BiddingStrategyConfiguration->new({
          biddingStrategyType => "MANUAL_CPC"
        }
        ),
      settings => [
        Google::Ads::AdWords::v201809::ShoppingSetting->new({
            # Campaigns with numerically higher priorities take precedence over
            # those with lower priorities.
            campaignPriority => 0,
            # Set the Merchant Center account ID from which to source products.
            merchantId => $merchant_id,
            # Display Network campaigns do not support partition by country.
            # The only supported value is "ZZ". This signals that products
            # from all countries are available in the campaign. The actual
            # products which serve are based on the products tagged in the user
            # list entry.
            salesCountry => "ZZ",
            # Optional: Enable local inventory ads (items for sale in physical
            # stores.)
            enableLocal => 1
          })
      ],
    });

  # Create operation.
  my $campaign_operation =
    Google::Ads::AdWords::v201809::CampaignOperation->new({
      operator => "ADD",
      operand  => $campaign
    });

  my $result =
    $client->CampaignService()->mutate({operations => [$campaign_operation]});
  return $result->get_value()->[0];
}

Ruby

def create_campaign(adwords, merchant_id, budget_id)
  campaign_srv = adwords.service(:CampaignService, API_VERSION)

  campaign = {
    :name => 'Shopping campaign #%d' % (Time.new.to_f * 1000).to_i,
    # Dynamic remarketing campaigns are only available on the Google Display
    # Network
    :advertising_channel_type => 'DISPLAY',
    :status => 'PAUSED',
    :budget => {
      :budget_id => budget_id
    },
    # This example uses a Manual CPC bidding strategy, but you should select the
    # strategy that best aligns with your sales goals. More details here:
    # https://support.google.com/adwords/answer/2472725
    :bidding_strategy_configuration => {
      :bidding_strategy_type => 'MANUAL_CPC'
    },
    :settings => [{
      :xsi_type => 'ShoppingSetting',
      # Campaigns with numerically higher priorities take precedence over those
      # with lower priorities.
      :campaign_priority => 0,
      # Set the Merchant Center account ID from which to source products.
      :merchant_id => merchant_id,
      # Display Network campaigns do not support partition by country. The only
      # supported value is "ZZ". This signals that products from all countries
      # are available in the campaign. The actual products which serve are based
      # on the products tagged in the user list entry.
      :sales_country => 'ZZ',
      # Optional: Enable local inventory ads (items for sale in physical
      # stores.)
      :enable_local => true
    }]
  }

  operation = {
    :operator => 'ADD',
    :operand => campaign
  }

  result = campaign_srv.mutate([operation])
  return result[:value].first
end

Step 2 - Create an ad group for the remarketing campaign

Code Example:

C#

private static AdGroup CreateAdGroup(AdWordsUser user, Campaign campaign)
{
    using (AdGroupService adGroupService =
        (AdGroupService) user.GetService(AdWordsService.v201809.AdGroupService))
    {
        AdGroup group = new AdGroup
        {
            name = "Dynamic remarketing ad group",
            campaignId = campaign.id,
            status = AdGroupStatus.ENABLED
        };

        AdGroupOperation op = new AdGroupOperation
        {
            operand = group,
            @operator = Operator.ADD
        };
        AdGroupReturnValue result = adGroupService.mutate(new AdGroupOperation[]
        {
            op
        });
        return result.value[0];
    }
}

Java

private static AdGroup createAdGroup(
    AdWordsServicesInterface services, AdWordsSession session, Campaign campaign)
    throws RemoteException {
  AdGroupServiceInterface adGroupService = services.get(session, AdGroupServiceInterface.class);

  AdGroup group = new AdGroup();
  group.setName("Dynamic remarketing ad group");
  group.setCampaignId(campaign.getId());
  group.setStatus(AdGroupStatus.ENABLED);

  AdGroupOperation op = new AdGroupOperation();
  op.setOperand(group);
  op.setOperator(Operator.ADD);
  AdGroupReturnValue result = adGroupService.mutate(new AdGroupOperation[] {op});
  return result.getValue(0);
}

Python

def CreateAdGroup(client, campaign_id):
  """Creates a dynamic remarketing campaign.

  Args:
    client: an AdWordsClient instance.
    campaign_id: an int campaign ID.

  Returns:
    The ad group that was successfully created.
  """
  ad_group_service = client.GetService('AdGroupService', 'v201809')

  ad_group = {
      'name': 'Dynamic remarketing ad group',
      'campaignId': campaign_id,
      'status': 'ENABLED'
  }

  operations = [{
      'operator': 'ADD',
      'operand': ad_group
  }]

  return ad_group_service.mutate(operations)['value'][0]

PHP

private static function createAdGroup(
    AdWordsServices $adWordsServices,
    AdWordsSession $session,
    Campaign $campaign
) {
    $adGroupService =
        $adWordsServices->get($session, AdGroupService::class);

    // Creates ad group.
    $adGroup = new AdGroup();
    $adGroup->setCampaignId($campaign->getId());
    $adGroup->setName('Dynamic remarketing ad group #' . uniqid());
    $adGroup->setStatus(AdGroupStatus::ENABLED);

    // Creates operation.
    $adGroupOperation = new AdGroupOperation();
    $adGroupOperation->setOperand($adGroup);
    $adGroupOperation->setOperator(Operator::ADD);

    // Makes the mutate request.
    $adGroupAddResult = $adGroupService->mutate([$adGroupOperation]);
    $adGroup = $adGroupAddResult->getValue()[0];

    return $adGroup;
}

Perl

sub _create_ad_group {
  my ($client, $campaign) = @_;

  my $ad_group = Google::Ads::AdWords::v201809::AdGroup->new({
    name       => sprintf("Dynamic remarketing ad group"),
    campaignId => $campaign->get_id(),
    status     => "ENABLED"
  });

  my $ad_group_operation =
    Google::Ads::AdWords::v201809::AdGroupOperation->new({
      operator => "ADD",
      operand  => $ad_group
    });

  my $result =
    $client->AdGroupService()->mutate({operations => [$ad_group_operation]});
  return $result->get_value()->[0];
}

Ruby

def create_ad_group(adwords, campaign)
  ad_group_srv = adwords.service(:AdGroupService, API_VERSION)

  ad_group = {
    :name => 'Dynamic remarketing ad group',
    :campaign_id => campaign[:id],
    :status => 'ENABLED'
  }

  operation = {
    :operator => 'ADD',
    :operand => ad_group
  }

  result = ad_group_srv.mutate([operation])
  return result[:value].first
end

Step 3 - Create a responsive ad for display

Code Example:

C#

private static AdGroupAd CreateAd(AdWordsUser user, AdGroup adGroup)
{
    using (AdGroupAdService adService =
        (AdGroupAdService) user.GetService(AdWordsService.v201809.AdGroupAdService))
    {
        ResponsiveDisplayAd ad = new ResponsiveDisplayAd
        {
            // This ad format does not allow the creation of an image using the
            // Image.data field. An image must first be created using the MediaService,
            // and Image.mediaId must be populated when creating the ad.
            marketingImage = UploadImage(user, "https://goo.gl/3b9Wfh"),

            shortHeadline = "Travel",
            longHeadline = "Travel the World",
            description = "Take to the air!",
            businessName = "Interplanetary Cruises",
            finalUrls = new string[]
            {
                "http://www.example.com/"
            },

            // Optional: Call to action text.
            // Valid texts: https://support.google.com/adwords/answer/7005917
            callToActionText = "Apply Now",

            // Optional: Set dynamic display ad settings, composed of landscape logo
            // image, promotion text, and price prefix.
            dynamicDisplayAdSettings = CreateDynamicDisplayAdSettings(user),

            // Optional: Create a logo image and set it to the ad.
            logoImage = UploadImage(user, "https://goo.gl/mtt54n"),

            // Optional: Create a square marketing image and set it to the ad.
            squareMarketingImage = UploadImage(user, "https://goo.gl/mtt54n")
        };

        // Whitelisted accounts only: Set color settings using hexadecimal values.
        // Set allowFlexibleColor to false if you want your ads to render by always
        // using your colors strictly.
        // ad.mainColor = "#0000ff";
        // ad.accentColor = "#ffff00";
        // ad.allowFlexibleColor = false;

        // Whitelisted accounts only: Set the format setting that the ad will be
        // served in.
        // ad.formatSetting = DisplayAdFormatSetting.NON_NATIVE;

        AdGroupAd adGroupAd = new AdGroupAd
        {
            ad = ad,
            adGroupId = adGroup.id
        };

        AdGroupAdOperation op = new AdGroupAdOperation
        {
            operand = adGroupAd,
            @operator = Operator.ADD
        };

        AdGroupAdReturnValue result = adService.mutate(new AdGroupAdOperation[]
        {
            op
        });
        return result.value[0];
    }
}

Java

private static AdGroupAd createAd(
    AdWordsServicesInterface services, AdWordsSession session, AdGroup adGroup)
    throws IOException {
  AdGroupAdServiceInterface adService = services.get(session, AdGroupAdServiceInterface.class);

  ResponsiveDisplayAd ad = new ResponsiveDisplayAd();

  // This ad format does not allow the creation of an image using the
  // Image.data field. An image must first be created using the MediaService,
  // and Image.mediaId must be populated when creating the ad.
  ad.setMarketingImage(uploadImage(services, session, "https://goo.gl/3b9Wfh"));

  ad.setShortHeadline("Travel");
  ad.setLongHeadline("Travel the World");
  ad.setDescription("Take to the air!");
  ad.setBusinessName("Interplanetary Cruises");
  ad.setFinalUrls(new String[] {"http://www.example.com/"});

  // Optional: Call to action text.
  // Valid texts: https://support.google.com/adwords/answer/7005917
  ad.setCallToActionText("Apply Now");

  // Optional: Set dynamic display ad settings, composed of landscape logo
  // image, promotion text, and price prefix.
  DynamicSettings dynamicDisplayAdSettings = createDynamicDisplayAdSettings(services, session);
  ad.setDynamicDisplayAdSettings(dynamicDisplayAdSettings);

  Image optionalImage = uploadImage(services, session, "https://goo.gl/mtt54n");

  // Optional: Create a logo image and set it to the ad.
  ad.setLogoImage(optionalImage);

  // Optional: Create a square marketing image and set it to the ad.
  ad.setSquareMarketingImage(optionalImage);

  // Whitelisted accounts only: Set color settings using hexadecimal values.
  // Set allowFlexibleColor to false if you want your ads to render by always
  // using your colors strictly.
  /*
  ad.setMainColor("#0000ff");
  ad.setAccentColor("#ffff00");
  ad.setAllowFlexibleColor(false);
  */

  // Whitelisted accounts only: Set the format setting that the ad will be
  // served in.
  /*
  ad.setFormatSetting(
      com.google.api.ads.adwords.axis.v201809.cm.DisplayAdFormatSetting.NON_NATIVE);
  */

  AdGroupAd adGroupAd = new AdGroupAd();
  adGroupAd.setAd(ad);
  adGroupAd.setAdGroupId(adGroup.getId());

  AdGroupAdOperation op = new AdGroupAdOperation();
  op.setOperand(adGroupAd);
  op.setOperator(Operator.ADD);

  AdGroupAdReturnValue result = adService.mutate(new AdGroupAdOperation[] {op});
  return result.getValue(0);
}

Python

def CreateAd(client, opener, ad_group_id):
  """Creates a ResponsiveDisplayAd.

  Args:
    client: an AdWordsClient instance.
    opener: an OpenerDirector instance.
    ad_group_id: an int ad group ID.

  Returns:
    The ad group ad that was successfully created.
  """
  ad_group_ad_service = client.GetService('AdGroupAdService', 'v201809')
  media_service = client.GetService('MediaService', 'v201809')

  marketing_image_id = _CreateImage(
      media_service, opener, 'https://goo.gl/3b9Wfh')
  logo_image_id = _CreateImage(media_service, opener, 'https://goo.gl/mtt54n')

  ad = {
      'xsi_type': 'ResponsiveDisplayAd',
      # This ad format doesn't allow the creation of an image using the
      # Image.data field. An image must first be created using the MediaService,
      # and Image.mediaId must be populated when creating the ad.
      'marketingImage': {
          'xsi_type': 'Image',
          'mediaId': marketing_image_id
      },
      'shortHeadline': 'Travel',
      'longHeadline': 'Travel the World',
      'description': 'Take to the air!',
      'businessName': 'Interplanetary Cruises',
      'finalUrls': ['http://wwww.example.com'],
      # Optional: Call to action text.
      # Valid texts: https://support.google.com/adwords/answer/7005917
      'callToActionText': 'Apply Now',
      # Optional: Set dynamic display ad settings, composed of landscape logo
      # image, promotion text, and price prefix.
      'dynamicDisplayAdSettings': CreateDynamicDisplayAdSettings(
          client, opener),
      # Optional: Create a logo image and set it to the ad.
      'logoImage': {
          'xsi_type': 'Image',
          'mediaId': logo_image_id
      },
      # Optional: Create a square marketing image and set it to the ad.
      'squareMarketingImage': {
          'xsi_type': 'Image',
          'mediaId': logo_image_id
      },
      # Whitelisted accounts only: Set color settings using hexadecimal values.
      # Set allowFlexibleColor to False if you want your ads to render by always
      # using your colors strictly.
      # 'mainColor': '#000fff',
      # 'accentColor': '#fff000',
      # 'allowFlexibleColor': False,
      # Whitelisted accounts only: Set the format setting that the ad will be
      # served in.
      # 'formatSetting': 'NON_NATIVE'
  }

  ad_group_ad = {
      'ad': ad,
      'adGroupId': ad_group_id
  }

  operations = [{
      'operation': 'ADD',
      'operand': ad_group_ad
  }]

  return ad_group_ad_service.mutate(operations)['value'][0]

PHP

private static function createAd(
    AdWordsServices $adWordsServices,
    AdWordsSession $session,
    AdGroup $adGroup
) {
    $adGroupAdService =
        $adWordsServices->get($session, AdGroupAdService::class);

    $responsiveDisplayAd = new ResponsiveDisplayAd();

    // This ad format does not allow the creation of an image using the
    // Image.data field. An image must first be created using the
    // MediaService and Image.mediaId must be populated when creating the
    // ad.
    $marketingImage = self::uploadImage(
        $adWordsServices,
        $session,
        'https://goo.gl/3b9Wfh'
    );
    $responsiveDisplayAd->setMarketingImage($marketingImage);

    $responsiveDisplayAd->setShortHeadline('Travel');
    $responsiveDisplayAd->setLongHeadline('Travel the World.');
    $responsiveDisplayAd->setDescription('Take to the air!');
    $responsiveDisplayAd->setBusinessName('Interplanetary Cruises');
    $responsiveDisplayAd->setFinalUrls(['http://www.example.com']);

    // Optional: Set the call-to-action text.
    // Valid texts: https://support.google.com/adwords/answer/7005917.
    $responsiveDisplayAd->setCallToActionText('Apply Now');

    // Optional: Set dynamic display ad settings, composed of landscape logo
    // image, promotion text, and price prefix.
    $dynamicDisplayAdSettings =
        self::createDynamicDisplayAdSettings($adWordsServices, $session);
    $responsiveDisplayAd->setDynamicDisplayAdSettings(
        $dynamicDisplayAdSettings
    );

    // Optional: Creates a square marketing image using MediaService, and
    // set it to the ad.
    $squareMarketingImage = self::uploadImage(
        $adWordsServices,
        $session,
        'https://goo.gl/mtt54n'
    );
    $responsiveDisplayAd->setSquareMarketingImage($squareMarketingImage);

    // Optional: Set the logo image.
    $logoImage = self::uploadImage(
        $adWordsServices,
        $session,
        'https://goo.gl/mtt54n'
    );
    $responsiveDisplayAd->setLogoImage($logoImage);

    // Whitelisted accounts only: Set color settings using hexadecimal
    // values. Set allowFlexibleColor to false if you want your ads to
    // render by always using your colors strictly.
    /*
    $responsiveDisplayAd->setMainColor('#0000ff');
    $responsiveDisplayAd->setAccentColor('#ffff00');
    $responsiveDisplayAd->setFlexibleColor(false);
    */

    // Whitelisted accounts only: Set the format setting that the ad will be
    // served in.
    /*
    $responsiveDisplayAd->setFormatSetting(
        \Google\AdsApi\AdWords\v201809\cm\DisplayAdFormatSetting::NON_NATIVE
    );
    */

    // Creates ad group ad.
    $adGroupAd = new AdGroupAd();
    $adGroupAd->setAdGroupId($adGroup->getId());
    $adGroupAd->setAd($responsiveDisplayAd);

    // Create an ad group ad operation.
    $adGroupAdOperation = new AdGroupAdOperation();
    $adGroupAdOperation->setOperand($adGroupAd);
    $adGroupAdOperation->setOperator(Operator::ADD);

    // Creates an ad group ad on the server.
    $adGroupAdAddResult = $adGroupAdService->mutate([$adGroupAdOperation]);
    $adGroupAd = $adGroupAdAddResult->getValue()[0];

    return $adGroupAd;
}

Perl

sub _create_ad {
  my ($client, $ad_group) = @_;

  # This ad format does not allow the creation of an image using the
  # Image.data field. An image must first be created using the MediaService,
  # and Image.mediaId must be populated when creating the ad.
  my $ad_image = _upload_image($client, "https://goo.gl/3b9Wfh");
  my $marketing_image = Google::Ads::AdWords::v201809::Image->new(
    {mediaId => $ad_image->get_mediaId()});

  # Create the responsive display ad.
  my $responsive_display_ad =
    Google::Ads::AdWords::v201809::ResponsiveDisplayAd->new({
      marketingImage => $marketing_image,
      shortHeadline  => "Travel",
      longHeadline   => "Travel the World",
      description    => "Take to the air!",
      businessName   => "Interplanetary Cruises",
      finalUrls      => ["http://www.example.com/"]});

  # Optional: Call to action text.
  # Valid texts: https://support.google.com/adwords/answer/7005917
  $responsive_display_ad->set_callToActionText("Apply Now");

  # Optional: Set dynamic display ad settings, composed of landscape logo
  # image, promotion text, and price prefix.
  my $dynamic_settings = _create_dynamic_display_ad_settings($client);
  $responsive_display_ad->set_dynamicDisplayAdSettings($dynamic_settings);

  # Optional: Create a logo image and set it to the ad.
  my $logo_image = _upload_image($client, "https://goo.gl/mtt54n");
  my $logo_marketing_image = Google::Ads::AdWords::v201809::Image->new(
    {mediaId => $logo_image->get_mediaId()});
  $responsive_display_ad->set_logoImage($logo_marketing_image);

  # Optional: Create a square marketing image and set it to the ad.
  my $square_image = _upload_image($client, "https://goo.gl/mtt54n");
  my $square_marketing_image = Google::Ads::AdWords::v201809::Image->new(
    {mediaId => $square_image->get_mediaId()});
  $responsive_display_ad->set_squareMarketingImage($square_marketing_image);

  # Whitelisted accounts only: Set color settings using hexadecimal values.
  # Set allowFlexibleColor to false if you want your ads to render by always
  # using your colors strictly.
  # $responsiveDisplayAd->set_mainColor("#0000ff");
  # $responsiveDisplayAd->set_accentColor("#ffff00");
  # $responsiveDisplayAd->set_allowFlexibleColor(0);

  # Whitelisted accounts only: Set the format setting that the ad will be
  # served in.
  # $responsiveDisplayAd->set_formatSetting("NON_NATIVE");

  # Create ad group ad for the responsive display ad.
  my $responsive_display_ad_group_ad =
    Google::Ads::AdWords::v201809::AdGroupAd->new({
      adGroupId => $ad_group->get_id(),
      ad        => $responsive_display_ad
    });

  my $responsive_display_ad_group_ad_operation =
    Google::Ads::AdWords::v201809::AdGroupAdOperation->new({
      operator => "ADD",
      operand  => $responsive_display_ad_group_ad
    });

  my $result =
    $client->AdGroupAdService()
    ->mutate({operations => [$responsive_display_ad_group_ad_operation]});
  return $result->get_value()->[0];
}

Ruby

def create_ad(adwords, ad_group)
  ad_srv = adwords.service(:AdGroupAdService, API_VERSION)

  optional_media_id = upload_image(adwords, 'https://goo.gl/mtt54n')

  ad = {
    :xsi_type => 'ResponsiveDisplayAd',
    # This ad format does not allow the creation of an image using the
    # Image.data field. An image must first be created using the MediaService,
    # and Image.mediaId must be populated when creating the ad.
    :marketing_image => {
      :xsi_type => 'Image',
      :media_id => upload_image(adwords, 'https://goo.gl/3b9Wfh')
    },
    :short_headline => 'Travel',
    :long_headline => 'Travel the World',
    :description => 'Take to the air!',
    :business_name => 'Interplanetary Cruises',
    :final_urls => ['http://www.example.com'],
    # Optional: Call to action text.
    # Valid texts: https://support.google.com/adwords/answer/7005917
    :call_to_action_text => 'Apply Now',
    # Optional: Set dynamic display ad settings, composed of landscape logo
    # image, promotion text, and price prefix.
    :dynamic_display_ad_settings => create_dynamic_display_ad_settings(adwords),
    # Optional: Create a logo image and set it to the ad.
    :logo_image => {
      :xsi_type => 'Image',
      :media_id => optional_media_id
    },
    # Optional: Create a square marketing image and set it to the ad.
    :square_marketing_image => {
      :xsi_type => 'Image',
      :media_id => optional_media_id
    },
    # Whitelisted accounts only: Set color settings using hexadecimal values.
    # Set allowFlexibleColor to false if you want your ads to render by always
    # using your colors strictly.
    # :main_color => '#0000ff',
    # :accent_color => '#ffff00',
    # :allow_flexible_color => false,
    # Whitelisted accounts only: Set the format setting that the ad will be
    # served in.
    # :format_setting => 'NON_NATIVE'
  }

  ad_group_ad = {
    :ad => ad,
    :ad_group_id => ad_group[:id]
  }

  operation = {
    :operator => 'ADD',
    :operand => ad_group_ad
  }

  result = ad_srv.mutate([operation])
  return result[:value].first
end

Step 4 - Target a user list

Code Example:

C#

private static void AttachUserList(AdWordsUser user, AdGroup adGroup, long userListId)
{
    using (AdGroupCriterionService adGroupCriterionService =
        (AdGroupCriterionService) user.GetService(AdWordsService.v201809
            .AdGroupCriterionService))
    {
        CriterionUserList userList = new CriterionUserList
        {
            userListId = userListId
        };
        BiddableAdGroupCriterion adGroupCriterion = new BiddableAdGroupCriterion
        {
            criterion = userList,
            adGroupId = adGroup.id
        };

        AdGroupCriterionOperation op = new AdGroupCriterionOperation
        {
            operand = adGroupCriterion,
            @operator = Operator.ADD
        };

        adGroupCriterionService.mutate(new AdGroupCriterionOperation[]
        {
            op
        });
    }
}

Java

private static void attachUserList(
    AdWordsServicesInterface services, AdWordsSession session, AdGroup adGroup, long userListId)
    throws RemoteException {
  AdGroupCriterionServiceInterface adGroupCriterionService =
      services.get(session, AdGroupCriterionServiceInterface.class);

  CriterionUserList userList = new CriterionUserList();
  userList.setUserListId(userListId);
  BiddableAdGroupCriterion adGroupCriterion = new BiddableAdGroupCriterion();
  adGroupCriterion.setCriterion(userList);
  adGroupCriterion.setAdGroupId(adGroup.getId());

  AdGroupCriterionOperation op = new AdGroupCriterionOperation();
  op.setOperand(adGroupCriterion);
  op.setOperator(Operator.ADD);

  adGroupCriterionService.mutate(new AdGroupCriterionOperation[] {op});
}

Python

def AttachUserList(client, ad_group_id, user_list_id):
  """Links the provided ad group and user list.

  Args:
    client: an AdWordsClient instance.
    ad_group_id: an int ad group ID.
    user_list_id: an int user list ID.

  Returns:
    The ad group criterion that was successfully created.
  """
  ad_group_criterion_service = client.GetService(
      'AdGroupCriterionService', 'v201809')

  user_list = {
      'xsi_type': 'CriterionUserList',
      'userListId': user_list_id
  }

  ad_group_criterion = {
      'xsi_type': 'BiddableAdGroupCriterion',
      'criterion': user_list,
      'adGroupId': ad_group_id
  }

  operations = [{
      'operator': 'ADD',
      'operand': ad_group_criterion
  }]

  return ad_group_criterion_service.mutate(operations)['value'][0]

PHP

private static function attachUserList(
    AdWordsServices $adWordsServices,
    AdWordsSession $session,
    AdGroup $adGroup,
    $userListId
) {
    $adGroupCriterionService =
        $adWordsServices->get($session, AdGroupCriterionService::class);

    // Creates criterion user list.
    $userList = new CriterionUserList();
    $userList->setUserListId($userListId);

    // Creates ad group criterion.
    $adGroupCriterion = new BiddableAdGroupCriterion();
    $adGroupCriterion->setCriterion($userList);
    $adGroupCriterion->setAdGroupId($adGroup->getId());

    // Creates operation.
    $adGroupCriterionOperation = new AdGroupCriterionOperation();
    $adGroupCriterionOperation->setOperand($adGroupCriterion);
    $adGroupCriterionOperation->setOperator(Operator::ADD);

    // Makes the mutate request.
    $adGroupCriterionAddResult =
        $adGroupCriterionService->mutate([$adGroupCriterionOperation]);
    $adGroupCriterion = $adGroupCriterionAddResult->getValue()[0];

    return $adGroupCriterion;
}

Perl

sub _attach_user_list {
  my ($client, $ad_group, $user_list_id) = @_;

  my $user_list = Google::Ads::AdWords::v201809::CriterionUserList->new({
    userListId => $user_list_id
  });

  my $ad_group_criterion =
    Google::Ads::AdWords::v201809::BiddableAdGroupCriterion->new({
      adGroupId => $ad_group->get_id(),
      criterion => $user_list
    });

  my $operation = Google::Ads::AdWords::v201809::AdGroupCriterionOperation->new(
    {
      operand  => $ad_group_criterion,
      operator => "ADD"
    });
  $client->AdGroupCriterionService()->mutate({operations => [$operation]});
}

Ruby

def attach_user_list(adwords, ad_group, user_list_id)
  ad_group_criterion_srv = adwords.service(:AdGroupCriterionService,
      API_VERSION)

  user_list = {
    :xsi_type => 'CriterionUserList',
    :user_list_id => user_list_id
  }

  ad_group_criterion = {
    :xsi_type => 'BiddableAdGroupCriterion',
    :criterion => user_list,
    :ad_group_id => ad_group[:id]
  }

  operation = {
    :operator => 'ADD',
    :operand => ad_group_criterion
  }

  result = ad_group_criterion_srv.mutate([operation])
end

Once you have the dynamic remarketing campaign setup for your Merchant Center feeds, you can use the Ad Preview tool from your Google Ads account to see the contents pulled from your Merchant Center feeds.

Reporting

To gather performance statistics for your Dynamic Remarketing ads, use the same reports you would use for any other Display Network campaign.

Further information

This guide covers examples for real estate, flights and retail. If your Dynamic Remarketing ads target a different vertical, check out the complete list of Dynamic Remarketing placeholder types to get the appropriate placeholder type ID and placeholder field IDs.

And as described in the Feed Services guide, you should only associate dynamic remarketing feeds at the campaign level via CampaignFeedService. Adding an association at the customer or ad group level will succeed, but the association will be ignored.

ส่งความคิดเห็นเกี่ยวกับ...

หากต้องการความช่วยเหลือ ให้ไปที่หน้าการสนับสนุน