Aktualizacje przy użyciu masek pól

W interfejsie Google Ads API aktualizacje są przeprowadzane 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 zostaną wysłane na serwer.

FieldMaskUtil

Zalecamy generowanie masek pól za pomocą wbudowanego narzędzia do tworzenia 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 do 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 następnie ustawia jego nazwę zasobu, aby poinformować interfejs API o aktualizowanej kampanii.

Ten przykład używa 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 tworzy maskę pola, która zawiera listę zmienionych pól. Możesz podać tę maskę pola w operacji podczas jej tworzenia 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. W większości przypadków możesz jednak 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 ta metoda otrzyma ciąg nazwy zasobu, automatycznie utworzy nowy zasób kampanii z resource_name wypełnionym, utworzy maskę pola na podstawie zmian wprowadzonych w bloku, utworzy operację aktualizacji i zwróci ostateczną operację z update i update_mask już wypełnionymi. Zamiast ciągu nazwy zasobu możesz też przekazać istniejącą instancję proto Campaign, aby określić stan początkowy kampanii. Ten wzorzec działa w przypadku wszystkich zasobów, które obsługują operację aktualizacji.

Ręczne tworzenie maski pola

Aby utworzyć maskę pola od zera bez użycia narzędzi biblioteki, utwórz Google::Protobuf::FieldMask, utwórz tablicę zawierającą nazwy 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 pól podrzędnych

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

Pola wiadomości bez zdefiniowanych pól podrzędnych

Podczas aktualizowania pola MESSAGE, które nie jest zdefiniowane z żadnymi polami podrzędnymi, użyj FieldMaskUtil do wygenerowania maski pola, jak opisano wcześniej.

Pola wiadomości ze zdefiniowanymi polami podrzędnymi

Podczas aktualizowania pola MESSAGE, które jest zdefiniowane z polami podrzędnymi bez wyraźnego ustawiania żadnego z tych pól w wiadomości, musisz ręcznie dodać wszystkie zmienne pola podrzędne MESSAGE do FieldMask, podobnie jak w poprzednim przykładzie, w którym utworzono maskę pola od zera.

Jednym z typowych przykładów jest aktualizowanie strategii ustalania stawek kampanii bez ustawiania żadnych pól w nowej strategii ustalania stawek. Poniższy przykład pokazuje jak zaktualizować kampanię, aby używała strategii ustalania stawek MaximizeConversions bez ustawiania żadnych pól podrzędnych w tej strategii.

W tym przykładzie użycie wbudowanego porównania FieldMaskUtil nie przynosi oczekiwanych rezultatów.

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 zwraca 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 wyraźnie 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 używa strategii ustalania stawek MaximizeConversions, a pole target_cpa_micros ma wartość większą niż 0.

W proto3 ustawienie pola skalarnego, które nie jest opcjonalne, na wartość domyślną (0) jest nieodróżnialne od pozostawienia go nieustawionego w nowej instancji wiadomości. W rezultacie FieldMaskUtil dodaje maximize_conversions do maski pola 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 jest wymagane.