In the Google Ads API some message fields are defined as empty message objects,
such as campaign.manual_cpm
,
or they may only have optional fields that do not need to be set, for example
campaign.manual_cpc
. Setting these
fields is important to tell the API which bidding strategy to use for the given
Campaign, but it's not intuitive when the messages are empty.
When updating the campaign.name
field, which is a string, we set the field
by updating it directly as if it were a normal Python object attribute:
campaign.name = "Test campaign value"
campaign.manual_cpc
is a nested field, meaning it contains
another protobuf message and not a primitive type, like a string. You
can update its fields directly as well:
campaign.manual_cpc.enhanced_cpc_enabled = True
This will tell the API that this Campaign has a bidding strategy of manual_cpc
with enhanced CPC enabled.
But what if you want to use manual_cpm
, which is empty? Or manual_cpc
without enabling enhanced cpc? To do this you will need to copy a separate
empty instance of the class onto the campaign, for example:
client = GoogleAdsClient.load_from_storage()
empty_cpm = client.get_type('ManualCpm')
client.copy_from(campaign.manual_cpm, empty_cpm)
Note how manual_cpm
is specified for the campaign
object:
name {
value: "Test campaign value"
}
manual_cpm {
}
The manual_cpm
field is set, but none of its fields have values. When sending
request to the API that use this pattern, you can verify that you're setting the
empty message object correctly by enabling logging and inspecting the
request payload.
Lastly, you'll need to manually add this field to the request object's
update_mask
. The field mask helper has no mechanism to determine the
difference between a field that's been explicitly set to an empty object, and a
field that hasn't been set.
from google.api_core.protobuf_helpers import field_mask
campaign_operation.create = campaign
campaign_operation.update_mask = field_mask(None, campaign)
# Here we manually add the "manual_cpm" field
campaign_operation.update_mask.append("manual_cpm")