Page Summary
-
Updates in the Google Ads API require a field mask that specifies all fields intended for change.
-
Field masks can be created manually or generated automatically using the built-in
FieldMasksutility. -
When updating message fields with subfields without explicitly setting the subfields, you must manually add the mutable subfields to the field mask to avoid errors.
-
To clear a field, it must be explicitly added to the field mask, even if setting it to a zero-like value in the entity object.
In the Google Ads API, updates are done using a field mask. The field mask lists
all the fields you intend to change with the update, and any specified fields
that aren't in the field mask are ignored, even if sent to the server. You
can create a field mask manually by creating a FieldMask
(Google\Protobuf\FieldMask), making an array populated with the names of all
the fields you intend to change, and then assigning that array to the field
mask's paths field.
You can also use our built-in field mask utility
(FieldMasks), which hides many of the specific details and
lets you generate field masks automatically by inspecting the changes you make
to the entity's fields.
Here's an example for updating a campaign:
$campaign = new Campaign([
'resource_name' => ResourceNames::forCampaign($customerId, $campaignId),
'status' => CampaignStatusEnum\CampaignStatus::PAUSED
]);
$campaignOperation = new CampaignOperation();
$campaignOperation->setUpdate($campaign);
$campaignOperation->setUpdateMask(FieldMasks::allSetFieldsOf($campaign));
This code first creates a Campaign object and then sets its resource name
using ResourceNames, so that the API knows which campaign is
being updated. status is also set to CampaignStatus::PAUSED.
The code then creates a CampaignOperation object and sets the previously
created campaign on it. After that, it uses
FieldMasks::allSetFieldsOf() to create a field
mask for the campaign by enumerating all modified fields. Finally, it passes the
returned mask to the campaign operation object.
Note that FieldMasks::allSetFieldsOf() is a convenience method for
FieldMasks::compare(). It compares your passed object to
an empty object of the same class. For example, in the earlier code, you could
have used FieldMasks::compare(new Campaign(), $campaign) instead of
FieldMasks::allSetFieldsOf($campaign).
Update message fields and their subfields
MESSAGE fields can have subfields (such as
MaximizeConversions, which includes subfields such as
target_cpa_micros, cpc_bid_ceiling_micros, and cpc_bid_floor_micros), or
they can have none at all (such as ManualCpm).
Message fields with no defined subfields
When updating a MESSAGE field that is not defined with any subfields, use
FieldMasks to generate a field mask, as previously described.
Message fields with defined subfields
When updating a MESSAGE field that is defined with subfields without
explicitly setting any of the subfields on that message, you must manually add
each of the mutable MESSAGE subfields to the FieldMask, similar to the
previous example that created a field mask from scratch.
One common example is updating a campaign's bidding strategy without setting any
of the fields on the new bidding strategy. The following code demonstrates how
to update a campaign to use the MaximizeConversions
bidding strategy without setting any of the subfields on the bidding strategy.
In this case, using the allSetFieldsOf() and compare() methods of
FieldMasks does not achieve the intended goal.
The following code generates a field mask that includes maximize_conversions.
However, the Google Ads API doesn't allow this behavior in order to prevent
accidentally clearing fields, and produces a
FieldMaskError.FIELD_HAS_SUBFIELDS error.
// Creates a campaign with the proper resource name and an empty
// MaximizeConversions field.
$campaign = new Campaign([
'resource_name' => ResourceNames::forCampaign($customerId, $campaignId),
'maximize_conversions' => new MaximizeConversions()
]);
// Constructs an operation, using the FieldMasks' allSetFieldsOf utility to
// derive the update mask. The field mask includes 'maximize_conversions',
// which produces a FieldMaskError.FIELD_HAS_SUBFIELDS error.
$campaignOperation = new CampaignOperation();
$campaignOperation->setUpdate($campaign);
$campaignOperation->setUpdateMask(FieldMasks::allSetFieldsOf($campaign));
// Sends the operation in a mutate request that results in a
// FieldMaskError.FIELD_HAS_SUBFIELDS error because empty MESSAGE fields cannot
// be included in a field mask.
$campaignServiceClient = $googleAdsClient->getCampaignServiceClient();
$response = $campaignServiceClient->mutateCampaigns(
MutateCampaignsRequest::build($customerId, [$campaignOperation])
);
The following code demonstrates how to properly update a campaign to use the
MaximizeConversions bidding strategy without setting any of its subfields.
// Creates a Campaign object with the proper resource name.
$campaign = new Campaign([
'resource_name' => ResourceNames::forCampaign($customerId, $campaignId)
]);
// Creates a field mask from the existing campaign and adds the mutable
// subfield on the MaximizeConversions bidding strategy to the field mask.
// Because this field is included in the field mask but excluded from the
// campaign object, the Google Ads API sets the campaign's bidding strategy
// to a MaximizeConversions object without any of its subfields set.
$fieldMask = FieldMasks::allSetFieldsOf($campaign);
// Only include 'maximize_conversions.target_cpa_micros' in the field mask
// as it is the only mutable subfield on MaximizeConversions when used as a
// standard bidding strategy.
//
// Learn more about standard and portfolio bidding strategies:
// https://developers.google.com/google-ads/api/docs/campaigns/bidding/assign-strategies
$fieldMask->getPaths()[] = 'maximize_conversions.target_cpa_micros';
// Creates an operation to update the campaign with the specified fields.
$campaignOperation = new CampaignOperation();
$campaignOperation->setUpdate($campaign);
$campaignOperation->setUpdateMask($fieldMask);
Clear fields
Some fields can be explicitly cleared. Similar to the earlier example, you must
explicitly add these fields to the field mask because FieldMasks ignores
Proto3 scalar fields set to their default values (such as 0, false, or
""). For example, assume you have a campaign that uses a
MaximizeConversions bidding strategy and that the target_cpa_micros field
is set with a value that is greater than 0.
The following code runs; however, maximize_conversions.target_cpa_micros
won't be added to the field mask and so no changes are made to the
target_cpa_micros field:
// Creates a campaign with the proper resource name and a MaximizeConversions
// object with target_cpa_micros set to 0.
$campaign = new Campaign([
'resource_name' => ResourceNames::forCampaign($customerId, $campaignId),
'maximize_conversions' => new MaximizeConversions([
'target_cpa_micros' => 0
]),
'status' => CampaignStatusEnum\CampaignStatus::PAUSED
]);
// Constructs an operation, using the FieldMasks' allSetFieldsOf utility to
// derive the update mask. However, the field mask does NOT include
// 'maximize_conversions.target_cpa_micros'.
$campaignOperation = new CampaignOperation();
$campaignOperation->setUpdate($campaign);
$campaignOperation->setUpdateMask(FieldMasks::allSetFieldsOf($campaign));
// Sends the operation in a mutate request that succeeds, but does NOT update
// the 'target_cpa_micros' field because
// 'maximize_conversions.target_cpa_micros' was not included in the field mask.
$campaignServiceClient = $googleAdsClient->getCampaignServiceClient();
$response = $campaignServiceClient->mutateCampaigns(
MutateCampaignsRequest::build($customerId, [$campaignOperation])
);
The following code demonstrates how to properly clear the target_cpa_micros
field on the MaximizeConversions bidding strategy.
// Creates a Campaign object with the proper resource name.
$campaign = new Campaign([
'resource_name' => ResourceNames::forCampaign($customerId, $campaignId)
]);
// Constructs a field mask from the existing campaign and adds the
// 'maximize_conversions.target_cpa_micros' field to the field mask, which
// clears this field from the bidding strategy without impacting any other
// fields on the bidding strategy.
$fieldMask = FieldMasks::allSetFieldsOf($campaign);
$fieldMask->getPaths()[] = 'maximize_conversions.target_cpa_micros';
// Creates an operation to update the campaign with the specified field.
$campaignOperation = new CampaignOperation();
$campaignOperation->setUpdate($campaign);
$campaignOperation->setUpdateMask($fieldMask);
Note that setting a default value does work as intended for fields that are
defined as optional in the Google Ads API protocol buffers. However,
because target_cpa_micros is not an optional field, setting
it to 0 without explicitly adding the path to the field mask does not update
the bidding strategy to clear target_cpa_micros.