Como definir objetos de mensagem vazios como campos

Na API Google Ads, alguns campos de mensagem são definidos como objetos de mensagem vazios, como campaign.manual_cpm, ou podem ter apenas campos opcionais que não precisam ser definidos, por exemplo, campaign.manual_cpc. Definir esses campos é importante para informar à API qual estratégia de lances usar na campanha especificada, mas não é intuitivo quando as mensagens estão vazias.

Ao atualizar o campo campaign.name, que é uma string, definimos o campo atualizando-o diretamente como se fosse um atributo de objeto Python normal:

campaign.name = "Test campaign value"

campaign.manual_cpc é um campo aninhado, ou seja, contém outra mensagem protobuf e não um tipo primitivo, como uma string. Você também pode atualizar os campos diretamente:

campaign.manual_cpc.enhanced_cpc_enabled = True

Isso informa à API que a campanha tem uma estratégia de lances de manual_cpc com o CPC otimizado ativado.

Mas e se você quiser usar manual_cpm, que está vazio? Ou manual_cpc sem ativar o CPC otimizado? Para fazer isso, copie uma instância vazia separada da classe para a campanha. Por exemplo:

client = GoogleAdsClient.load_from_storage()

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

Observe como manual_cpm é especificado para o objeto campaign:

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

O campo manual_cpm está definido, mas nenhum dos campos dele tem valores. Ao enviar solicitações para a API que usa esse padrão, verifique se você está definindo o objeto de mensagem vazia corretamente ativando o registro em log e inspecionando o payload da solicitação.

Por fim, adicione manualmente esse campo ao update_mask do objeto de solicitação. O auxiliar de máscara de campo não tem um mecanismo para determinar a diferença entre um campo que foi definido explicitamente como um objeto vazio e um campo que não foi definido.

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