Aktualizacje przy użyciu masek pól

W interfejsie Google Ads API aktualizacje są wykonywane za pomocą maski pola. Maska pola zawiera listę wszystkich pól, które chcesz zmienić w ramach aktualizacji. Wszystkie określone pola, które nie znajdują się w masce pola, są ignorowane, nawet jeśli zostały wysłane na serwer.

FieldMaskUtil

Zalecanym sposobem generowania masek pól jest użycie wbudowanego narzędzia do masek pól, które ukrywa określone szczegóły i umożliwia automatyczne generowanie masek pól przez monitorowanie zmian wprowadzanych w polach encji.

Poniższy przykład pokazuje, jak wygenerować maskę pola na potrzeby aktualizacji kampanii:

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

Kod najpierw tworzy pusty obiekt Campaign, a potem ustawia jego nazwę zasobu, aby poinformować interfejs API o aktualizowanej kampanii.

W tym przykładzie używamy metody client.field_mask.with w kampanii, aby rozpocząć blok obejmujący aktualizacje. Na końcu tego bloku narzędzie porównuje bieżący stan kampanii po bloku z początkowym stanem kampanii przed blokiem i automatycznie generuje maskę pola, która zawiera listę zmienionych pól. Możesz podać tę maskę pola w operacji, gdy tworzysz ją na potrzeby wywołania mutate, w ten sposób:

operation = client.operation.campaign
operation.update = campaign
operation.update_mask = mask

Ta metoda jest zalecana, gdy tworzysz złożoną operację i chcesz mieć szczegółową kontrolę nad każdym krokiem. Jednak w większości przypadków możesz przekazać nazwę zasobu (lub istniejącą instancję zasobu) do metody fabrycznej biblioteki Ruby:

campaign_resource_name = client.path.campaign(customer_id, campaign_id)

operation =
  client.operation.update_resource.campaign(campaign_resource_name) do |c|
    c.status = :PAUSED
    c.network_settings = client.resource.network_settings do |ns|
      ns.target_search_network = false
    end
  end

Gdy podasz ciąg znaków z nazwą zasobu, ta metoda automatycznie utworzy nowy zasób kampanii z wypełnionym polem resource_name, utworzy maskę pola na podstawie zmian wprowadzonych w bloku, utworzy operację aktualizacji i zwróci ostateczną operację z wypełnionymi polami update i update_mask. Zamiast ciągu znaków z nazwą zasobu możesz też przekazać istniejącą instancję proto Campaign, aby określić stan początkowy kampanii. Ten wzorzec działa we wszystkich zasobach, które obsługują operację aktualizacji.

Ręczne tworzenie maski pola

Aby utworzyć maskę pola od podstaw bez użycia narzędzi bibliotecznych, utwórz obiekt Google::Protobuf::FieldMask, utwórz tablicę wypełnioną nazwami wszystkich pól, które chcesz zmienić, i przypisz tablicę do pola paths maski pola:

mask = Google::Protobuf::FieldMask.new
mask.paths = ['status', 'name']

Aktualizowanie pól wiadomości i ich podpól

MESSAGE Pola mogą mieć podpola (np. MaximizeConversions, które ma 3 podpola: target_cpa_micros, cpc_bid_ceiling_micros i cpc_bid_floor_micros) lub nie mieć ich wcale (np. ManualCpm).

Pola wiadomości bez zdefiniowanych podpól

Podczas aktualizowania pola MESSAGE, które nie jest zdefiniowane z żadnymi polami podrzędnymi, użyj FieldMaskUtil, aby wygenerować maskę pola, jak pokazano wcześniej.

Pola wiadomości ze zdefiniowanymi podpólami

Podczas aktualizowania pola MESSAGE, które jest zdefiniowane z polami podrzędnymi, bez wyraźnego ustawiania żadnego z pól podrzędnych w tej wiadomości, musisz ręcznie dodać każde z modyfikowalnych pól podrzędnych MESSAGE do FieldMask, podobnie jak we wcześniejszym przykładzie, w którym maska pola została utworzona od podstaw.

Typowym przykładem jest aktualizacja strategii ustalania stawek w kampanii bez ustawiania żadnych pól w nowej strategii. Poniższy przykład pokazuje, jak zaktualizować kampanię, aby korzystała ze strategii ustalania stawek MaximizeConversions bez ustawiania żadnych pól podrzędnych w strategii ustalania stawek.

W tym przykładzie użycie wbudowanego porównania FieldMaskUtil nie pozwala osiągnąć zamierzonego celu.

Poniższy kod generuje maskę pola, która zawiera maximize_conversions. Interfejs Google Ads API nie zezwala jednak na takie działanie, aby zapobiec przypadkowemu wyczyszczeniu pól, i wyświetla błąd 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 results 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]
)
# Create the operation directly from the campaign's resource name. Don't do
# anything in the block so that the field mask starts empty. You can modify
# other fields in this block, except the message field intended to have a
# blank subfield.
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]
)

Wyczyść pola

Niektóre pola można wyczyścić. Podobnie jak w poprzednim przykładzie, musisz wyraźnie dodać te pola do maski pola. Załóżmy na przykład, że masz kampanię, która korzysta ze strategii ustalania stawek MaximizeConversions, a pole target_cpa_micros ma wartość większą niż 0.

W proto3 ustawienie nieopcjonalnego pola skalarnego na wartość domyślną (0) nie różni się od pozostawienia go bez ustawienia w nowej instancji wiadomości. W rezultacie FieldMaskUtil dodaje do maski pola maximize_conversions zamiast maximize_conversions.target_cpa_micros, co powoduje błąd FieldMaskError.FIELD_HAS_SUBFIELDS.

# 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 includes 'maximize_conversions',
# but not 'maximize_conversions.target_cpa_micros', so it results 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 fails because the field mask is invalid.
response = client.service.campaign.mutate_campaigns(
  customer_id: customer_id,
  operations: [operation]
)
# Create a campaign including the maximize conversions fields right away, since
# they are manually added 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 can add a block here with
# other changes that are automatically 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 succeeds because the correct field mask is specified.
response = client.service.campaign.mutate_campaigns(
  customer_id: customer_id,
  operations: [operation]
)

Pamiętaj, że automatyczne porównywanie działa zgodnie z oczekiwaniami w przypadku pól zdefiniowanych jako optional w buforach protokołu interfejsu Google Ads API. Ponieważ target_cpa_micros nie jest polem optional w MaximizeConversions, aby je wyczyścić, musisz wyraźnie dołączyć ścieżkę do update_mask.paths.