Обновления с использованием масок полей

В Google Ads API обновления выполняются с использованием маски поля. В маске поля перечислены все поля, которые вы собираетесь изменить при обновлении, а любые указанные поля, которых нет в маске поля, игнорируются, даже если они отправлены на сервер.

ПолеМаскаУтилита

Рекомендуемый способ создания масок полей — использование нашей встроенной утилиты маски полей, которая скрывает множество конкретных деталей и позволяет автоматически создавать маски полей, отслеживая изменения, вносимые вами в поля сущности.

Вот как можно создать маску поля для обновления кампании:

campaign = client.resource.campaign
campaign.resource_name = client.path.campaign(customer_id, campaign_id)

mask = client.field_mask.with campaign do
  campaign.status = :PAUSED
  campaign.network_settings = client.resource.network_settings do |ns|
    ns.target_search_network = false
  end
end

Код сначала создает пустой объект Campaign, затем задает имя его ресурса, чтобы сообщить API об обновляемой кампании.

В этом примере используется метод client.field_mask.with кампании, чтобы начать блок, включающий обновления. В конце этого блока утилита сравнивает текущий статус кампании после блокировки с исходным статусом кампании до блокировки и автоматически формирует маску поля, перечисляющую измененные поля. Вы можете предоставить эту маску поля операции при ее создании для вызова mutate следующим образом:

operation = client.operation.campaign
operation.update = campaign
operation.update_mask = mask

Этот метод рекомендуется, когда вы выполняете сложную операцию и хотите точно контролировать каждый шаг. Однако в большинстве случаев вы можете использовать более простую утилиту библиотеки Ruby:

operation = client.operation.update_resource.campaign do |c|
  c.status = :PAUSED
  c.network_settings = client.resource.network_settings do |ns|
    ns.target_search_network = false
  end
end

Этот метод автоматически создает новый пустой ресурс кампании, создает маску поля на основе изменений, внесенных вами в блоке, строит операцию обновления и возвращает окончательную операцию с уже заполненными update и update_mask . Вы также можете передать кампанию методу campaign , чтобы указать начальное состояние кампании. Этот шаблон работает для всех ресурсов, поддерживающих операцию обновления.

Создание маски вручную

Чтобы создать маску поля с нуля, без использования каких-либо библиотечных утилит, вы должны сначала создать Google::Protobuf::FieldMask , затем создать массив, заполненный именами всех полей, которые вы собираетесь изменить, и, наконец, присвоить массив Поле path маски поля.

mask = Google::Protobuf::FieldMask.new
mask.path = ["status", "name"]

Обновление полей сообщений и их подполей

Поля MESSAGE могут иметь подполя (например, MaximizeConversions , у которого их три: target_cpa_micros , cpc_bid_ceiling_micros и cpc_bid_floor_micros ) или вообще не иметь их (например, ManualCpm ).

Поля сообщений без определенных подполей

При обновлении поля MESSAGE , которое не определено какими-либо подполями, используйте FieldMaskUtil для создания маски поля, как было представлено ранее.

Поля сообщений с определенными подполями

При обновлении поля MESSAGE , которое определено с подполями, без явной установки каких-либо подполей в этом сообщении, вы должны вручную добавить каждое из изменяемых подполей MESSAGE в FieldMask , аналогично предыдущему примеру, в котором маска поля создавалась с нуля.

Одним из распространенных примеров является обновление стратегии назначения ставок кампании без задания каких-либо полей в новой стратегии назначения ставок. В следующем примере показано, как обновить кампанию для использования стратегии назначения ставок MaximizeConversions не задавая никаких подполей в стратегии назначения ставок.

В этом примере использование встроенного сравнения FieldMaskUtil не достигает намеченной цели.

Следующий код генерирует маску поля, включающую в себя maximize_conversions . Однако API Google Рекламы не допускает такого поведения во избежание случайной очистки полей и выдает ошибку FieldMaskError.FIELD_HAS_SUBFIELDS .

# Creates a campaign with the proper resource name.
campaign = client.resource.campaign do |c|
  c.resource_name = client.path.campaign(customer_id, campaign_id)
end

# Update the maximize conversions field within the update block, so it's
# captured in the field mask
operation = client.operation.update_resource.campaign(campaign) do |c|
  c.maximize_conversions = client.resource.maximize_conversions
end

# 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.
response = client.service.campaign.mutate_campaigns(
  customer_id: customer_id,
  operations: [operation],
)

В следующем коде показано, как правильно обновить кампанию для использования стратегии назначения ставок MaximizeConversions , не задавая ни одного из ее подполей.

# Create the operation directly from the campaign's resource name. Don't do
# anything in the block so that the field mask is empty. You could modify other
# fields in this block, just not the message field that is intended to have a
# blank subfield. We'll add that below.
campaign_resource_name = client.path.campaign(customer_id, campaign_id)
operation = client.operation.update_resource.campaign(campaign_resource_name) {}

# Manually add the maximize conversions subfield to the field mask so the API
# knows to clear it.
operation.update_mask.paths << "maximize_conversions.target_cpa_micros"

# This operation succeeds.
response = client.service.campaign.mutate_campaigns(
  customer_id: customer_id,
  operations: [operation],
)

Очистка полей

Некоторые поля можно очистить явно. Как и в предыдущем примере, вы должны явно добавить эти поля в маску поля. Например, предположим, что у вас есть кампания, в которой используется стратегия назначения ставок MaximizeConversions , и в поле target_cpa_micros установлено значение больше 0 .

Выполняется следующий код; однако maximize_conversions.target_cpa_micros не будет добавлен в маску поля, поэтому в поле target_cpa_micros не будет внесено никаких изменений:

# Create a campaign object representing the campaign you want to change.
campaign = client.resource.campaign do |c|
  c.resource_name = client.path.campaign(customer_id, campaign_id)
end

# The field mask in this operation will include 'maximize_conversions',
# but not 'maximize_conversions.target_cpa_micros', so it will result in an
# error.
operation = client.operation.update_resource.campaign(campaign) do |c|
  c.maximize_conversions = client.resource.maximize_conversions do |mc|
    mc.target_cpa_micros = 0
  end
end

# Operation will fail since field mask is incorrect.
response = client.service.campaign.mutate_campaigns(
  customer_id: customer_id,
  operations: [operation],
end

Следующий код демонстрирует, как правильно очистить поле target_cpa_micros в стратегии назначения ставок MaximizeConversions .

# Create a campaign including the maximize conversions fields right away, since
# we're going to manually add them to the field mask.
campaign = client.resource.campaign do |c|
  c.resource_name = client.path.campaign(customer_id, campaign_id)
  c.maximize_conversions = client.resource.maximize_conversions do |mc|
    mc.target_cpa_micros = 0
  end
end

# Create the operation with an empty field mask. You may add a block here with
# other changes that will automatically get added to the field mask.
operation = client.operation.update_resource.campaign(campaign) {}

# Add the field to the field mask so the API knows to clear it.
operation.update_mask.paths << 'maximize_conversions.target_cpa_micros'

# Operation will succeed since we specified the correct field mask.
response = client.service.campaign.mutate_campaigns(
  customer_id: customer_id,
  operations: [operation],
end

Обратите внимание, что «неправильный» код работает должным образом для полей, которые определены как optional в protocol buffers API Google Рекламы. Но поскольку поле target_cpa_micros не является optional , «неправильный» код не обновляет стратегию назначения ставок и не очищает поле target_cpa .