필드 마스크

Google Ads API에서는 필드 마스크를 사용하여 업데이트가 수행됩니다. 필드 마스크는 업데이트로 변경하려는 모든 필드를 나열하며, 필드 마스크에 없는 지정된 필드는 서버로 전송되더라도 무시됩니다. FieldMask(Google\Protobuf\FieldMask)를 만들고 변경하려는 모든 필드의 이름으로 채워진 배열을 만든 다음 해당 배열을 필드 마스크의 paths 필드에 할당하여 필드 마스크를 수동으로 만들 수 있습니다.

기본 제공 필드 마스크 유틸리티(FieldMasks)를 사용할 수도 있습니다. 이 유틸리티는 많은 세부정보를 숨기고 항목 필드에 대한 변경사항을 검사하여 필드 마스크를 자동으로 생성할 수 있게 해줍니다.

다음은 캠페인을 업데이트하는 예입니다.

$campaign = new Campaign([
    'resource_name' => ResourceNames::forCampaign($customerId, $campaignId),
    'status' => CampaignStatusEnum\CampaignStatus::PAUSED
]);

$campaignOperation = new CampaignOperation();
$campaignOperation->setUpdate($campaign);
$campaignOperation->setUpdateMask(FieldMasks::allSetFieldsOf($campaign));

이 코드는 먼저 Campaign 객체를 만든 다음 ResourceNames를 사용하여 리소스 이름을 설정하므로 API는 업데이트 중인 캠페인을 알 수 있습니다. status도 CampaignStatus::PAUSED로 설정됩니다.

그런 다음 코드는 CampaignOperation 객체를 만들고 이전에 만든 캠페인을 설정합니다. 그런 다음 FieldMasks::allSetFieldsOf()를 사용하여 수정된 모든 필드를 열거하여 캠페인의 필드 마스크를 만듭니다. 마지막으로 반환된 마스크를 캠페인 작업 객체에 전달합니다.

FieldMasks::allSetFieldsOf()는 FieldMasks::compare()의 편의 메서드입니다. 전달된 객체를 동일한 클래스의 빈 객체와 비교합니다. 예를 들어 이전 코드에서 FieldMasks::allSetFieldsOf($campaign) 대신 FieldMasks::compare(new Campaign(), $campaign)를 사용할 수 있습니다.

메시지 필드 및 하위 필드 업데이트

MESSAGE 필드에는 하위 필드 (예: target_cpa_micros, cpc_bid_ceiling_micros, cpc_bid_floor_micros 등의 하위 필드를 포함하는 MaximizeConversions)가 있을 수 있으며, 하위 필드가 전혀 없을 수도 있습니다 (예: ManualCpm).

정의된 하위 필드가 없는 메시지 필드

하위 필드로 정의되지 않은 MESSAGE 필드를 업데이트할 때는 앞에서 설명한 대로 FieldMasks를 사용하여 필드 마스크를 생성합니다.

정의된 하위 필드가 있는 메시지 필드

메시지에서 하위 필드를 명시적으로 설정하지 않고 하위 필드로 정의된 MESSAGE 필드를 업데이트할 때는 처음부터 필드 마스크를 만든 이전 예시와 유사하게 각 변경 가능한 MESSAGE 하위 필드를 FieldMask에 수동으로 추가해야 합니다.

한 가지 일반적인 예는 새 입찰 전략에 필드를 설정하지 않고 캠페인의 입찰 전략을 업데이트하는 것입니다. 다음 코드는 입찰 전략의 하위 필드를 설정하지 않고 MaximizeConversions 입찰 전략을 사용하도록 캠페인을 업데이트하는 방법을 보여줍니다.

이 경우 FieldMasks의 allSetFieldsOf() 및 compare() 메서드를 사용해도 의도한 목표를 달성할 수 없습니다.

다음 코드는 maximize_conversions를 포함하는 필드 마스크를 생성합니다. 하지만 Google Ads API는 실수로 필드를 지우는 것을 방지하기 위해 이 동작을 허용하지 않으며 FieldMaskError.FIELD_HAS_SUBFIELDS 오류를 생성합니다.

// Creates a campaign with the proper resource name and an empty
// MaximizeConversions field.
$campaign = new Campaign([
    'resource_name' => ResourceNames::forCampaign($customerId, $campaignId),
    'maximize_conversions' => new MaximizeConversions()
]);

// Constructs an operation, using the FieldMasks' allSetFieldsOf utility to
// derive the update mask. The field mask includes 'maximize_conversions',
// which produces a FieldMaskError.FIELD_HAS_SUBFIELDS error.
$campaignOperation = new CampaignOperation();
$campaignOperation->setUpdate($campaign);
$campaignOperation->setUpdateMask(FieldMasks::allSetFieldsOf($campaign));

// Sends the operation in a mutate request that results in a
// FieldMaskError.FIELD_HAS_SUBFIELDS error because empty MESSAGE fields cannot
// be included in a field mask.
$campaignServiceClient = $googleAdsClient->getCampaignServiceClient();
$response = $campaignServiceClient->mutateCampaigns(
    MutateCampaignsRequest::build($customerId, [$campaignOperation])
);

다음 코드는 하위 필드를 설정하지 않고 MaximizeConversions 입찰 전략을 사용하도록 캠페인을 올바르게 업데이트하는 방법을 보여줍니다.

// Creates a Campaign object with the proper resource name.
$campaign = new Campaign([
    'resource_name' => ResourceNames::forCampaign($customerId, $campaignId)
]);

// 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 without any of its subfields set.
$fieldMask = FieldMasks::allSetFieldsOf($campaign);
// 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.
//
// Learn more about standard and portfolio bidding strategies:
// https://developers.google.com/google-ads/api/docs/campaigns/bidding/assign-strategies
$fieldMask->getPaths()[] = 'maximize_conversions.target_cpa_micros';

// Creates an operation to update the campaign with the specified fields.
$campaignOperation = new CampaignOperation();
$campaignOperation->setUpdate($campaign);
$campaignOperation->setUpdateMask($fieldMask);

필드 지우기

일부 필드는 명시적으로 삭제할 수 있습니다. 이전 예시와 마찬가지로 FieldMasks는 기본값 (예: 0, false, "")으로 설정된 Proto3 스칼라 필드를 무시하므로 이러한 필드를 필드 마스크에 명시적으로 추가해야 합니다. 예를 들어 MaximizeConversions 입찰 전략을 사용하는 캠페인이 있고 target_cpa_micros 필드가 0보다 큰 값으로 설정되어 있다고 가정해 보겠습니다.

다음 코드가 실행되지만 maximize_conversions.target_cpa_micros가 필드 마스크에 추가되지 않으므로 target_cpa_micros 필드가 변경되지 않습니다.

// Creates a campaign with the proper resource name and a MaximizeConversions
// object with target_cpa_micros set to 0.
$campaign = new Campaign([
    'resource_name' => ResourceNames::forCampaign($customerId, $campaignId),
    'maximize_conversions' => new MaximizeConversions([
        'target_cpa_micros' => 0
    ]),
    'status' => CampaignStatusEnum\CampaignStatus::PAUSED
]);

// Constructs an operation, using the FieldMasks' allSetFieldsOf utility to
// derive the update mask. However, the field mask does NOT include
// 'maximize_conversions.target_cpa_micros'.
$campaignOperation = new CampaignOperation();
$campaignOperation->setUpdate($campaign);
$campaignOperation->setUpdateMask(FieldMasks::allSetFieldsOf($campaign));

// Sends the operation in a mutate request that succeeds, but does NOT update
// the 'target_cpa_micros' field because
// 'maximize_conversions.target_cpa_micros' was not included in the field mask.
$campaignServiceClient = $googleAdsClient->getCampaignServiceClient();
$response = $campaignServiceClient->mutateCampaigns(
    MutateCampaignsRequest::build($customerId, [$campaignOperation])
);

다음 코드는 MaximizeConversions 입찰 전략에서 target_cpa_micros 필드를 올바르게 지우는 방법을 보여줍니다.

// Creates a Campaign object with the proper resource name.
$campaign = new Campaign([
    'resource_name' => ResourceNames::forCampaign($customerId, $campaignId)
]);

// Constructs a field mask from the existing campaign and adds the
// 'maximize_conversions.target_cpa_micros' field to the field mask, which
// clears this field from the bidding strategy without impacting any other
// fields on the bidding strategy.
$fieldMask = FieldMasks::allSetFieldsOf($campaign);
$fieldMask->getPaths()[] = 'maximize_conversions.target_cpa_micros';

// Creates an operation to update the campaign with the specified field.
$campaignOperation = new CampaignOperation();
$campaignOperation->setUpdate($campaign);
$campaignOperation->setUpdateMask($fieldMask);

기본값을 설정하면 Google Ads API 프로토콜 버퍼에서 optional로 정의된 필드에 대해 의도한 대로 작동합니다. 하지만 target_cpa_micros는 optional 필드가 아니므로 필드 마스크에 경로를 명시적으로 추가하지 않고 0로 설정하면 입찰 전략이 업데이트되어 target_cpa_micros가 삭제되지 않습니다.