Маски полей

В 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::compare(new Campaign(), $campaign) вместо FieldMasks::allSetFieldsOf($campaign).

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

Поля MESSAGE могут иметь вложенные поля (например, MaximizeConversions, которое включает вложенные поля target_cpa_micros, cpc_bid_ceiling_micros и cpc_bid_floor_micros), а могут не иметь их (например, ManualCpm).

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

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

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

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

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

В этом случае использование методов allSetFieldsOf() и compare() класса FieldMasks не приведет к желаемому результату.

Приведенный ниже код создает маску поля, которая включает 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 игнорирует скалярные поля Proto3, для которых заданы значения по умолчанию (например, 0, false или ""). Предположим, что у вас есть кампания, в которой используется стратегия назначения ставок 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])
);

В примере кода ниже показано, как правильно очистить поле target_cpa_micros в стратегии назначения ставок MaximizeConversions.

// 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);

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