欄位遮罩

在 Google Ads API 中,更新作業是透過欄位遮罩完成。欄位遮罩會列出您打算透過更新變更的所有欄位,且系統會忽略任何指定的欄位 (即使傳送至伺服器),除非這些欄位位於欄位遮罩中。

FieldMasks 公用程式

建議使用內建的欄位遮罩公用程式 (FieldMasks) 產生欄位遮罩,這樣就能從修改過的物件產生欄位遮罩,不必從頭建構。

以下是更新廣告活動的範例:

use Google::Ads::GoogleAds::Utils::FieldMasks qw(all_set_fields_of field_mask);

my $campaign =
  Google::Ads::GoogleAds::V25::Resources::Campaign->new({
    resourceName =>
      Google::Ads::GoogleAds::V25::Utils::ResourceNames::campaign(
        $customer_id, $campaign_id
      ),
    status => "PAUSED",
    networkSettings =>
      Google::Ads::GoogleAds::V25::Resources::NetworkSettings
      ->new({
        targetSearchNetwork => "false",
      }),
  });

my $campaign_operation =
  Google::Ads::GoogleAds::V25::Services::CampaignService::CampaignOperation
  ->new({
    update     => $campaign,
    updateMask => all_set_fields_of($campaign),
  });

這個範例會先使用 ResourceNames 公用程式設定資源名稱,藉此建立 Campaign 物件,讓 API 知道要更新哪個廣告活動。

這個範例會使用廣告活動的 FieldMasks::all_set_fields_of() 方法,自動產生列舉所有已設定欄位的欄位遮罩。然後,您可以將傳回的遮罩直接傳遞至更新呼叫。

FieldMasks::all_set_fields_of() 是 FieldMasks::field_mask() 的便利方法。這個方法會將您傳遞的物件與相同類別的空白物件進行比較。在上述程式碼中,您也可以使用:

field_mask(
  Google::Ads::GoogleAds::V25::Resources::Campaign->new({}),
  $campaign
)

而非 all_set_fields_of($campaign)。

手動建立遮罩

如要從頭建立欄位遮罩,請先建立 Google::Ads::GoogleAds::Common::FieldMask 物件,然後建立陣列參照,其中填入您要變更的所有欄位名稱,最後將陣列參照指派給欄位遮罩的 paths 欄位:

my $field_mask = Google::Ads::GoogleAds::Common::FieldMask->new({
  paths => ["status", "name"],
});

更新物件欄位及其子欄位

物件欄位可以有子欄位 (例如 MaximizeConversions,其中包含 target_cpa_micros 等子欄位),也可以完全沒有子欄位 (例如 ManualCpm)。

未定義子欄位的物件欄位

Perl 中的物件欄位等同於在 gRPC 上執行的用戶端程式庫中的 protobuf MESSAGE。更新未定義任何子欄位的物件欄位時,請使用 FieldMasks 公用程式產生欄位遮罩,如上一節所述。

定義子欄位的物件欄位

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

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

在這種情況下,使用 FieldMasks 公用程式的 all_set_fields_of() 和 field_mask() 方法無法達成預期目標。

以下範例會產生包含 maximize_conversions 的欄位遮罩。不過,Google Ads API 不允許這種行為,以免不小心清除欄位,並產生 FieldMaskError.FIELD_HAS_SUBFIELDS 錯誤。

# Creates a campaign with the proper resource name and an empty
# MaximizeConversions field.
my $campaign =
  Google::Ads::GoogleAds::V25::Resources::Campaign->new({
    resourceName =>
      Google::Ads::GoogleAds::V25::Utils::ResourceNames::campaign(
        $customer_id, $campaign_id
      ),
    maximizeConversions =>
      Google::Ads::GoogleAds::V25::Resources::MaximizeConversions
      ->new(),
  });

# Constructs an operation, using the FieldMasks' all_set_fields_of utility to
# derive the update mask. The field mask includes 'maximize_conversions',
# which produces a FieldMaskError.FIELD_HAS_SUBFIELDS error.
my $campaign_operation =
  Google::Ads::GoogleAds::V25::Services::CampaignService::CampaignOperation
  ->new({
    update     => $campaign,
    updateMask => all_set_fields_of($campaign),
  });

# Sends the operation in a mutate request that results in a
# FieldMaskError.FIELD_HAS_SUBFIELDS error because empty object fields cannot
# be included in a field mask.
my $response = $api_client->CampaignService()->mutate({
  customerId => $customer_id,
  operations => [$campaign_operation],
});

以下範例說明如何正確更新廣告活動,以使用 MaximizeConversions 出價策略,而不設定任何子欄位。

# Creates a campaign with the proper resource name.
my $campaign =
  Google::Ads::GoogleAds::V25::Resources::Campaign->new({
    resourceName =>
      Google::Ads::GoogleAds::V25::Utils::ResourceNames::campaign(
        $customer_id, $campaign_id
      ),
  });

# Creates a field mask from the existing campaign and adds the mutable subfield
# on the MaximizeConversions bidding strategy to the field mask. Because this
# field is included in the field mask but excluded from the campaign object,
# the Google Ads API sets the campaign's bidding strategy to a
# MaximizeConversions object with none of its subfields set.
# Only include 'maximize_conversions.target_cpa_micros' in the field mask
# as it is the only mutable subfield on MaximizeConversions when used as a
# standard bidding strategy.
#
# See the guide on assigning standard and portfolio bidding strategies
# (/google-ads/api/docs/campaigns/bidding/assign-strategies).
my $field_mask = all_set_fields_of($campaign);
push @{$field_mask->{paths}}, "maximize_conversions.target_cpa_micros";

# Creates an operation to update the campaign with the specified fields.
my $campaign_operation =
  Google::Ads::GoogleAds::V25::Services::CampaignService::CampaignOperation
  ->new({
    update     => $campaign,
    updateMask => $field_mask,
  });

清除欄位

如要明確清除欄位,請將欄位新增至欄位遮罩 (如上例所示),或將欄位設為空白或未定義的值。舉例來說,假設您有一個廣告活動採用 MaximizeConversions 出價策略,且 target_cpa_micros 欄位的值大於 0。

# Creates a campaign with the proper resource name and a MaximizeConversions
# object with target_cpa_micros set to 0.
my $campaign =
  Google::Ads::GoogleAds::V25::Resources::Campaign->new({
    resourceName =>
      Google::Ads::GoogleAds::V25::Utils::ResourceNames::campaign(
        $customer_id, $campaign_id
      ),
    maximizeConversions =>
      Google::Ads::GoogleAds::V25::Resources::MaximizeConversions
      ->new({
        targetCpaMicros => 0,
      }),
  });

# Constructs an operation using all_set_fields_of to derive the update mask,
# which includes 'maximize_conversions.target_cpa_micros'.
my $campaign_operation =
  Google::Ads::GoogleAds::V25::Services::CampaignService::CampaignOperation
  ->new({
    update     => $campaign,
    updateMask => all_set_fields_of($campaign),
  });

請注意,如要清除含有巢狀子欄位的欄位,只能清除每個子欄位,如「已定義子欄位的物件欄位」所示。