Máscaras de campo

En la API de Google Ads, las actualizaciones se realizan mediante una máscara de campo. La máscara de campo enumera todos los campos que deseas cambiar con la actualización y los campos especificados que no estén en la máscara de campo se ignoran, incluso si se envían al servidor. Podrías crear una máscara de campo de forma manual si creas un Google\Protobuf\FieldMask, si haces que se propague un array con los nombres de todos los campos que deseas cambiar y, luego, lo asignas al campo de ruta de acceso de la máscara de campo.

También puedes usar nuestra utilidad de máscara de campo integrada (FieldMasks), que oculta muchos detalles específicos y te permite generar máscaras de campo automáticamente mediante la supervisión de los cambios que realizas en los campos de la entidad.

A continuación, le mostramos un ejemplo de cómo actualizar una campaña:

    $campaign = new Campaign([
        'resource_name' => ResourceNames::forCampaign($customerId, $campaignId),
        'status' => CampaignStatus::PAUSED
    ]);

    $campaignOperation = new CampaignOperation();
    $campaignOperation->setUpdate($campaign);
    $campaignOperation->setUpdateMask(FieldMasks::allSetFieldsOf($campaign));

Este código primero crea un objeto Campaign y, luego, establece su nombre de recurso mediante ResourceNames, de modo que la API sepa qué campaña se está actualizando. status también se configura como PAUSED.

Luego, el código crea un objeto CampaignOperation y establece la campaña creada anteriormente en él. Luego, usa FieldMasks::allSetFieldsOf() para crear una máscara de campo para la campaña con todos los campos modificados. Por último, pasa la máscara que se muestra al objeto de operación de la campaña.

Ten en cuenta que FieldMasks::allSetFieldsOf es un método conveniente para FieldMasks::compare(). Compara el objeto que se pasó con un objeto vacío de la misma clase. Por ejemplo, en el código anterior, podrías haber usado FieldMasks::compare(new Campaign(), $campaign) en lugar de allSetFieldsOf().

Actualiza los campos de mensaje y sus subcampos

Los campos MESSAGE pueden tener subcampos (como MaximizeConversions, que tiene tres: target_cpa_micros, cpc_bid_ceiling_micros y cpc_bid_floor_micros), o no pueden tener ninguno (como ManualCpm).

Campos de mensaje sin subcampos definidos

Cuando actualices un campo MESSAGE que no esté definido con ningún subcampo, usa FieldMasks para generar una máscara de campo, como se describió antes.

Campos de mensaje con subcampos definidos

Cuando actualizas un campo MESSAGE que se define con subcampos sin configurar explícitamente ninguno de los subcampos en ese mensaje, debes agregar de forma manual cada uno de los subcampos MESSAGE mutables a FieldMask, similar al ejemplo anterior en el que se creó una máscara de campo desde cero.

Un ejemplo común es actualizar la estrategia de ofertas de una campaña sin configurar ninguno de los campos en la estrategia de ofertas nueva. En el siguiente código, se muestra cómo actualizar una campaña para usar la estrategia de ofertas MaximizeConversions sin configurar ninguno de los subcampos de la estrategia de ofertas.

En este caso, el uso de los métodos allSetFieldsOf() y compare() de FieldMasks no logra el objetivo previsto.

El siguiente código genera una máscara de campo que incluye maximize_conversions. Sin embargo, la API de Google Ads no permite este comportamiento para evitar borrar campos por accidente y generar un error FieldMaskError.FIELD_HAS_SUBFIELDS.

// 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 will include 'maximize_conversions`,
// which will produce 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 will result in a
// FieldMaskError.FIELD_HAS_SUBFIELDS error because empty MESSAGE fields cannot
// be included in a field mask.
$campaignServiceClient = $googleAdsClient->getCampaignServiceClient();
$response = $campaignServiceClient->mutateCampaigns($customerId, [$campaignOperation]);

En el siguiente código, se muestra cómo actualizar correctamente una campaña para usar la estrategia de ofertas MaximizeConversions sin configurar ninguno de sus subcampos.

// 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 all of the mutable
// fields (only one in this case) 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 will set 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 here:
// https://developers.google.com/google-ads/api/docs/campaigns/bidding/assign-strategies
$fieldMask->setPaths(array_merge(
    iterator_to_array($fieldMask->getPaths()->getIterator()),
    ['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);

Borrando campos

Algunos campos se pueden borrar de forma explícita. Al igual que en el ejemplo anterior, debes agregar de forma explícita estos campos a la máscara de campo. Por ejemplo, supongamos que tienes una campaña que usa una estrategia de ofertas MaximizeConversions y que el campo target_cpa_micros está configurado con un valor superior a 0.

Se ejecuta el siguiente código. Sin embargo, no se agregará maximize_conversions.target_cpa_micros a la máscara de campo, por lo que no se realizarán cambios en el campo target_cpa_micros:

// 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' => 0]),
    'status' => CampaignStatus::PAUSED
]);

// Constructs an operation, using the FieldMasks' allSetFieldsOf utility to
// derive the update mask. However, the field mask will 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 will succeed but will 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($customerId, [$campaignOperation]);

En el siguiente código, se muestra cómo borrar correctamente el campo target_cpa_micros de la estrategia de ofertas MaximizeConversions.

// 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 will
// clear this field from the bidding strategy without impacting any other fields
// on the bidding strategy.
$fieldMask = FieldMasks::allSetFieldsOf($campaign);
$fieldMask->setPaths(array_merge(
    iterator_to_array($fieldMask->getPaths()->getIterator()),
    ['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);

Ten en cuenta que el código "incorrecto" funciona según lo previsto para los campos que se definen como optional en protocol buffers de la API de Google Ads. Sin embargo, como el target_cpa_micros no es un campo optional, el código "incorrecto" no actualiza la estrategia de oferta para borrar el campo target_cpa.