Cómo configurar objetos de mensaje vacíos como campos

En la API de Google Ads, algunos campos de mensajes se definen como objetos de mensajes vacíos, como campaign.manual_cpm, o pueden tener solo campos opcionales que no es necesario configurar, por ejemplo, campaign.manual_cpc. Es importante configurar estos campos para indicarle a la API qué estrategia de ofertas debe usar para la campaña determinada, pero no es intuitivo cuando los mensajes están vacíos.

Cuando actualizamos el campo campaign.name, que es una cadena, lo establecemos actualizándolo directamente como si fuera un atributo de objeto de Python normal:

campaign.name = "Test campaign value"

campaign.manual_cpc es un campo anidado, lo que significa que contiene otro mensaje de protobuf y no un tipo primitivo, como una cadena. También puedes actualizar sus campos directamente:

campaign.manual_cpc.enhanced_cpc_enabled = True

Esto le indicará a la API que esta campaña tiene una estrategia de ofertas de manual_cpc con el CPC avanzado habilitado.

Pero, ¿qué sucede si quieres usar manual_cpm, que está vacío? ¿O manual_cpcsin habilitar el CPC avanzado? Para ello, deberás copiar una instancia vacía independiente de la clase en la campaña, por ejemplo:

client = GoogleAdsClient.load_from_storage()

empty_cpm = client.get_type('ManualCpm')
client.copy_from(campaign.manual_cpm, empty_cpm)

Observa cómo se especifica manual_cpm para el objeto campaign:

name {
  value: "Test campaign value"
}
manual_cpm {
}

El campo manual_cpm está configurado, pero ninguno de sus campos tiene valores. Cuando envíes solicitudes a la API que usen este patrón, puedes verificar que estás configurando el objeto de mensaje vacío correctamente habilitando el registro y, luego, inspeccionando la carga útil de la solicitud.

Por último, deberás agregar manualmente este campo al update_mask del objeto de solicitud. El asistente de máscara de campo no tiene un mecanismo para determinar la diferencia entre un campo que se configuró de forma explícita como un objeto vacío y un campo que no se configuró.

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")