Forward Compatibility Maps

The forwardCompatibilityMap field allows you to explore cutting-edge functionality before it is formally exposed in the API. This field is included in some of the major API entities (for example, Campaign).

forwardCompatibilityMap is of type String_StringMapEntry, representing a mapping of string to string. The mapping is used to get and set properties on API entities—properties that are not yet available as formal attributes of the object or its descendants. These properties are exposed through keys in forwardCompatibilityMap. Objects that have the forwardCompatibilityMap field include Campaign, AdGroup, and AdGroupAd.

Reading the map

You don't need to reference a forwardCompatibilityMap field as part of your Selector.fields array. If there's at least one key exposed in the API version and service you're using, the forwardCompatibilityMap field will be present in the response.

A map may contain a set of keys, one for each object type, that are exposed as an extension of the formal attributes of the object or one of its descendants. A key in an object's forwardCompatibilityMap may reference an attribute of the object's descendant rather than the object itself. For example, you may see the key Ad.devicePreferred in the map for AdGroupAd, but in actuality, that key belongs to the Ad object (a descendant of AdGroupAd ).

Map values are of type string, but depending on the associated key and the attribute it represents, values can be string representations of other basic data types such as integers or booleans. You may need to convert the type before using them.

Get example

Here is an example of calling the get() method in CampaignService to retrieve the the value for a specific key from the forwardCompatibilityMap of each campaign.

Java

// Get the CampaignService.
CampaignServiceInterface campaignService =
    adWordsServices.get(session, CampaignServiceInterface.class);

// Create selector.
// Notice there is no need to explicitly request the
// forwardCompatibilityMap, indeed adding to the list of fields
// will throw an error.
SelectorBuilder selectorBuilder =
    new SelectorBuilder().fields(CampaignField.Id).limit(PAGE_SIZE);

int offset = 0;

CampaignPage page;
Map<Long, Boolean> campaignMap = new HashMap<>();
do {
  page = campaignService.get(selectorBuilder.build());

  // Collect the campaigns from the page.
  for (Campaign campaign : page.getEntries()) {
    Map<String, String> forwardCompatibilityMap =
        Maps.toMap(campaign.getForwardCompatibilityMap());
    String value = forwardCompatibilityMap.get(compatibilityMapKey);
    System.out.printf(
        "Campaign ID %d has forward compatibility map value of '%s' for key '%s'.%n",
        campaign.getId(), value, compatibilityMapKey);
    // This demonstrates how to handle a forward compatibility map key where
    // the value is a boolean. Check the forward compatibility map documentation
    // for the data type for each supported key:
    // https://developers.google.com/adwords/api/docs/guides/forward-compatibility-maps
    campaignMap.put(campaign.getId(), value == null ? null : Boolean.valueOf(value));
  }
  offset += PAGE_SIZE;
  selectorBuilder.increaseOffsetBy(PAGE_SIZE);
} while (offset < page.getTotalNumEntries());
return campaignMap;

C#

// Get the CampaignService.
CampaignService campaignService = (CampaignService)user.GetService(
    AdWordsService.v201708.CampaignService);

// Create selector. There is no need to explicitly request the forwardCompatibilityMap field.
// Requesting this field through selectors will throw an error.
Selector selector = new Selector() {
  fields = new string[] { Campaign.Fields.Id },
  paging = Paging.Default
};

CampaignPage page = new CampaignPage();
Dictionary<long, bool> campaignMap = new Dictionary<long, bool>();

try {
  do {
    // Get the campaigns.
    page = campaignService.get(selector);

    // Display the results.
    if (page != null && page.entries != null) {
      foreach (Campaign campaign in page.entries) {
        Dictionary<String, String> forwardCompatibilityMap =
            campaign.forwardCompatibilityMap.ToDict();

        String value = CollectionUtilities.TryGetValue(
            forwardCompatibilityMap, compatibilityMapKey);

        if (value != null) {
          Console.WriteLine("Campaign ID {0} has forward compatibility map value of " +
              "'{1}' for key '{2}'.", campaign.id, compatibilityMapKey);
          // This demonstrates how to handle a forward compatibility map key where
          // the value is a boolean. Check the forward compatibility map documentation
          // for the data type for each supported key:
          // https://developers.google.com/adwords/api/docs/guides/forward-compatibility-maps
          campaignMap[campaign.id] = Convert.ToBoolean(value);
        } else {
          campaignMap[campaign.id] = false;
        }
      }
    }
    selector.paging.IncreaseOffset();
  } while (selector.paging.startIndex < page.totalNumEntries);
  Console.WriteLine("Number of campaigns found: {0}", page.totalNumEntries);
} catch (Exception e) {
  throw new System.ApplicationException("Failed to retrieve forward compatibility map for " +
      "campaigns", e);
}
return campaignMap;

PHP

// Get the CampaignService.
$campaignService = $adWordsServices->get($session, CampaignService::class);

// Create selector.
// Notice there is no need to explicitly request the
// forwardCompatibilityMap, indeed adding to the list of fields
// will throw an error.
$selector = new Selector();
$selector->setFields(['Id']);
$selector->setPaging(new Paging(0, self::PAGE_LIMIT));

$campaignMap = [];
$foundResults = false;
do {
  // Retrieve campaigns one page at a time, continuing to request pages
  // until all campaigns have been retrieved.
  $page = $campaignService->get($selector);

  // Print out some information for each campaign.
  if ($page->getEntries() !== null) {
    $totalNumEntries = $page->getTotalNumEntries();
    foreach ($page->getEntries() as $campaign) {
      if (is_null($campaign->getForwardCompatibilityMap())) {
        continue;
      }
      $forwardCompatibilityMap = MapEntries::toAssociativeArray(
          $campaign->getForwardCompatibilityMap());
      // This demonstrates how to handle a forward compatibility map key
      // where the value is a boolean. Check the forward compatibility map
      // documentation for the data type for each supported key:
      // https://developers.google.com/adwords/api/docs/guides/forward-compatibility-maps
      $value = boolval($forwardCompatibilityMap[$compatibilityMapKey]);
      $foundResults = true;
      printf(
          "Campaign ID %d has forward compatibility map value of '%s' for "
              . "key '%s'.\n",
          $campaign->getId(),
          $value,
          $compatibilityMapKey
      );
      // Cast the ID to string to prevent 32-bit PHP to convert this to
      // negative number.
      $campaignId = strval($campaign->getId());
      $campaignMap[$campaignId] = $value;
    }
  }
  $selector->getPaging()->setStartIndex(
      $selector->getPaging()->getStartIndex() + self::PAGE_LIMIT);
} while ($selector->getPaging()->getStartIndex() < $totalNumEntries);
if (!$foundResults) {
  print "No forward compatibility maps are found.\n";
}

return $campaignMap;

Python

# Get the CampaignService.
campaign_service = client.GetService('CampaignService', version='v201708')

# Create selector.
# Notice there is no need to explicitly request the forwardCompatibilityMap;
# adding to the list of fields will throw an error.
offset = 0
selector = {
    'fields': ['Id'],
    'paging': {
        'startIndex': offset,
        'numberResults': PAGE_SIZE
    }
}

campaign_map = {}
more_pages = True

while more_pages:
  page = campaign_service.get(selector)

  if 'entries' in page:
    for campaign in page['entries']:
      raw_fcm = getattr(
          campaign, 'forwardCompatibilityMap', {})
      forward_compatibility_map = {
          string_map_entry['key']: string_map_entry['value']
          for string_map_entry in raw_fcm
      }

      campaign_id = campaign['id']
      value = forward_compatibility_map.get(bool(compatibility_map_key),
                                            False)
      campaign_map[campaign_id] = value

      # This demonstrates how to handle a forward compatibility map key where
      # the value is a boolean. Check the forward compatibility map
      # documentation for the data type for each supported key:
      # https://developers.google.com/adwords/api/docs/guides/forward-compatibility-maps
      print ('Campaign with id "%s" has forward compatibility map value of '
             '"%s" for key "%s".' % (campaign_id, value,
                                     compatibility_map_key))
  offset += PAGE_SIZE
  selector['paging']['startIndex'] = offset
  more_pages = offset < int(page['totalNumEntries'])

return campaign_map

Perl

# Create selector.
# Notice there is no need to explicitly request the forwardCompatibilityMap,
# indeed adding to the list of fields will throw an error.
my $paging = Google::Ads::AdWords::v201708::Paging->new({
  startIndex    => 0,
  numberResults => PAGE_SIZE
});
my $selector = Google::Ads::AdWords::v201708::Selector->new({
  fields     => ["Id"],
  paging     => $paging
});

my $campaign_map = {};
# Retrieve campaigns one page at a time, continuing to request pages until
# all campaigns have been retrieved.
Google::Ads::AdWords::Utilities::PageProcessor->new({
    client   => $client,
    service  => $client->CampaignService(),
    selector => $selector
  }
  )->process_entries(
  sub {
    # Print out some information for each campaign.
    my ($campaign) = @_;

    my $forward_compatibility_map =
        Google::Ads::Common::MapUtils::get_map(
          $campaign->get_forwardCompatibilityMap());
    if (defined $forward_compatibility_map) {
      # This demonstrates how to handle a forward compatibility map key
      # where the value is a boolean. Check the forward compatibility map
      # documentation for the data type for each supported key:
      # https://developers.google.com/adwords/api/docs/guides/forward-compatibility-maps
      my $value = $forward_compatibility_map->{$compatibility_map_key};
      if (defined $value) {
        printf "Campaign ID %d has forward compatibility map value of '%s'" .
          " for key '%s'.\n", $campaign->get_id(), $value,
          $compatibility_map_key;
        $campaign_map->{$campaign->get_id()} = $value;
      }
    }
  });

if (!keys %{$campaign_map}) {
  print "No forward compatibility maps were found.\n";
}

return $campaign_map;

Ruby

# Create selector.
# Notice there is no need to explicitly request the forwardCompatibilityMap,
# indeed adding it to the list of fields will throw an error.
selector = {
  :fields => ['Id'],
  :paging => {
    :start_index => 0,
    :number_results => PAGE_SIZE
  }
}

campaign_map = {}

# Iterate over all pages.
offset, page = 0, {}
begin
  page = campaign_srv.get(selector)
  if page[:entries]
    page[:entries].each do |campaign|
      unless campaign[:forward_compatibility_map].nil?
        value = campaign[:forward_compatibility_map][fcm_key]
        unless value.nil?
          puts ("Campaign ID %d has forward compatibility map value of '%s'" +
             " for key '%s'") % [campaign[:id], fcm_key, value]
          # This demonstrates how to handle a forward compatibility map key
          # where the value is a boolean. Check the forward compatibility map
          # documentation for the data type for each supported key:
          # https://developers.google.com/adwords/api/docs/guides/forward-compatibility-maps
          campaign_map[campaign[:id]] = (value.casecmp('true') >= 0)
        end
      end
    end
    # Increment values to request the next page.
    offset += PAGE_SIZE
    selector[:paging][:start_index] = offset
  end
end while page[:total_num_entries] > offset

return campaign_map

Changing properties from the map

Mutating keys through forwardCompatibilityMap is no different than with any other attribute: You just need to call the mutate() method, making sure the forwardCompatibilityMap is populated with the keys and values you want changed. The regular ADD and SET mutate operations accept forwardCompatibilityMap data, but may require a few provisions.

Be sure to pass a valid value for a key or an ApiException will result. Also, be sure the key name is correct, as wrong or undefined key names are silently ignored by the API, and can cause errors that are difficult to diagnose.

Mutate example

The following example demonstrates how to change a campaign by sending the key and value in the forwardCompatibilityMap.

Java

// This is an example on how to update a campaign using the
// CampaignService and the forwardCompatibilityMap field.

// Get the CampaignService.
CampaignServiceInterface campaignService =
    adWordsServices.get(session, CampaignServiceInterface.class);

// Create campaign with updated status.
Campaign campaign = new Campaign();
campaign.setId(campaignId);
// Set the forward compatibility map entry to "true" to update the campaign.
// This demonstrates how to handle a forward compatibility map key where
// the value is a boolean. Check the forward compatibility map documentation
// for the data type for each supported key:
// https://developers.google.com/adwords/api/docs/guides/forward-compatibility-maps
campaign.setForwardCompatibilityMap(
    new String_StringMapEntry[] {
      new String_StringMapEntry(compatibilityMapKey, Boolean.TRUE.toString())
    });

// Create operations.
CampaignOperation operation = new CampaignOperation();
operation.setOperand(campaign);
operation.setOperator(Operator.SET);

CampaignOperation[] operations = new CampaignOperation[] {operation};

// Update campaign.
CampaignReturnValue result = campaignService.mutate(operations);
System.out.printf(
    "Updated forward compatibility map of campaign ID %d.%n", result.getValue(0).getId());

C#

// This is an example on how to update a campaign using the
// CampaignService and the forwardCompatibilityMap field.

// Get the CampaignService.
CampaignService campaignService = (CampaignService)user.GetService(
    AdWordsService.v201708.CampaignService);

// Create campaign with updated status.
Campaign campaign = new Campaign();
campaign.id = campaignId;
// Set the forward compatibility map entry to "true" to update the campaign.
// This demonstrates how to handle a forward compatibility map key where
// the value is a boolean. Check the forward compatibility map documentation
// for the data type for each supported key:
// https://developers.google.com/adwords/api/docs/guides/forward-compatibility-maps
campaign.forwardCompatibilityMap = new String_StringMapEntry[] {
  new String_StringMapEntry() {
    key = compatibilityMapKey,
    value = Boolean.TrueString
  }
};

// Create operations.
CampaignOperation operation = new CampaignOperation();
operation.operand = campaign;
operation.@operator = Operator.SET;

try {
  CampaignOperation[] operations = new CampaignOperation[] { operation };

  // Update campaign.
  CampaignReturnValue result = campaignService.mutate(operations);
  Console.WriteLine("Updated forward compatibility map of campaign ID {0}.",
      result.value[0].id);
} catch (Exception e) {
  throw new System.ApplicationException("Failed to update forward compatibility map for " +
      "campaigns", e);
}

PHP

// This is an example on how to update a campaign using the
// CampaignService and the forwardCompatibilityMap field.

// Get the CampaignService.
$campaignService = $adWordsServices->get($session, CampaignService::class);

// Create campaign with updated status.
$campaign = new Campaign();
$campaign->setId($campaignId);
// Set the forward compatibility map entry to "true" to update the campaign.
// This demonstrates how to handle a forward compatibility map key
// where the value is a boolean. Check the forward compatibility map
// documentation for the data type for each supported key:
// https://developers.google.com/adwords/api/docs/guides/forward-compatibility-maps
$campaign->setForwardCompatibilityMap([
    new String_StringMapEntry($compatibilityMapKey, 'true')
]);

// Create operations.
$operation = new CampaignOperation();
$operation->setOperand($campaign);
$operation->setOperator(Operator::SET);

// Update campaign on the server.
$result = $campaignService->mutate([$operation]);
printf("Updated forward compatibility map of campaign ID %d.\n",
    $result->getValue()[0]->getId());

Python

# This is an example on how to update a campaign using the CampaignService and
# the forwardCompatibilityMap field.

# Get the CampaignService.
campaign_service = client.GetService('CampaignService', version='v201708')

# Create campaign with updated status.
campaign = {
    'id': campaign_id,
    # This demonstrates how to handle a forward compatibility map key where
    # the value is a boolean. Check the forward compatibility map
    # documentation for the data type for each supported key:
    # https://developers.google.com/adwords/api/docs/guides/forward-compatibility-maps
    'forwardCompatibilityMap': [{
        'key': compatibility_map_key,
        'value': str(True)
    }]
}

# Create operations.
operations = [{
    'operand': campaign,
    'operator': 'SET'
}]

# Update campaign.
updated_campaign = campaign_service.mutate(operations)['value'][0]
print 'Updated forward compatibility map of campaign ID "%d".' % (
    updated_campaign['id'])

Perl

# This is an example on how to update a campaign using the
# CampaignService and the forwardCompatibilityMap field.

# Create campaign with updated status.
my $campaign = Google::Ads::AdWords::v201708::Campaign->new({
  id => $campaign_id,
  # Set the forward compatibility map entry to "1" to update the campaign.
  # This demonstrates how to handle a forward compatibility map key
  # where the value is a boolean. Check the forward compatibility map
  # documentation for the data type for each supported key:
  # https://developers.google.com/adwords/api/docs/guides/forward-compatibility-maps
  forwardCompatibilityMap =>
    [Google::Ads::AdWords::v201708::String_StringMapEntry->new({
      key   => $compatibility_map_key,
      value => 1})]
});

my $operation = Google::Ads::AdWords::v201708::CampaignOperation->new({
  operand  => $campaign,
  operator => "SET"
});

# Update campaign on the server.
my $result = $client->CampaignService()->mutate({
  operations => [$operation]});

printf("Updated forward compatibility map of campaign ID %d.\n",
      $result->get_value()->[0]->get_id());

Ruby

# Prepare for updating campaign.
operation = {
  :operator => 'SET',
  :operand => {
    :id => campaign_id,
    # Set the forward compatibility map entry to "true" as an example.
    :forward_compatibility_map => [
      {:key => fcm_key, :value => true}
    ]
  }
}

# Update campaign.
response = campaign_srv.mutate([operation])
if response and response[:value]
  campaign = response[:value].first
  puts "Campaign ID %d was successfully updated." % campaign[:id]
else
  puts 'No campaigns were updated.'
end

Handling errors

Certain operations such as passing an invalid value of a key in the forwardCompatibilityMap will result in an ApiException containing an ApiError. This error will contain the fieldPath pointing to the forwardCompatibilityMap and the trigger populated with the offending value.

Passing an invalid key name may result in errors that are difficult to diagnose, since the API will silently allow passing the invalid key name.

It's also worth noting that keys are tied to API versions. A key that's valid in one version will cease to be accepted in a future version when its functionality is formally implemented in the API. If a key is passed to an API version that no longer accepts it, an ApiException will be returned.

FAQ

How do I request the forwardCompatibilityMap to be populated in the response? I don’t see a field name for it in the documentation.

You don’t have to request it as part of your Selector.fields, it will get populated if there is data attached to the object that should be returned in the map.

Why isn’t the forwardCompatibilityMap being populated?

Generally, because the object has no data attached to the key you're expecting to see in the map.

Will I get an error if I send the wrong key in the map?

No, but you need to be careful when specifying the name of the key because the API will silently ignore unrecognized keys.

I know there's a new field/key supported in an object but I don’t see the object having a forwardCompatibilityMap.

Only top level API entities, such as Campaign, AdGroup and AdGroupAd, expose the forwardCompatibilityMap. But some keys affect underlying objects.

What happens if I send the wrong value in the map?

If you set the right key but use an unsupported value, an ApiException will be returned.

Are keys exposed across all API versions?

No, keys are exposed and accepted only in API versions that don’t have the functionality already exposed.

Current ForwardCompatibilityMap keys

Available ForwardCompatibilityMap keys
Service
AdGroupAdService
Entity
AdGroupAd
Key name
Ad.type
Selector field
AdType
Type
Enum
Supported version
v201705
Read-only

Set to EXPANDED_DYNAMIC_SEARCH_AD for ExpandedDynamicSearchAds. For all other types of ads, this key will not be present in the forward compatibility map.

The ExpandedDynamicSearchAd type was introduced in v201705, but the corresponding Ad.type enum is not available. Use this key and its value to determine if a given ad is an ExpandedDynamicSearchAd.

Enviar comentarios sobre…

¿Necesitas ayuda? Visita nuestra página de asistencia.