В API Google Ads обновления выполняются с помощью маски поля . Маска поля ( google.protobuf.FieldMask ) содержит список путей к полям в snake_case , которые вы намереваетесь изменить при обновлении. Любые указанные поля, не включенные в маску поля, игнорируются, даже если они отправляются на сервер.
утилита FieldMasks
Рекомендуемый способ генерации масок полей в клиентской библиотеке Java — использование встроенного класса FieldMasks , который позволяет генерировать маски полей из модифицированного объекта, а не создавать их с нуля.
Вот пример обновления кампании:
// Creates a Campaign object with the proper resource name and any other
// changes.
Campaign campaign =
Campaign.newBuilder()
.setResourceName(ResourceNames.campaign(customerId, campaignId))
.setStatus(CampaignStatus.PAUSED)
.build();
// Constructs an operation that updates the campaign, using the
// FieldMasks.allSetFieldsOf utility to derive the update mask. This mask tells
// the Google Ads API which attributes of the campaign you want to change.
CampaignOperation operation =
CampaignOperation.newBuilder()
.setUpdate(campaign)
.setUpdateMask(FieldMasks.allSetFieldsOf(campaign))
.build();
// Sends the operation in a mutate request.
MutateCampaignsResponse response =
campaignServiceClient.mutateCampaigns(
customerId.toString(), Collections.singletonList(operation));
В этом примере сначала создается пустой конструктор Campaign и задается его имя ресурса, чтобы API знал, какая кампания обновляется.
В примере затем вызывается метод FieldMasks.allSetFieldsOf() для кампании, чтобы автоматически создать маску поля, которая перечисляет все установленные поля. Вы можете передать возвращенную маску непосредственно в вызов обновления.
Если вам нужно работать с существующим объектом и обновить несколько полей, используйте FieldMasks.compare() следующим образом:
// Assumes existingCampaign was retrieved from a previous API call.
// Creates a new campaign based on the existing campaign and updates the
// campaign by setting its status to paused.
Campaign campaignToUpdate =
existingCampaign.toBuilder()
.setStatus(CampaignStatus.PAUSED)
.build();
// Constructs an operation that updates the campaign, using the
// FieldMasks.compare utility to derive the update mask. This mask tells the
// Google Ads API which attributes of the campaign you want to change.
CampaignOperation operation =
CampaignOperation.newBuilder()
.setUpdate(campaignToUpdate)
.setUpdateMask(FieldMasks.compare(existingCampaign, campaignToUpdate))
.build();
// Sends the operation in a mutate request.
MutateCampaignsResponse response =
campaignServiceClient.mutateCampaigns(
customerId.toString(), Collections.singletonList(operation));
Чтобы создать маску поля с нуля, создайте конструктор FieldMask и добавьте имя каждого поля, которое вы собираетесь изменить, snake_case :
FieldMask fieldMask =
FieldMask.newBuilder()
.addPaths("status")
.addPaths("name")
.build();
Обновить поля сообщения и их подполя.
Поля MESSAGE могут иметь подполя (например, MaximizeConversions , которое содержит target_cpa_micros , cpc_bid_ceiling_micros и cpc_bid_floor_micros ), или же не иметь подполей (например, ManualCpm ).
Поля сообщения, не имеющие определенных подполей.
При обновлении поля MESSAGE , для которого не определены подполя, используйте утилиту FieldMasks для генерации маски поля, как описано в предыдущем разделе.
Поля сообщения с определенными подполями
При обновлении поля MESSAGE , имеющего определенные подполя, без явного указания каких-либо из этих подполей в самом сообщении, необходимо вручную добавить каждое из изменяемых подполей MESSAGE в FieldMask , аналогично созданию маски поля с нуля.
Один из распространенных примеров — обновление стратегии назначения ставок кампании ( oneof полей campaign_bidding_strategy ) без указания каких-либо полей в новой стратегии назначения ставок. Следующий пример демонстрирует, как обновить кампанию, чтобы использовать стратегию назначения ставок MaximizeConversions без указания каких-либо подполей в стратегии назначения ставок.
В данном случае использование только методов allSetFieldsOf() и compare() класса FieldMasks не позволяет достичь желаемого результата.
В следующем примере генерируется маска поля, включающая maximize_conversions . Однако API Google Ads не допускает пути сообщений верхнего уровня, содержащие подполя в маске обновления (во избежание случайного удаления подполей), и возвращает ошибку FieldMaskError.FIELD_HAS_SUBFIELDS .
// Creates a campaign with the proper resource name and an empty
// MaximizeConversions field.
Campaign campaign =
Campaign.newBuilder()
.setResourceName(ResourceNames.campaign(customerId, campaignId))
.setMaximizeConversions(MaximizeConversions.newBuilder().build())
.build();
// Constructs an operation using FieldMasks.allSetFieldsOf to derive the update
// mask. The field mask includes 'maximize_conversions', which produces a
// FieldMaskError.FIELD_HAS_SUBFIELDS error.
CampaignOperation operation =
CampaignOperation.newBuilder()
.setUpdate(campaign)
.setUpdateMask(FieldMasks.allSetFieldsOf(campaign))
.build();
// Sends the operation in a mutate request that results in a
// FieldMaskError.FIELD_HAS_SUBFIELDS error because empty MESSAGE fields with
// subfields cannot be included directly in a field mask.
MutateCampaignsResponse response =
campaignServiceClient.mutateCampaigns(
customerId.toString(), Collections.singletonList(operation));
В следующем примере показано, как правильно обновить кампанию, чтобы использовать стратегию назначения ставок MaximizeConversions , не задавая никаких подполей. Узнайте больше о назначении стандартных и портфельных стратегий назначения ставок .
// Creates a Campaign object with the proper resource name.
Campaign campaign =
Campaign.newBuilder()
.setResourceName(ResourceNames.campaign(customerId, campaignId))
.build();
// Creates a field mask from the campaign and adds the mutable subfield
// ('maximize_conversions.target_cpa_micros') on the MaximizeConversions
// bidding strategy to the field mask. Because this subfield is included in the
// field mask while excluded from the campaign object, the Google Ads API
// switches the campaign's bidding strategy oneof to MaximizeConversions with
// target_cpa_micros unset.
FieldMask fieldMask =
FieldMasks.allSetFieldsOf(campaign).toBuilder()
.addPaths("maximize_conversions.target_cpa_micros")
.build();
// Creates an operation to update the campaign with the specified fields.
CampaignOperation operation =
CampaignOperation.newBuilder()
.setUpdate(campaign)
.setUpdateMask(fieldMask)
.build();
Чистые поля
Некоторые поля можно явно очистить. Аналогично предыдущему примеру, необходимо явно добавить эти поля в маску полей, оставив их незаданными в объекте сообщения. Например, предположим, что у вас есть кампания, использующая стратегию назначения ставок MaximizeConversions , и что поле target_cpa_micros имеет значение больше 0 .
Следующий код выполняется, но maximize_conversions.target_cpa_micros не очищается, как предполагалось:
// Creates a campaign with the proper resource name and a MaximizeConversions
// object with target_cpa_micros set to 0L.
Campaign campaign =
Campaign.newBuilder()
.setResourceName(ResourceNames.campaign(customerId, campaignId))
.setMaximizeConversions(
MaximizeConversions.newBuilder().setTargetCpaMicros(0L).build())
.setStatus(CampaignStatus.PAUSED)
.build();
// Constructs an operation using FieldMasks.allSetFieldsOf to derive the
// update mask.
CampaignOperation operation =
CampaignOperation.newBuilder()
.setUpdate(campaign)
.setUpdateMask(FieldMasks.allSetFieldsOf(campaign))
.build();
// Sends the operation in a mutate request that does not clear the field
// cleanly.
MutateCampaignsResponse response =
campaignServiceClient.mutateCampaigns(
customerId.toString(), Collections.singletonList(operation));
В следующем примере показано, как правильно очистить поле target_cpa_micros в стратегии назначения ставок MaximizeConversions .
// Creates a Campaign object with the proper resource name.
Campaign campaign =
Campaign.newBuilder()
.setResourceName(ResourceNames.campaign(customerId, campaignId))
.build();
// Constructs a field mask from the 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 fieldMask =
FieldMasks.allSetFieldsOf(campaign).toBuilder()
.addPaths("maximize_conversions.target_cpa_micros")
.build();
// Creates an operation to update the campaign with the specified field.
CampaignOperation operation =
CampaignOperation.newBuilder()
.setUpdate(campaign)
.setUpdateMask(fieldMask)
.build();