使用欄位遮罩更新

在 Google Ads API 中,更新作業會使用欄位遮罩。欄位遮罩會列出您打算透過更新變更的所有欄位,而任何不在欄位遮罩中的指定欄位都會遭到忽略,即使已傳送至伺服器也不例外。

FieldMaskUtil

建議您使用內建的欄位遮罩公用程式產生欄位遮罩,這項公用程式可隱藏許多特定詳細資料,並監控您對實體欄位所做的變更,讓您自動產生欄位遮罩。

以下說明如何產生欄位遮罩,以便更新廣告活動:

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 方法,開始包含更新的區塊。在這個區塊結束時,公用程式會比較區塊後廣告活動的目前狀態,與區塊前廣告活動的初始狀態,並自動產生列舉已變更欄位的欄位遮罩。您可以在為變異呼叫建構運算時,為運算提供該欄位遮罩,如下所示:

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

這個方法會自動建立新的空白廣告活動資源,並根據您在區塊中所做的變更建構欄位遮罩,接著建構更新作業,並傳回已填入 updateupdate_mask 的最終作業。您也可以將廣告活動傳遞至 campaign 方法,藉此指定廣告活動的開始狀態。這個模式適用於所有支援更新作業的資源。

手動建立遮罩

如要從頭開始建立欄位遮罩,而不需要使用任何程式庫公用程式,請先建立 Google::Protobuf::FieldMask,然後建立陣列,並填入您要變更的所有欄位名稱,最後將陣列指派給欄位遮罩的 path 欄位。

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

更新訊息欄位及其子欄位

MESSAGE 欄位可以有子欄位 (例如 MaximizeConversions,其中有三個:target_cpa_microscpc_bid_ceiling_microscpc_bid_floor_micros),也可以沒有子欄位 (例如 ManualCpm)。

未定義子欄位的訊息欄位

更新未定義任何子欄位的 MESSAGE 欄位時,請使用 FieldMaskUtil 產生欄位遮罩,如前所述。

訊息欄位及其定義的子欄位

更新使用子欄位定義的 MESSAGE 欄位,但未明確設定該訊息的任何子欄位時,您必須手動將每個可變更MESSAGE 子欄位新增至 FieldMask,類似於先前從頭建立欄位遮罩的範例。

一個常見的例子是更新廣告活動的出價策略,但未在新的出價策略中設定任何欄位。以下範例說明如何更新廣告活動,以便使用 MaximizeConversions 出價策略,且不需在出價策略中設定任何子欄。

在本例中,使用 FieldMaskUtil 內建的比較功能無法達成預期目標。

以下程式碼會產生包含 maximize_conversions 的欄位遮罩。不過,Google Ads API 不允許這種行為,以免誤刪欄位並產生 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

以下程式碼示範如何正確清除 MaximizeConversions 出價策略的 target_cpa_micros 欄位。

# 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

請注意,「不正確」的程式碼在 Google Ads API protocol buffers 中定義為 optional 的欄位上確實能正常運作。但由於 target_cpa_micros 並非 optional 欄位,因此「不正確」的程式碼「不會」更新出價策略,以清除 target_cpa 欄位。