使用欄位遮罩更新

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

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 欄位。