En la API de Google Ads, las actualizaciones se realizan con una máscara de campo. La máscara de campo (google.protobuf.FieldMask) contiene una lista de rutas de campo en snake_case que deseas cambiar con la actualización. Se ignorarán todos los campos especificados que no estén en la máscara de campo, incluso si se envían al servidor.
Utilidad de FieldMasks
La forma recomendada de generar máscaras de campo en la biblioteca cliente de Java es usar la clase de utilidad FieldMasks integrada, que te permite generar máscaras de campo a partir de un objeto modificado en lugar de crearlas desde cero.
A continuación, se incluye un ejemplo para actualizar una campaña:
// 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));
En este ejemplo, primero se crea un compilador Campaign vacío y se establece su nombre de recurso para que la API sepa qué campaña se está actualizando.
Luego, el ejemplo llama a FieldMasks.allSetFieldsOf() en la campaña para producir automáticamente una máscara de campo que enumera todos los campos establecidos. Puedes pasar la máscara devuelta directamente a la llamada de actualización.
Si necesitas trabajar con un objeto existente y actualizar algunos campos, usa FieldMasks.compare() de la siguiente manera:
// 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));
Para crear una máscara de campo desde cero, crea un compilador FieldMask y agrega el nombre snake_case de cada campo que desees cambiar:
FieldMask fieldMask =
FieldMask.newBuilder()
.addPaths("status")
.addPaths("name")
.build();
Actualiza los campos de mensajes y sus subcampos
Los campos MESSAGE pueden tener subcampos (como MaximizeConversions, que tiene target_cpa_micros, cpc_bid_ceiling_micros y cpc_bid_floor_micros) o no tener subcampos (como ManualCpm).
Campos de mensajes sin subcampos definidos
Cuando actualices un campo MESSAGE que no esté definido con ningún subcampo, usa la utilidad FieldMasks para generar una máscara de campo, como se describe en la sección anterior.
Campos de mensajes con subcampos definidos
Cuando actualices un campo MESSAGE que tenga subcampos definidos sin establecer explícitamente ninguno de los subcampos en ese mensaje, debes agregar manualmente cada uno de los subcampos MESSAGE mutables al FieldMask, de manera similar a la creación de una máscara de campo desde cero.
Un ejemplo común es actualizar la estrategia de ofertas de una campaña (campo oneof campaign_bidding_strategy) sin configurar ninguno de los campos de la nueva estrategia de ofertas. En el siguiente ejemplo, se muestra cómo actualizar una campaña para que use la estrategia de ofertas MaximizeConversions sin configurar ninguno de los subcampos de la estrategia de ofertas.
En este caso, usar solo los métodos allSetFieldsOf() y compare() de FieldMasks no logra el objetivo previsto.
En el siguiente ejemplo, se genera una máscara de campo que incluye maximize_conversions. Sin embargo, la API de Google Ads no permite rutas de mensajes de nivel superior que tengan subcampos en una máscara de actualización (para evitar que se borren subcampos accidentalmente) y devuelve un error 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));
En el siguiente ejemplo, se muestra cómo actualizar correctamente una campaña para que use la estrategia de ofertas MaximizeConversions sin configurar ninguno de sus subcampos.
Obtén más información para asignar estrategias de ofertas estándar y de cartera.
// 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();
Borrar campos
Algunos campos se pueden borrar de forma explícita. De manera similar al ejemplo anterior, debes agregar estos campos de forma explícita a la máscara de campo y dejarlos sin configurar en el objeto del mensaje. Por ejemplo, supongamos que tienes una campaña que utiliza una estrategia de ofertas MaximizeConversions y que el campo target_cpa_micros está configurado con un valor superior a 0.
El siguiente código se ejecuta, pero maximize_conversions.target_cpa_micros no se borrará según lo previsto:
// 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));
En el siguiente ejemplo, se muestra cómo borrar correctamente el campo target_cpa_micros en la estrategia de ofertas 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();