Ad customizers are a very powerful tool that lets you customize the text content of extended text ads by using text placeholders, countdowns, and IF functions.
An ad customizer is a feed-based solution for injecting dynamic information into your ads. You can set up a feed with targeting options for specific campaigns, ad groups, and/or keywords, and then create ads that reference the information in the feed, so the values in the feed are dynamically injected in your ads at serve time.
You can put strings, prices, numbers, and even a countdown to a specific date or time in your ad.
Ad customizers
A common use case for ad customizers is promoting sale prices on items during specific date ranges. To do this, you set up a feed with a string attribute for the item name, another string attribute for the price, and a date attribute for the date your sale ends, then populate feed items accordingly.
When setting up an ad, you reference the feed item, its name attribute, and its sale price attribute in the ad text fields, and Google Ads automatically populates the ad with the name and price from the feed item.
To use the feed item's end date, you include the date attribute in a function that tells Google Ads to display a countdown to the end date in your ad. When creating the ad, reference the feed item and its name, sale price, and end date attributes, and Google Ads will automatically populate the ad with the name, price, and end date from the feed item.
This will allow you to reuse the ad with another product sale or with the next sale of the same product, by updating your feed item's price and end date values, instead of creating a new ad for each product or for each sale.
The following sections describe all phases of this use case, including how to:
- Set up the feed and its attributes
- Map the feed to the "Ad Customizer" placeholder type
- Create feed items with the values you want to appear in your ads
- Target feed items to a specific campaign, ad group or keyword
- Use the feed in an ad
- Add a countdown
- Add an IF function
Set up the feed
The first step is to create a feed with all of the attributes you'll need to customize your ad.
Show me an example of creating a feed with three attributes: two of type STRING and one of type DATE_TIME
Java
private String createAdCustomizerFeed( GoogleAdsClient googleAdsClient, long customerId, String feedName) { // Creates three feed attributes: a name, a price and a date. The attribute names are arbitrary // choices and will be used as placeholders in the ad text fields. FeedAttribute nameAttribute = FeedAttribute.newBuilder().setName("Name").setType(FeedAttributeType.STRING).build(); FeedAttribute priceAttribute = FeedAttribute.newBuilder().setName("Price").setType(FeedAttributeType.STRING).build(); FeedAttribute dateAttribute = FeedAttribute.newBuilder().setName("Date").setType(FeedAttributeType.DATE_TIME).build(); Feed adCustomizerFeed = Feed.newBuilder() .setName(feedName) .addAttributes(nameAttribute) .addAttributes(priceAttribute) .addAttributes(dateAttribute) .build(); FeedOperation feedOperation = FeedOperation.newBuilder().setCreate(adCustomizerFeed).build(); try (FeedServiceClient feedServiceClient = googleAdsClient.getLatestVersion().createFeedServiceClient()) { MutateFeedsResponse response = feedServiceClient.mutateFeeds(Long.toString(customerId), ImmutableList.of(feedOperation)); String feedResourceName = response.getResults(0).getResourceName(); System.out.printf("Added feed with resource name %s.%n", feedResourceName); return feedResourceName; } }
C#
private string CreateAdCustomizerFeed(GoogleAdsClient client, long customerId, string feedName) { // Get the FeedServiceClient. FeedServiceClient feedService = client.GetService(Services.V11.FeedService); // Creates three feed attributes: a name, a price and a date. The attribute names // are arbitrary choices and will be used as placeholders in the ad text fields. FeedAttribute nameAttribute = new FeedAttribute() { Name = "Name", Type = FeedAttributeType.String }; FeedAttribute priceAttribute = new FeedAttribute() { Name = "Price", Type = FeedAttributeType.String }; FeedAttribute dateAttribute = new FeedAttribute() { Name = "Date", Type = FeedAttributeType.DateTime }; Feed adCustomizerFeed = new Feed() { Name = feedName, Attributes = { nameAttribute, priceAttribute, dateAttribute } }; FeedOperation feedOperation = new FeedOperation() { Create = adCustomizerFeed }; MutateFeedsResponse response = feedService.MutateFeeds(customerId.ToString(), new[] { feedOperation }); string feedResourceName = response.Results[0].ResourceName; Console.WriteLine($"Added feed with resource name '{feedResourceName}'."); return feedResourceName; }
PHP
private static function createAdCustomizerFeed( GoogleAdsClient $googleAdsClient, int $customerId, string $feedName ) { // Creates three feed attributes: a name, a price and a date. The attribute names are // arbitrary choices and will be used as placeholders in the ad text fields. $nameAttribute = new FeedAttribute(['type' => FeedAttributeType::STRING, 'name' => 'Name']); $priceAttribute = new FeedAttribute(['type' => FeedAttributeType::STRING, 'name' => 'Price']); $dateAttribute = new FeedAttribute(['type' => FeedAttributeType::DATE_TIME, 'name' => 'Date']); // Creates the feed. $feed = new Feed([ 'name' => $feedName, 'attributes' => [$nameAttribute, $priceAttribute, $dateAttribute], 'origin' => FeedOrigin::USER ]); // Creates a feed operation for creating a feed. $feedOperation = new FeedOperation(); $feedOperation->setCreate($feed); // Issues a mutate request to add the feed. $feedServiceClient = $googleAdsClient->getFeedServiceClient(); $feedResponse = $feedServiceClient->mutateFeeds($customerId, [$feedOperation]); $feedResourceName = $feedResponse->getResults()[0]->getResourceName(); printf("Added feed with resource name '%s'.%s", $feedResourceName, PHP_EOL); return $feedResourceName; }
Python
def _create_add_customizer_feed(client, customer_id, feed_name): """Creates a feed to be used for ad customization. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. feed_name: the name of the feed to create. Returns: A str of a resource name for the newly created feed. """ # Creates three feed attributes: a name, a price and a date. # The attribute names are arbitrary choices and will be used as # placeholders in the ad text fields. feed_attr_type_enum = client.enums.FeedAttributeTypeEnum name_attr = client.get_type("FeedAttribute") name_attr.type_ = feed_attr_type_enum.STRING name_attr.name = "Name" price_attr = client.get_type("FeedAttribute") price_attr.type_ = feed_attr_type_enum.STRING price_attr.name = "Price" date_attr = client.get_type("FeedAttribute") date_attr.type_ = feed_attr_type_enum.DATE_TIME date_attr.name = "Date" feed_operation = client.get_type("FeedOperation") feed = feed_operation.create feed.name = feed_name feed.attributes.extend([name_attr, price_attr, date_attr]) feed.origin = client.enums.FeedOriginEnum.USER feed_service = client.get_service("FeedService") response = feed_service.mutate_feeds( customer_id=customer_id, operations=[feed_operation] ) resource_name = response.results[0].resource_name print(f"Added feed with resource name {resource_name}") return resource_name
Ruby
def create_ad_customizer_feed( client, customer_id, feed_name) # Creates a feed operation for creating a feed. operation = client.operation.create_resource.feed do |feed| feed.name = feed_name # Creates three feed attributes: a name, a price and a date. The attribute # names are arbitrary choices and will be used as placeholders in the ad # text fields. feed.attributes << client.resource.feed_attribute do |a| a.type = :STRING a.name = "Name" end feed.attributes << client.resource.feed_attribute do |a| a.type = :STRING a.name = "Price" end feed.attributes << client.resource.feed_attribute do |a| a.type = :DATE_TIME a.name = "Date" end feed.origin = :USER end # Issues a mutate request to add the feed. feed_response = client.service.feed.mutate_feeds( customer_id: customer_id, operations: [operation], ) feed_resource_name = feed_response.results.first.resource_name puts "Added a feed with resource name #{feed_resource_name}." feed_resource_name end
Perl
sub create_ad_customizer_feed { my ($api_client, $customer_id, $feed_name) = @_; # Create three feed attributes: a name, a price and a date. The attribute names # are arbitrary choices and will be used as placeholders in the ad text fields. my $name_attribute = Google::Ads::GoogleAds::V11::Resources::FeedAttribute->new({ type => STRING, name => "Name" }); my $price_attribute = Google::Ads::GoogleAds::V11::Resources::FeedAttribute->new({ type => STRING, name => "Price" }); my $date_attribute = Google::Ads::GoogleAds::V11::Resources::FeedAttribute->new({ type => DATE_TIME, name => "Date" }); # Create the feed. my $feed = Google::Ads::GoogleAds::V11::Resources::Feed->new({ name => $feed_name, attributes => [$name_attribute, $price_attribute, $date_attribute], origin => USER }); # Create a feed operation for creating a feed. my $feed_operation = Google::Ads::GoogleAds::V11::Services::FeedService::FeedOperation->new({ create => $feed }); # Issue a mutate request to add the feed. my $feeds_response = $api_client->FeedService()->mutate({ customerId => $customer_id, operations => [$feed_operation]}); my $feed_resource_name = $feeds_response->{results}[0]{resourceName}; printf "Added feed with resource name '%s'.\n", $feed_resource_name; return $feed_resource_name; }
Take note of the resource name for the feed and the IDs for the feed attributes, as you'll need them when setting up the feed items. You can retrieve the feed attributes with a GAQL query that uses the resource name to filter results:
SELECT feed.attributes, feed.name FROM feed WHERE feed.resource_name = '%s'
Show me an example of feed attribute retrieval
Java
private Map<String, FeedAttribute> getFeedAttributes( GoogleAdsClient googleAdsClient, long customerId, String feedResourceName) { String query = String.format( "SELECT feed.attributes, feed.name FROM feed WHERE feed.resource_name = '%s'", feedResourceName); SearchGoogleAdsRequest request = SearchGoogleAdsRequest.newBuilder() .setCustomerId(Long.toString(customerId)) .setPageSize(PAGE_SIZE) .setQuery(query) .build(); Map<String, FeedAttribute> feedAttributes = new HashMap<>(); try (GoogleAdsServiceClient googleAdsServiceClient = googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) { SearchPagedResponse searchPagedResponse = googleAdsServiceClient.search(request); Feed feed = searchPagedResponse.iterateAll().iterator().next().getFeed(); System.out.printf( "Found the following attributes for feed with name '%s':%n", feed.getName()); for (FeedAttribute feedAttribute : feed.getAttributesList()) { System.out.printf( "\t'%s' with id %d and type '%s'%n", feedAttribute.getName(), feedAttribute.getId(), feedAttribute.getType()); feedAttributes.put(feedAttribute.getName(), feedAttribute); } } return feedAttributes; }
C#
private Dictionary<string, FeedAttribute> GetFeedAttributes(GoogleAdsClient client, long customerId, string feedResourceName) { // Get the GoogleAdsServiceClient. GoogleAdsServiceClient googleAdsService = client.GetService(Services.V11.GoogleAdsService); string query = $"SELECT feed.attributes, feed.name FROM feed WHERE " + $"feed.resource_name = '{feedResourceName}'"; SearchGoogleAdsRequest request = new SearchGoogleAdsRequest() { CustomerId = customerId.ToString(), Query = query }; Dictionary<string, FeedAttribute> feedAttributes = new Dictionary<string, FeedAttribute>(); Feed feed = googleAdsService.Search(request).First().Feed; Console.WriteLine($"Found the following attributes for feed with name '{feed.Name}'"); foreach (FeedAttribute feedAttribute in feed.Attributes) { Console.WriteLine($"\t'{feedAttribute.Name}' with id {feedAttribute.Id} and " + $"type '{feedAttribute.Type}'"); feedAttributes[feedAttribute.Name] = feedAttribute; } return feedAttributes; }
PHP
private static function getFeedAttributes( GoogleAdsClient $googleAdsClient, int $customerId, string $feedResourceName ) { $query = "SELECT feed.attributes, feed.name FROM feed " . "WHERE feed.resource_name = '$feedResourceName'"; $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient(); $response = $googleAdsServiceClient->search($customerId, $query, ['pageSize' => self::PAGE_SIZE]); /** @var Feed $feed */ $feed = $response->getIterator()->current()->getFeed(); $feedDetails = []; printf( "Found the following attributes for feed with name %s:%s", $feed->getName(), PHP_EOL ); foreach ($feed->getAttributes() as $feedAttribute) { /** @var FeedAttribute $feedAttribute */ $feedDetails[$feedAttribute->getName()] = $feedAttribute->getId(); printf( "\t'%s' with id %d and type '%s'%s", $feedAttribute->getName(), $feedAttribute->getId(), FeedAttributeType::name($feedAttribute->getType()), PHP_EOL ); } return $feedDetails; }
Python
def _get_feed_attributes(client, customer_id, feed_resource_name): """Retrieves attributes for a feed. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. feed_resource_name: the resource name of the feed. Returns: A dict of feed attributes, keyed by attribute name. """ query = f""" SELECT feed.attributes, feed.name FROM feed WHERE feed.resource_name = "{feed_resource_name}" """ ga_service = client.get_service("GoogleAdsService") search_request = client.get_type("SearchGoogleAdsRequest") search_request.customer_id = customer_id search_request.query = query search_request.page_size = 1 results = ga_service.search(request=search_request) feed = list(results)[0].feed print(f"Found the following attributes for feed with name {feed.name}") feed_details = {} for feed_attribute in feed.attributes: name = feed_attribute.name feed_attr_id = feed_attribute.id feed_type = feed_attribute.type_.name feed_details[name] = feed_attr_id print(f"\t{name} with id {feed_attr_id} and type {feed_type}.") return feed_details
Ruby
def get_feed_attributes( client, customer_id, ad_customizer_feed_resource_name) query = <<~QUERY SELECT feed.attributes, feed.name FROM feed WHERE feed.resource_name = "#{ad_customizer_feed_resource_name}" QUERY response = client.service.google_ads.search( customer_id: customer_id, query: query, page_size: PAGE_SIZE, ) feed = response.first.feed feed_details = {} puts "Found the following attributes for feed with name #{feed.name}:" feed.attributes.each do |a| feed_details[a.name.to_sym] = a.id puts "\t#{a.name} with id #{a.id} and type #{a.type}" end feed_details end
Perl
sub get_feed_attributes { my ($api_client, $customer_id, $feed_resource_name) = @_; my $search_query = "SELECT feed.attributes, feed.name FROM feed " . "WHERE feed.resource_name = '$feed_resource_name'"; my $search_response = $api_client->GoogleAdsService()->search({ customerId => $customer_id, query => $search_query, pageSize => PAGE_SIZE }); my $feed = $search_response->{results}[0]{feed}; my $feed_details = {}; printf "Found the following attributes for feed with name %s:\n", $feed->{name}; foreach my $feed_attribute (@{$feed->{attributes}}) { $feed_details->{$feed_attribute->{name}} = $feed_attribute->{id}; printf "\t'%s' with id %d and type '%s'\n", $feed_attribute->{name}, $feed_attribute->{id}, $feed_attribute->{type}; } return $feed_details; }
You are going to use the attribute IDs later, so store them in a structure that lets you retrieve by attribute name.
Create a FeedMapping
The next step is declaring that the feed you just created is to be used for ad
customizing by mapping it to the
AD_CUSTOMIZER
placeholder type and each of its fields to a specific
AdCustomizerPlaceholderField
:
Show me an example of FeedMapping creation
Java
private void createAdCustomizerMapping( GoogleAdsClient googleAdsClient, long customerId, String feedResourceName, Map<String, FeedAttribute> feedAttributes) { // Map the feed attributes to ad customizer placeholder fields. // For a full list of ad customizer placeholder fields, see // https://developers.google.com/google-ads/api/reference/rpc/latest/AdCustomizerPlaceholderFieldEnum.AdCustomizerPlaceholderField AttributeFieldMapping nameFieldMapping = AttributeFieldMapping.newBuilder() .setFeedAttributeId(feedAttributes.get("Name").getId()) .setAdCustomizerField(AdCustomizerPlaceholderField.STRING) .build(); AttributeFieldMapping priceFieldMapping = AttributeFieldMapping.newBuilder() .setFeedAttributeId(feedAttributes.get("Price").getId()) .setAdCustomizerField(AdCustomizerPlaceholderField.PRICE) .build(); AttributeFieldMapping dateFieldMapping = AttributeFieldMapping.newBuilder() .setFeedAttributeId(feedAttributes.get("Date").getId()) .setAdCustomizerField(AdCustomizerPlaceholderField.DATE) .build(); FeedMapping feedMapping = FeedMapping.newBuilder() .setFeed(feedResourceName) // Sets the feed to the AD_CUSTOMIZER placeholder type. .setPlaceholderType(PlaceholderType.AD_CUSTOMIZER) .addAttributeFieldMappings(nameFieldMapping) .addAttributeFieldMappings(priceFieldMapping) .addAttributeFieldMappings(dateFieldMapping) .build(); FeedMappingOperation feedMappingOperation = FeedMappingOperation.newBuilder().setCreate(feedMapping).build(); try (FeedMappingServiceClient feedMappingServiceClient = googleAdsClient.getLatestVersion().createFeedMappingServiceClient()) { MutateFeedMappingsResponse response = feedMappingServiceClient.mutateFeedMappings( Long.toString(customerId), ImmutableList.of(feedMappingOperation)); System.out.printf( "Added feed mapping with resource name %s.%n", response.getResults(0).getResourceName()); } }
C#
private void CreateAdCustomizerMapping(GoogleAdsClient client, long customerId, string feedResourceName, Dictionary<string, FeedAttribute> feedAttributes) { // Get the FeedMappingService. FeedMappingServiceClient feedMappingService = client.GetService(Services.V11.FeedMappingService); // Map the feed attributes to ad customizer placeholder fields. // For a full list of ad customizer placeholder fields, see // https://developers.google.com/google-ads/api/reference/rpc/latest/AdCustomizerPlaceholderFieldEnum.AdCustomizerPlaceholderField AttributeFieldMapping nameFieldMapping = new AttributeFieldMapping() { FeedAttributeId = feedAttributes["Name"].Id, AdCustomizerField = AdCustomizerPlaceholderField.String }; AttributeFieldMapping priceFieldMapping = new AttributeFieldMapping() { FeedAttributeId = feedAttributes["Price"].Id, AdCustomizerField = AdCustomizerPlaceholderField.Price }; AttributeFieldMapping dateFieldMapping = new AttributeFieldMapping() { FeedAttributeId = feedAttributes["Date"].Id, AdCustomizerField = AdCustomizerPlaceholderField.Date }; FeedMapping feedMapping = new FeedMapping() { Feed = feedResourceName, PlaceholderType = PlaceholderType.AdCustomizer, AttributeFieldMappings = { nameFieldMapping, priceFieldMapping, dateFieldMapping } }; FeedMappingOperation operation = new FeedMappingOperation() { Create = feedMapping }; MutateFeedMappingsResponse response = feedMappingService.MutateFeedMappings(customerId.ToString(), new[] { operation }); Console.WriteLine($"Added feed mapping with resource name" + $" '{response.Results[0].ResourceName}'."); }
PHP
private static function createAdCustomizerMapping( GoogleAdsClient $googleAdsClient, int $customerId, string $adCustomizerFeedResourceName, array $feedDetails ) { // Maps the feed attribute IDs to the field ID constants. $nameFieldMapping = new AttributeFieldMapping([ 'feed_attribute_id' => $feedDetails['Name'], 'ad_customizer_field' => AdCustomizerPlaceholderField::STRING ]); $priceFieldMapping = new AttributeFieldMapping([ 'feed_attribute_id' => $feedDetails['Price'], 'ad_customizer_field' => AdCustomizerPlaceholderField::PRICE ]); $dateFieldMapping = new AttributeFieldMapping([ 'feed_attribute_id' => $feedDetails['Date'], 'ad_customizer_field' => AdCustomizerPlaceholderField::DATE ]); // Creates the feed mapping. $feedMapping = new FeedMapping([ 'placeholder_type' => PlaceholderType::AD_CUSTOMIZER, 'feed' => $adCustomizerFeedResourceName, 'attribute_field_mappings' => [$nameFieldMapping, $priceFieldMapping, $dateFieldMapping] ]); // Creates the operation. $feedMappingOperation = new FeedMappingOperation(); $feedMappingOperation->setCreate($feedMapping); // Issues a mutate request to add the feed mapping. $feedMappingServiceClient = $googleAdsClient->getFeedMappingServiceClient(); $response = $feedMappingServiceClient->mutateFeedMappings( $customerId, [$feedMappingOperation] ); // Displays the results. foreach ($response->getResults() as $result) { printf( "Created feed mapping with resource name '%s'.%s", $result->getResourceName(), PHP_EOL ); } }
Python
def _create_ad_customizer_mapping( client, customer_id, ad_customizer_feed_resource_name, feed_details, ): """Creates a feed mapping for a given feed. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. ad_customizer_feed_resource_name: the resource name of the ad customizer feed. feed_details: a dict mapping feed attribute names to their IDs. """ placeholder_field_enum = client.enums.AdCustomizerPlaceholderFieldEnum # Map the feed attributes to ad customizer placeholder fields. For a full # list of ad customizer placeholder fields, see: # https://developers.google.com/google-ads/api/reference/rpc/latest/AdCustomizerPlaceholderFieldEnum.AdCustomizerPlaceholderField name_field_mapping = client.get_type("AttributeFieldMapping") name_field_mapping.feed_attribute_id = feed_details["Name"] name_field_mapping.ad_customizer_field = placeholder_field_enum.STRING price_field_mapping = client.get_type("AttributeFieldMapping") price_field_mapping.feed_attribute_id = feed_details["Price"] price_field_mapping.ad_customizer_field = placeholder_field_enum.PRICE date_field_mapping = client.get_type("AttributeFieldMapping") date_field_mapping.feed_attribute_id = feed_details["Date"] date_field_mapping.ad_customizer_field = placeholder_field_enum.DATE feed_mapping_op = client.get_type("FeedMappingOperation") feed_mapping = feed_mapping_op.create feed_mapping.feed = ad_customizer_feed_resource_name feed_mapping.placeholder_type = ( client.enums.PlaceholderTypeEnum.AD_CUSTOMIZER ) feed_mapping.attribute_field_mappings.extend( [name_field_mapping, price_field_mapping, date_field_mapping] ) feed_mapping_service = client.get_service("FeedMappingService") response = feed_mapping_service.mutate_feed_mappings( customer_id=customer_id, operations=[feed_mapping_op] ) for result in response.results: print( "Created feed mapping with resource name " f"{result.resource_name}" )
Ruby
def create_ad_customizer_mapping( client, customer_id, ad_customizer_feed_resource_name, ad_customizer_feed_attributes) # Creates the operation. operation = client.operation.create_resource.feed_mapping do |fm| fm.placeholder_type = :AD_CUSTOMIZER fm.feed = ad_customizer_feed_resource_name # Maps the feed attribute IDs to the field ID constants. fm.attribute_field_mappings << client.resource.attribute_field_mapping do |af| af.feed_attribute_id = ad_customizer_feed_attributes[:Name] af.ad_customizer_field = :STRING end fm.attribute_field_mappings << client.resource.attribute_field_mapping do |af| af.feed_attribute_id = ad_customizer_feed_attributes[:Price] af.ad_customizer_field = :PRICE end fm.attribute_field_mappings << client.resource.attribute_field_mapping do |af| af.feed_attribute_id = ad_customizer_feed_attributes[:Date] af.ad_customizer_field = :DATE end end # Issues a mutate request to add the feed mapping. response = client.service.feed_mapping.mutate_feed_mappings( customer_id: customer_id, operations: [operation], ) # Displays the results. response.results.each do |result| puts "Created feed mapping with resource name: #{result.resource_name}" end end
Perl
sub create_ad_customizer_mapping { my ( $api_client, $customer_id, $ad_customizer_feed_resource_name, $ad_customizer_feed_attributes ) = @_; # Map the feed attribute IDs to the field ID constants. my $name_field_mapping = Google::Ads::GoogleAds::V11::Resources::AttributeFieldMapping->new({ feedAttributeId => $ad_customizer_feed_attributes->{Name}, adCustomizerField => Google::Ads::GoogleAds::V11::Enums::AdCustomizerPlaceholderFieldEnum::STRING, }); my $price_field_mapping = Google::Ads::GoogleAds::V11::Resources::AttributeFieldMapping->new({ feedAttributeId => $ad_customizer_feed_attributes->{Price}, adCustomizerField => Google::Ads::GoogleAds::V11::Enums::AdCustomizerPlaceholderFieldEnum::PRICE, }); my $date_field_mapping = Google::Ads::GoogleAds::V11::Resources::AttributeFieldMapping->new({ feedAttributeId => $ad_customizer_feed_attributes->{Date}, adCustomizerField => Google::Ads::GoogleAds::V11::Enums::AdCustomizerPlaceholderFieldEnum::DATE, }); # Create the feed mapping. my $feed_mapping = Google::Ads::GoogleAds::V11::Resources::FeedMapping->new({ placeholderType => AD_CUSTOMIZER, feed => $ad_customizer_feed_resource_name, attributeFieldMappings => [$name_field_mapping, $price_field_mapping, $date_field_mapping]}); # Create the operation. my $feed_mapping_operation = Google::Ads::GoogleAds::V11::Services::FeedMappingService::FeedMappingOperation ->new({ create => $feed_mapping }); # Issue a mutate request to add the feed mapping. my $feed_mappings_response = $api_client->FeedMappingService()->mutate({ customerId => $customer_id, operations => [$feed_mapping_operation]}); # Display the results. foreach my $result (@{$feed_mappings_response->{results}}) { printf "Created feed mapping with resource name '%s'.\n", $result->{resourceName}; } }
Create feed items
At this point you can create two different feed items, for two different product sales, that will be dynamically inserted in your expanded text ads:
Show me an example of feed item creation
Java
private List<String> createFeedItems( GoogleAdsClient googleAdsClient, long customerId, String feedResourceName, Map<String, FeedAttribute> feedAttributes) { List<FeedItemOperation> feedItemOperations = new ArrayList<>(); DateTime marsDate = DateTime.now().withDayOfMonth(1).withHourOfDay(0).withMinuteOfHour(0); feedItemOperations.add( createFeedItemOperation( "Mars", "$1234.56", marsDate.toString("yyyyMMdd HHmmss"), feedResourceName, feedAttributes)); DateTime venusDate = DateTime.now().withDayOfMonth(15).withHourOfDay(0).withMinuteOfHour(0); feedItemOperations.add( createFeedItemOperation( "Venus", "$1450.00", venusDate.toString("yyyyMMdd HHmmss"), feedResourceName, feedAttributes)); try (FeedItemServiceClient feedItemServiceClient = googleAdsClient.getLatestVersion().createFeedItemServiceClient()) { List<String> feedItemResourceNames = new ArrayList<>(); MutateFeedItemsResponse response = feedItemServiceClient.mutateFeedItems(Long.toString(customerId), feedItemOperations); System.out.printf("Added %d feed items:%n", response.getResultsCount()); for (MutateFeedItemResult result : response.getResultsList()) { String feedItemResourceName = result.getResourceName(); feedItemResourceNames.add(feedItemResourceName); System.out.printf("Added feed item with resource name %s.%n", feedItemResourceName); } return feedItemResourceNames; } }
C#
private List<string> CreateFeedItems(GoogleAdsClient client, long customerId, string feedResourceName, Dictionary<string, FeedAttribute> feedAttributes) { // Get the FeedItemServiceClient. FeedItemServiceClient feedItemService = client.GetService(Services.V11.FeedItemService); List<FeedItemOperation> feedItemOperations = new List<FeedItemOperation>(); DateTime marsDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1); feedItemOperations.Add( CreateFeedItemOperation("Mars", "$1234.56", marsDate.ToString("yyyyMMdd HHmmss"), feedResourceName, feedAttributes)); DateTime venusDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 15); feedItemOperations.Add( CreateFeedItemOperation("Venus", "$1450.00", venusDate.ToString("yyyyMMdd HHmmss"), feedResourceName, feedAttributes)); List<string> feedItemResourceNames = new List<string>(); MutateFeedItemsResponse response = feedItemService.MutateFeedItems(customerId.ToString(), feedItemOperations); Console.WriteLine($"Added {response.Results.Count} feed items:"); foreach (MutateFeedItemResult result in response.Results) { string feedItemResourceName = result.ResourceName; feedItemResourceNames.Add(feedItemResourceName); Console.WriteLine($"Added feed item with resource name '{feedItemResourceName}'."); } return feedItemResourceNames; }
PHP
private static function createFeedItems( GoogleAdsClient $googleAdsClient, int $customerId, string $adCustomizerFeedResourceName, array $adCustomizerFeedAttributes ) { $feedItemOperations = []; $feedItemOperations[] = self::createFeedItemOperation( 'Mars', '$1234.56', date_format(new DateTime('first day of this month'), 'Ymd His'), $adCustomizerFeedResourceName, $adCustomizerFeedAttributes ); $feedItemOperations[] = self::createFeedItemOperation( 'Venus', '$6543.21', // Set the date to the 15th of the current month. date_format(DateTime::createFromFormat('d', '15'), 'Ymd His'), $adCustomizerFeedResourceName, $adCustomizerFeedAttributes ); // Adds the feed items. $feedItemServiceClient = $googleAdsClient->getFeedItemServiceClient(); $response = $feedItemServiceClient->mutateFeedItems($customerId, $feedItemOperations); $feedItemResourceNames = []; // Displays the results. foreach ($response->getResults() as $result) { printf( "Created feed item with resource name '%s'.%s", $result->getResourceName(), PHP_EOL ); $feedItemResourceNames[] = $result->getResourceName(); } return $feedItemResourceNames; }
Python
def _create_feed_items( client, customer_id, ad_customizer_feed_resource_name, ad_customizer_feed_attributes, ): """Creates two feed items to enable two different ad customizations. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. ad_customizer_feed_resource_name: the resource name of the ad customizer feed. ad_customizer_feed_attributes: a dict mapping feed attribute names to their IDs. Returns: A list of feed item resource name strs. """ feed_item_operations = [] feed_item_operations.append( _create_feed_item_operation( client, "Mars", "$1234.56", # Set the date to the 1st of the current month. datetime.now().replace(day=1).strftime("%Y%m%d %H%M%S"), ad_customizer_feed_resource_name, ad_customizer_feed_attributes, ) ) feed_item_operations.append( _create_feed_item_operation( client, "Venus", "$6543.21", # Set the date to the 15th of the current month. datetime.now().replace(day=15).strftime("%Y%m%d %H%M%S"), ad_customizer_feed_resource_name, ad_customizer_feed_attributes, ) ) feed_item_service = client.get_service("FeedItemService") response = feed_item_service.mutate_feed_items( customer_id=customer_id, operations=feed_item_operations ) return [feed_item.resource_name for feed_item in response.results]
Ruby
def create_feed_items( client, customer_id, ad_customizer_feed_resource_name, ad_customizer_feed_attributes) feed_item_operations = [] feed_item_operations << create_feed_item_operation( client, "Mars", "$1234.56", # Set the date to the 1st of the current month. DateTime.new(Date.today.year, Date.today.month, 1, 0, 0, 0).strftime("%Y%m%d %H%M%S"), ad_customizer_feed_resource_name, ad_customizer_feed_attributes, ) feed_item_operations << create_feed_item_operation( client, "Venus", "$6543.21", # Set the date to the 15th of the current month. DateTime.new(Date.today.year, Date.today.month, 15, 0, 0, 0).strftime("%Y%m%d %H%M%S"), ad_customizer_feed_resource_name, ad_customizer_feed_attributes, ) # Adds the feed items. response = client.service.feed_item.mutate_feed_items( customer_id: customer_id, operations: feed_item_operations, ) feed_item_resource_names = [] response.results.each do |result| puts "Created feed item with resource name #{result.resource_name}" feed_item_resource_names << result.resource_name end feed_item_resource_names end
Perl
sub create_feed_items { my ( $api_client, $customer_id, $ad_customizer_feed_resource_name, $ad_customizer_feed_attributes ) = @_; my $feed_item_operations = []; my ($sec, $min, $hour, $mday, $mon, $year) = localtime(time); push @$feed_item_operations, create_feed_item_operation( "Mars", '$1234.56', strftime("%Y%m%d %H%M%S", localtime(mktime(0, 0, 0, 1, $mon, $year))), $ad_customizer_feed_resource_name, $ad_customizer_feed_attributes ); push @$feed_item_operations, create_feed_item_operation( "Venus", '$6543.21', # Set the date to the 15th of the current month. strftime("%Y%m%d %H%M%S", localtime(mktime(0, 0, 0, 15, $mon, $year))), $ad_customizer_feed_resource_name, $ad_customizer_feed_attributes ); # Add the feed items. my $feed_items_response = $api_client->FeedItemService()->mutate({ customerId => $customer_id, operations => $feed_item_operations }); my $feed_item_resource_names = []; # Displays the results. foreach my $result (@{$feed_items_response->{results}}) { printf "Created feed item with resource name '%s'.\n", $result->{resourceName}; push @$feed_item_resource_names, $result->{resourceName}; } return $feed_item_resource_names; }
The helper function creates a
FeedItemOperation
object and sets the value
of each feed attribute:
Show me the helper function that creates FeedItemOperation objects
Java
private FeedItemOperation createFeedItemOperation( String name, String price, String date, String feedResourceName, Map<String, FeedAttribute> feedAttributes) { FeedItemAttributeValue nameAttributeValue = FeedItemAttributeValue.newBuilder() .setFeedAttributeId(feedAttributes.get("Name").getId()) .setStringValue(name) .build(); FeedItemAttributeValue priceAttributeValue = FeedItemAttributeValue.newBuilder() .setFeedAttributeId(feedAttributes.get("Price").getId()) .setStringValue(price) .build(); FeedItemAttributeValue dateAttributeValue = FeedItemAttributeValue.newBuilder() .setFeedAttributeId(feedAttributes.get("Date").getId()) .setStringValue(date) .build(); FeedItem feedItem = FeedItem.newBuilder() .setFeed(feedResourceName) .addAttributeValues(nameAttributeValue) .addAttributeValues(priceAttributeValue) .addAttributeValues(dateAttributeValue) .build(); return FeedItemOperation.newBuilder().setCreate(feedItem).build(); }
C#
private FeedItemOperation CreateFeedItemOperation(string name, string price, string date, string feedResourceName, Dictionary<string, FeedAttribute> feedAttributes) { FeedItemAttributeValue nameAttributeValue = new FeedItemAttributeValue() { FeedAttributeId = feedAttributes["Name"].Id, StringValue = name }; FeedItemAttributeValue priceAttributeValue = new FeedItemAttributeValue() { FeedAttributeId = feedAttributes["Price"].Id, StringValue = price }; FeedItemAttributeValue dateAttributeValue = new FeedItemAttributeValue() { FeedAttributeId = feedAttributes["Date"].Id, StringValue = date }; FeedItem feedItem = new FeedItem() { Feed = feedResourceName, AttributeValues = { nameAttributeValue, priceAttributeValue, dateAttributeValue } }; return new FeedItemOperation() { Create = feedItem }; }
PHP
private static function createFeedItemOperation( string $name, string $price, string $date, string $adCustomizerFeedResourceName, array $adCustomizerFeedAttributes ) { $nameAttributeValue = new FeedItemAttributeValue([ 'feed_attribute_id' => $adCustomizerFeedAttributes['Name'], 'string_value' => $name ]); $priceAttributeValue = new FeedItemAttributeValue([ 'feed_attribute_id' => $adCustomizerFeedAttributes['Price'], 'string_value' => $price ]); $dateAttributeValue = new FeedItemAttributeValue([ 'feed_attribute_id' => $adCustomizerFeedAttributes['Date'], 'string_value' => $date ]); $feedItem = new FeedItem([ 'feed' => $adCustomizerFeedResourceName, 'attribute_values' => [$nameAttributeValue, $priceAttributeValue, $dateAttributeValue] ]); $feedItemOperation = new FeedItemOperation(); $feedItemOperation->setCreate($feedItem); return $feedItemOperation; }
Python
def _create_feed_item_operation( client, name, price, date, ad_customizer_feed_resource_name, ad_customizer_feed_attributes, ): """Creates a FeedItemOperation. Args: client: an initialized GoogleAdsClient instance. name: a str value for the name attribute of the feed_item price: a str value for the price attribute of the feed_item date: a str value for the date attribute of the feed_item ad_customizer_feed_resource_name: the resource name of the ad customizer feed. ad_customizer_feed_attributes: a dict mapping feed attribute names to their IDs. Returns: A FeedItemOperation that creates a FeedItem """ name_attr_value = client.get_type("FeedItemAttributeValue") name_attr_value.feed_attribute_id = ad_customizer_feed_attributes["Name"] name_attr_value.string_value = name price_attr_value = client.get_type("FeedItemAttributeValue") price_attr_value.feed_attribute_id = ad_customizer_feed_attributes["Price"] price_attr_value.string_value = price date_attr_value = client.get_type("FeedItemAttributeValue") date_attr_value.feed_attribute_id = ad_customizer_feed_attributes["Date"] date_attr_value.string_value = date feed_item_op = client.get_type("FeedItemOperation") feed_item = feed_item_op.create feed_item.feed = ad_customizer_feed_resource_name feed_item.attribute_values.extend( [name_attr_value, price_attr_value, date_attr_value] ) return feed_item_op
Ruby
def create_feed_item_operation( client, name, price, date, ad_customizer_feed_resource_name, ad_customizer_feed_attributes) client.operation.create_resource.feed_item do |item| item.feed = ad_customizer_feed_resource_name item.attribute_values << client.resource.feed_item_attribute_value do |v| v.feed_attribute_id = ad_customizer_feed_attributes[:Name] v.string_value = name end item.attribute_values << client.resource.feed_item_attribute_value do |v| v.feed_attribute_id = ad_customizer_feed_attributes[:Price] v.string_value = price end item.attribute_values << client.resource.feed_item_attribute_value do |v| v.feed_attribute_id = ad_customizer_feed_attributes[:Date] v.string_value = date end end end
Perl
sub create_feed_item_operation { my ( $name, $price, $date, $ad_customizer_feed_resource_name, $ad_customizer_feed_attributes ) = @_; my $name_attribute_value = Google::Ads::GoogleAds::V11::Resources::FeedItemAttributeValue->new({ feedAttributeId => $ad_customizer_feed_attributes->{Name}, stringValue => $name }); my $price_attribute_value = Google::Ads::GoogleAds::V11::Resources::FeedItemAttributeValue->new({ feedAttributeId => $ad_customizer_feed_attributes->{Price}, stringValue => $price }); my $date_attribute_value = Google::Ads::GoogleAds::V11::Resources::FeedItemAttributeValue->new({ feedAttributeId => $ad_customizer_feed_attributes->{Date}, stringValue => $date }); my $feed_item = Google::Ads::GoogleAds::V11::Resources::FeedItem->new({ feed => $ad_customizer_feed_resource_name, attributeValues => [$name_attribute_value, $price_attribute_value, $date_attribute_value]} ); return Google::Ads::GoogleAds::V11::Services::FeedItemService::FeedItemOperation-> new({ create => $feed_item }); }
Set up feed item targeting
To be sure that the items will be fetched only for a specific ad group, their
targeting can be restricted by creating a
FeedItemTarget
that binds a feed item to an ad
group:
Show me an example of feed item targeting setup
Java
private void createFeedItemTargets( GoogleAdsClient googleAdsClient, long customerId, List<Long> adGroupIds, List<String> feedItemResourceNames) { // Bind each feed item to a specific ad group to make sure it will only be used to customize // ads inside that ad group; using the feed item elsewhere will result in an error. for (int i = 0; i < feedItemResourceNames.size(); i++) { String feedItemResourceName = feedItemResourceNames.get(i); Long adGroupId = adGroupIds.get(i); FeedItemTarget feedItemTarget = FeedItemTarget.newBuilder() .setAdGroup(ResourceNames.adGroup(customerId, adGroupId)) .setFeedItem(feedItemResourceName) .build(); FeedItemTargetOperation feedItemTargetOperation = FeedItemTargetOperation.newBuilder().setCreate(feedItemTarget).build(); try (FeedItemTargetServiceClient feedItemTargetServiceClient = googleAdsClient.getLatestVersion().createFeedItemTargetServiceClient()) { MutateFeedItemTargetsResponse response = feedItemTargetServiceClient.mutateFeedItemTargets( Long.toString(customerId), ImmutableList.of(feedItemTargetOperation)); String feedItemTargetResourceName = response.getResults(0).getResourceName(); System.out.printf( "Added feed item target with resource name '%s'.%n", feedItemTargetResourceName); } } }
C#
private void CreateFeedItemTargets(GoogleAdsClient client, long customerId, long[] adGroupIds, List<string> feedItemResourceNames) { // Get the FeedItemTargetServiceClient. FeedItemTargetServiceClient feedItemTargetService = client.GetService(Services.V11.FeedItemTargetService); // Bind each feed item to a specific ad group to make sure it will only be used to // customize ads inside that ad group; using the feed item elsewhere will result // in an error. for (int i = 0; i < feedItemResourceNames.Count; i++) { string feedItemResourceName = feedItemResourceNames[i]; long adGroupId = adGroupIds[i]; FeedItemTarget feedItemTarget = new FeedItemTarget() { AdGroup = ResourceNames.AdGroup(customerId, adGroupId), FeedItem = feedItemResourceName }; FeedItemTargetOperation feedItemTargetOperation = new FeedItemTargetOperation() { Create = feedItemTarget }; MutateFeedItemTargetsResponse response = feedItemTargetService.MutateFeedItemTargets(customerId.ToString(), new[] { feedItemTargetOperation }); string feedItemTargetResourceName = response.Results[0].ResourceName; Console.WriteLine($"Added feed item target with resource name " + $"'{response.Results[0].ResourceName}'."); } }
PHP
private static function createFeedItemTargets( GoogleAdsClient $googleAdsClient, int $customerId, array $adGroupIds, array $feedItemResourceNames ) { // Bind each feed item to a specific ad group to make sure it will only be used to customize // ads inside that ad group; using the feed item elsewhere will result in an error. for ($i = 0; $i < count($feedItemResourceNames); $i++) { $feedItemResourceName = $feedItemResourceNames[$i]; $adGroupId = $adGroupIds[$i]; $feedItemTarget = new FeedItemTarget([ 'feed_item' => $feedItemResourceName, 'ad_group' => ResourceNames::forAdGroup($customerId, $adGroupId) ]); // Creates the operation. $feedItemTargetOperation = new FeedItemTargetOperation(); $feedItemTargetOperation->setCreate($feedItemTarget); // Issues a mutate request to add the feed item target. $feedItemTargetServiceClient = $googleAdsClient->getFeedItemTargetServiceClient(); $feedItemTargetResponse = $feedItemTargetServiceClient->mutateFeedItemTargets( $customerId, [$feedItemTargetOperation] ); $feedItemTargetResourceName = $feedItemTargetResponse->getResults()[0]->getResourceName(); printf( "Added feed item target with resource name '%s'.%s", $feedItemTargetResourceName, PHP_EOL ); } }
Python
def _create_feed_item_targets( client, customer_id, ad_group_ids, feed_item_resource_names ): """Restricts the feed items to work only with a specific ad group. This prevents the feed items from being used elsewhere and makes sure they are used only for customizing a specific ad group. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. ad_group_ids: a list of ad group IDs. feed_item_resource_names: a list of feed item resource name strs. """ ad_group_service = client.get_service("AdGroupService") feed_item_target_service = client.get_service("FeedItemTargetService") # Bind each feed item to a specific ad group to make sure it will only be # used to customize ads inside that ad group; using the feed item elsewhere # will result in an error. for i, resource_name in enumerate(feed_item_resource_names): ad_group_id = ad_group_ids[i] feed_item_target_op = client.get_type("FeedItemTargetOperation") feed_item_target = feed_item_target_op.create feed_item_target.feed_item = resource_name feed_item_target.ad_group = ad_group_service.ad_group_path( customer_id, ad_group_id ) response = feed_item_target_service.mutate_feed_item_targets( customer_id=customer_id, operations=[feed_item_target_op] ) print( "Added feed item target with resource name " f"{response.results[0].resource_name}" )
Ruby
def create_feed_item_targets( client, customer_id, ad_group_ids, feed_item_resource_names) # Bind each feed item to a specific ad group to make sure it will only be # used to customize ads inside that ad group; using the feed item elsewhere # will result in an error. feed_item_resource_names.size.times do |i| feed_item_resource_name = feed_item_resource_names[i] ad_group_id = ad_group_ids[i] # Creates the operation. operation = client.operation.create_resource.feed_item_target do |t| t.feed_item = feed_item_resource_name t.ad_group = client.path.ad_group(customer_id, ad_group_id) end # Issues a mutate request to add the feed item target. response = client.service.feed_item_target.mutate_feed_item_targets( customer_id: customer_id, operations: [operation], ) puts "Added feed item target with resource name #{response.results.first.resource_name}." end end
Perl
sub create_feed_item_targets { my ($api_client, $customer_id, $ad_group_ids, $feed_item_resource_names) = @_; # Bind each feed item to a specific ad group to make sure it will only be used # to customize ads inside that ad group; using the feed item elsewhere will # result in an error. for (my $i = 0 ; $i < scalar @$feed_item_resource_names ; $i++) { my $feed_item_resource_name = $feed_item_resource_names->[$i]; my $ad_group_id = $ad_group_ids->[$i]; my $feed_item_target = Google::Ads::GoogleAds::V11::Resources::FeedItemTarget->new({ feedItem => $feed_item_resource_name, adGroup => Google::Ads::GoogleAds::V11::Utils::ResourceNames::ad_group( $customer_id, $ad_group_id )}); # Create the operation. my $feed_item_target_operation = Google::Ads::GoogleAds::V11::Services::FeedItemTargetService::FeedItemTargetOperation ->new({ create => $feed_item_target }); # Issue a mutate request to add the feed item target. my $feed_item_targets_response = $api_client->FeedItemTargetService()->mutate({ customerId => $customer_id, operations => [$feed_item_target_operation]}); my $feed_item_target_resource_name = $feed_item_targets_response->{results}[0]{resourceName}; printf "Added feed item target with resource name '%s'.\n", $feed_item_target_resource_name; } }
Feed item targets can restrict feed items to be fetched for several different
resource types, like campaigns, ad groups, keywords, devices and locations: to
see the complete list of possible resources that a feed item can target, see the
FeedItemTarget
resource.
Use the feed in an ad
Once the feed is set up, you can reference it from any ad in the system.
When setting up an ad, you reference a feed and its attributes by name, not by ID. This is different from the other steps, where you use the system-generated IDs.
The syntax for inserting a custom value from a feed is
{=FeedName.AttributeName}
. If you want to specify a default value, the syntax
would be {=FeedName.AttributeName:default value}
. For example, using our feed
above, if you want to insert the price of an object in the string with a default
of $10, use {=AdCustomizerFeed.Price:$10}
:
Show me an example of how to use the feed to customize ads
Java
private void createAdsWithCustomizations( GoogleAdsClient googleAdsClient, long customerId, List<Long> adGroupIds, String feedName) { // Creates an expanded text ad using the feed attribute names as placeholders. ExpandedTextAdInfo expandedTextAdInfo = ExpandedTextAdInfo.newBuilder() .setHeadlinePart1(String.format("Luxury cruise to {=%s.Name}", feedName)) .setHeadlinePart2(String.format("Only {=%s.Price}", feedName)) .setDescription(String.format("Offer ends in {=countdown(%s.Date)}!", feedName)) .build(); Ad ad = Ad.newBuilder() .setExpandedTextAd(expandedTextAdInfo) .addFinalUrls("http://www.example.com") .build(); List<AdGroupAdOperation> adGroupAdOperations = new ArrayList<>(); // Creates the same ad in all ad groups. When they serve, they will show different values, // since they match different feed items. for (Long adGroupId : adGroupIds) { AdGroupAd adGroupAd = AdGroupAd.newBuilder() .setAd(ad) .setAdGroup(ResourceNames.adGroup(customerId, adGroupId)) .build(); AdGroupAdOperation adGroupAdOperation = AdGroupAdOperation.newBuilder().setCreate(adGroupAd).build(); adGroupAdOperations.add(adGroupAdOperation); } try (AdGroupAdServiceClient adGroupAdServiceClient = googleAdsClient.getLatestVersion().createAdGroupAdServiceClient()) { MutateAdGroupAdsResponse response = adGroupAdServiceClient.mutateAdGroupAds(Long.toString(customerId), adGroupAdOperations); System.out.printf("Added %d ads:%n", response.getResultsCount()); for (MutateAdGroupAdResult result : response.getResultsList()) { System.out.printf("Added an ad with resource name '%s'.%n", result.getResourceName()); } } }
C#
private void CreateAdsWithCustomizations(GoogleAdsClient client, long customerId, long[] adGroupIds, string feedName) { // Get the AdGroupAdServiceClient. AdGroupAdServiceClient adGroupAdService = client.GetService(Services.V11.AdGroupAdService); // Creates an expanded text ad using the feed attribute names as placeholders. Ad ad = new Ad() { ExpandedTextAd = new ExpandedTextAdInfo() { HeadlinePart1 = $"Luxury cruise to {{={feedName}.Name}}", HeadlinePart2 = $"Only {{={feedName}.Price}}", Description = $"Offer ends in {{=countdown({feedName}.Date)}}!" }, FinalUrls = { "http://www.example.com" } }; List<AdGroupAdOperation> adGroupAdOperations = new List<AdGroupAdOperation>(); // Creates the same ad in all ad groups. When they serve, they will show // different values, since they match different feed items. foreach (long adGroupId in adGroupIds) { AdGroupAd adGroupAd = new AdGroupAd() { Ad = ad, AdGroup = ResourceNames.AdGroup(customerId, adGroupId) }; adGroupAdOperations.Add(new AdGroupAdOperation() { Create = adGroupAd }); } MutateAdGroupAdsResponse response = adGroupAdService.MutateAdGroupAds(customerId.ToString(), adGroupAdOperations); Console.WriteLine($"Added {response.Results.Count} ads:"); foreach (MutateAdGroupAdResult result in response.Results) { Console.WriteLine($"Added an ad with resource name '{result.ResourceName}'."); } }
PHP
private static function createAdsWithCustomizations( GoogleAdsClient $googleAdsClient, int $customerId, array $adGroupIds, string $feedName ) { $expandedTextAdInfo = new ExpandedTextAdInfo([ 'headline_part1' => "Luxury cruise to {=$feedName.Name}", 'headline_part2' => "Only {=$feedName.Price}", 'description' => "Offer ends in {=countdown($feedName.Date)}!" ]); $ad = new Ad([ 'expanded_text_ad' => $expandedTextAdInfo, 'final_urls' => ['http://www.example.com'] ]); $adGroupAdOperations = []; foreach ($adGroupIds as $adGroupId) { $adGroupAd = new AdGroupAd([ 'ad' => $ad, 'ad_group' => ResourceNames::forAdGroup($customerId, $adGroupId) ]); $adGroupAdOperation = new AdGroupAdOperation(); $adGroupAdOperation->setCreate($adGroupAd); $adGroupAdOperations[] = $adGroupAdOperation; } // Issues a mutate request to add the ads. $adGroupAdServiceClient = $googleAdsClient->getAdGroupAdServiceClient(); $adGroupAdResponse = $adGroupAdServiceClient->mutateAdGroupAds( $customerId, $adGroupAdOperations ); printf('Added %d ads:%s', count($adGroupAdResponse->getResults()), PHP_EOL); foreach ($adGroupAdResponse->getResults() as $result) { printf("Added an ad with resource name '%s'.%s", $result->getResourceName(), PHP_EOL); } }
Python
def _create_ads_with_customizations( client, customer_id, ad_group_ids, feed_name ): """Creates expanded text ads that use the ad customizer feed. The expanded text ads use the ad customizer feed to populate the placeholders. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. ad_group_ids: a list of ad group IDs. feed_name: the name of the feed to create. """ ad_group_service = client.get_service("AdGroupService") ad_group_ad_service = client.get_service("AdGroupAdService") ad_group_ad_operations = [] for ad_group_id in ad_group_ids: ad_group_ad_operation = client.get_type("AdGroupAdOperation") ad_group_ad = ad_group_ad_operation.create ad_group_ad.ad_group = ad_group_service.ad_group_path( customer_id, ad_group_id ) ad_group_ad.ad.final_urls.append("http://www.example.com") ad_group_ad.ad.expanded_text_ad.headline_part1 = ( f"Luxury cruise to {{={feed_name}.Name}}" ) ad_group_ad.ad.expanded_text_ad.headline_part2 = ( f"Only {{={feed_name}.Price}}" ) # See this documentation for an explanation of how countdown ad # customizers work: https://support.google.com/google-ads/answer/6193743?hl=en ad_group_ad.ad.expanded_text_ad.description = ( f"Offer ends in {{=countdown({feed_name}.Date)}}!" ) ad_group_ad_operations.append(ad_group_ad_operation) response = ad_group_ad_service.mutate_ad_group_ads( customer_id=customer_id, operations=ad_group_ad_operations ) print(f"Added {len(response.results)} ads:") for ad in response.results: print(f"Added an ad with resource name {ad.resource_name}")
Ruby
def create_ads_with_customizations( client, customer_id, ad_group_ids, feed_name) operations = [] ad_group_ids.each do |ad_group_id| operations << client.operation.create_resource.ad_group_ad do |aga| aga.ad = client.resource.ad do |ad| ad.expanded_text_ad = client.resource.expanded_text_ad_info do |eta| eta.headline_part1 = "Luxury cruise to {=#{feed_name}.Name}" eta.headline_part2 = "Only {=#{feed_name}.Price}" eta.description = "Offer ends in {=countdown(#{feed_name}.Date)}!" end ad.final_urls << "http://www.example.com" end aga.ad_group = client.path.ad_group(customer_id, ad_group_id) end end # Issues a mutate request to add the ads. response = client.service.ad_group_ad.mutate_ad_group_ads( customer_id: customer_id, operations: operations, ) puts "Added #{response.results.size} ads:" response.results.each do |result| puts "Added an ad with resource name #{result.resource_name}." end end
Perl
sub create_ads_with_customizations { my ($api_client, $customer_id, $ad_group_ids, $feed_name) = @_; my $expanded_text_ad_info = Google::Ads::GoogleAds::V11::Common::ExpandedTextAdInfo->new({ headlinePart1 => "Luxury cruise to {=$feed_name.Name}", headlinePart2 => "Only {=$feed_name.Price}", description => "Offer ends in {=countdown($feed_name.Date)}!" }); my $ad = Google::Ads::GoogleAds::V11::Resources::Ad->new({ expandedTextAd => $expanded_text_ad_info, finalUrls => ["http://www.example.com"]}); my $ad_group_ad_operations = []; foreach my $ad_group_id (@$ad_group_ids) { my $ad_group_ad = Google::Ads::GoogleAds::V11::Resources::AdGroupAd->new({ ad => $ad, adGroup => Google::Ads::GoogleAds::V11::Utils::ResourceNames::ad_group( $customer_id, $ad_group_id )}); push @$ad_group_ad_operations, Google::Ads::GoogleAds::V11::Services::AdGroupAdService::AdGroupAdOperation ->new({ create => $ad_group_ad }); } # Issue a mutate request to add the ads. my $ad_group_ads_response = $api_client->AdGroupAdService()->mutate({ customerId => $customer_id, operations => $ad_group_ad_operations }); my $ad_group_ad_results = $ad_group_ads_response->{results}; printf "Added %d ads:\n", scalar @$ad_group_ad_results; foreach my $ad_group_ad_result (@$ad_group_ad_results) { printf "Added an ad with resource name '%s'.\n", $ad_group_ad_result->{resourceName}; } }
The references to the feed with name FeedName
are populated at serving time
with matching data from a feed item within that feed that is targeted to match
the current ad group. The ad won't serve if no match is found.
The API validates ads that include references to ad customizers: If no feed with the specified name is mapped to the ad placeholder type, or no attribute with a specified name exists in the feed, the ad is rejected.
If you change the name of a feed when ads are referencing it, the ads are automatically updated to reference the new feed name. If you delete a feed when ads are referencing it, those ads will no longer serve.
Ads using customizers are subject to approvals just like any other ads. Feed items and ads can both be disapproved separately, though disapproval of either will prevent the ad from serving. In rare cases where each is individually fine, but the combination of the two is a violation, the ad will be disapproved to prevent serving.
Using countdowns
The COUNTDOWN
function lets you dynamically change the way you display a date
field so it shows how much time (days, hours) is left.
For example, the description of the ad example above is set to
'Offer ends in {=COUNTDOWN(feedName.Date)}!'
At serve time, the ad will show "Offer ends in 5 days!"
or
"Offer ends in 4 hours!"
based on the time left.
Once the date specified in the countdown is past, the ad will no longer serve until the date is updated again.
The countdown function takes three arguments, but only the first is required:
timestamp
: The date to which you are counting down. This value can be a reference to a feed attribute or a specific date literal.language
: The localization in which the countdown should be displayed. If unspecified, this defaults toen-US
.days_before
: The number of days before the timestamp that this ad can start serving. For example, if it's 6 days before the specified time, but this field is set to 5, the ad won't serve. If unspecified, no restrictions are added.
For instance, you could use {=COUNTDOWN(AdCustomizerFeed.Date, 'es', 3)}
to
change the language to Spanish, and restrict the ad so it doesn't appear in
search results until 3 days before the date specified.
The COUNTDOWN
function counts down to an event in the timezone of the user
making the query. A variant of COUNTDOWN
, called GLOBAL_COUNTDOWN
, counts
down to a specific time in your account's time zone. GLOBAL_COUNTDOWN
takes
all the same parameters as COUNTDOWN
.
Using IF functions
For an easier way to customize your ads, IF functions let you insert a customized message in your ad based on who is searching and what device they're searching on, all without using a feed. The default text is optional.
Dimension | Criteria | Syntax | Example |
---|---|---|---|
device | mobile | {=IF(device=mobile,text to insert):optional default text} |
{=IF(device=mobile,"Quick, Easy, Mobile Booking"):"Best price guarantee"} |
audience | Any valid user list name in your account (if list name matches multiple lists in advertiser account, we will randomly pick any) | {=IF(audience IN (userlist1,userlist2),text to insert):optional default text} |
{=IF(audience IN (returning visitors,cart abandoners),30%):25%} |