Установка пустых объектов сообщений в качестве полей

В API Google Рекламы некоторые поля сообщений определяются как пустые объекты сообщений, например campaign.manual_cpm , или могут иметь только необязательные поля, которые не нужно задавать, например campaign.manual_cpc . Установка этих полей важна, чтобы сообщить API, какую стратегию назначения ставок использовать для данной кампании, но это не интуитивно понятно, когда сообщения пусты.

При обновлении поля campaign.name , которое представляет собой строку, мы устанавливаем это поле, обновляя его напрямую, как если бы оно было обычным атрибутом объекта Python:

campaign.name = "Test campaign value"

campaign.manual_cpc — это вложенное поле, то есть оно содержит другое сообщение protobuf, а не примитивный тип, такой как строка. Вы также можете обновить его поля напрямую:

campaign.manual_cpc.enhanced_cpc_enabled = True

Это сообщит API, что в этой кампании используется стратегия назначения ставок manual_cpc с включенной функцией повышения цены за клик.

Но что, если вы хотите использовать manual_cpm , который пуст? Или manual_cpc без включения расширенной цены за клик? Для этого вам нужно будет скопировать в кампанию отдельный пустой экземпляр класса, например:

client = GoogleAdsClient.load_from_storage()

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

Обратите внимание, как для объекта campaign указывается manual_cpm :

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

Поле manual_cpm установлено, но ни одно из его полей не имеет значений. При отправке запроса в API, использующий этот шаблон, вы можете убедиться, что вы правильно устанавливаете пустой объект сообщения, включив ведение журнала и проверив полезные данные запроса.

Наконец, вам нужно будет вручную добавить это поле в update_mask объекта запроса. Помощник маски поля не имеет механизма для определения разницы между полем, которому явно присвоен пустой объект, и полем, которое не было установлено.

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