Masques de champ

Dans l'API Google Ads, les modifications sont effectuées à l'aide d'un masque de champ. Le masque de champ (google.protobuf.FieldMask) contient une liste de chemins d'accès de champ dans snake_case que vous souhaitez modifier avec la mise à jour. Tous les champs spécifiés qui ne figurent pas dans le masque de champ sont ignorés, même s'ils sont envoyés au serveur.

Utilitaire FieldMasks

La méthode recommandée pour générer des masques de champ dans la bibliothèque cliente Java consiste à utiliser la classe utilitaire FieldMasks intégrée, qui vous permet de générer des masques de champ à partir d'un objet modifié au lieu de les créer de toutes pièces.

Voici un exemple de mise à jour d'une campagne :

// 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));

Cet exemple crée d'abord un générateur Campaign vide et définit son nom de ressource afin que l'API sache quelle campagne est mise à jour.

L'exemple appelle ensuite FieldMasks.allSetFieldsOf() sur la campagne pour générer automatiquement un masque de champ qui énumère tous les champs définis. Vous pouvez transmettre le masque renvoyé directement à l'appel de mise à jour.

Si vous devez travailler avec un objet existant et mettre à jour quelques champs, utilisez FieldMasks.compare() comme suit :

// 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));

Pour créer un masque de champ à partir de zéro, créez un compilateur FieldMask et ajoutez le nom snake_case de chaque champ que vous souhaitez modifier :

FieldMask fieldMask =
    FieldMask.newBuilder()
        .addPaths("status")
        .addPaths("name")
        .build();

Mettre à jour les champs de message et leurs sous-champs

Les champs MESSAGE peuvent comporter des sous-champs (comme MaximizeConversions, qui comporte target_cpa_micros, cpc_bid_ceiling_micros et cpc_bid_floor_micros) ou n'en comporter aucun (comme ManualCpm).

Champs de message sans sous-champs définis

Lorsque vous mettez à jour un champ MESSAGE qui n'est défini avec aucun sous-champ, utilisez l'utilitaire FieldMasks pour générer un masque de champ, comme décrit dans la section précédente.

Champs de message avec des sous-champs définis

Lorsque vous mettez à jour un champ MESSAGE qui comporte des sous-champs définis sans définir explicitement aucun des sous-champs de ce message, vous devez ajouter manuellement chacun des sous-champs MESSAGE modifiables au FieldMask, comme si vous créiez un masque de champ à partir de zéro.

Un exemple courant consiste à mettre à jour la stratégie d'enchères d'une campagne (champ oneof campaign_bidding_strategy) sans définir aucun des champs de la nouvelle stratégie d'enchères. L'exemple suivant montre comment mettre à jour une campagne pour utiliser la stratégie d'enchères MaximizeConversions sans définir aucun des sous-champs de la stratégie d'enchères.

Dans ce cas, l'utilisation des méthodes allSetFieldsOf() et compare() de FieldMasks seule ne permet pas d'atteindre l'objectif souhaité.

L'exemple suivant génère un masque de champ qui inclut maximize_conversions. Toutefois, l'API Google Ads n'autorise pas les chemins de message de premier niveau qui comportent des sous-champs dans un masque de mise à jour (pour éviter d'effacer accidentellement des sous-champs) et renvoie une erreur 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));

L'exemple suivant montre comment mettre à jour correctement une campagne pour utiliser la stratégie d'enchères MaximizeConversions sans définir aucun de ses sous-champs. En savoir plus sur l'attribution de stratégies d'enchères standards et de portefeuille

// 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();

Effacer les champs

Certains champs peuvent être effacés explicitement. Comme dans l'exemple précédent, vous devez ajouter explicitement ces champs au masque de champ tout en les laissant non définis dans l'objet de message. Par exemple, supposons que vous ayez une campagne qui utilise une stratégie d'enchères MaximizeConversions et que le champ target_cpa_micros soit défini sur une valeur supérieure à 0.

Le code suivant s'exécute, mais maximize_conversions.target_cpa_micros ne sera pas effacé comme prévu :

// 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));

L'exemple suivant montre comment effacer correctement le champ target_cpa_micros dans la stratégie d'enchères 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();