W interfejsie Google Ads API aktualizacje są przeprowadzane przy użyciu maski pola. Maska pola zawiera listę wszystkich pól, które chcesz zmienić w ramach aktualizacji. Wszystkie określone pola, których nie ma w masce pola, są ignorowane, nawet jeśli zostaną wysłane na serwer.
FieldMaskUtil
Zalecany sposób generowania masek pól to 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 jednostki.
Poniższy przykład pokazuje, jak wygenerować maskę pola do aktualizowania 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.
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 tworzy maskę pola, która zawiera listę zmienionych pól. Możesz podać tę maskę pola w operacji podczas tworzenia jej 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 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.
Możesz też przekazać istniejącą instancję Campaign zamiast ciągu znaków z nazwą zasobu, 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żywania narzędzi biblioteki, 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 pól podrzędnych
Pola MESSAGE 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 podpól
Podczas aktualizowania pola MESSAGE, które nie jest zdefiniowane za pomocą żadnych pól podrzędnych, użyj FieldMaskUtil, aby wygenerować maskę pola, jak pokazano wcześniej.
Pola wiadomości ze zdefiniowanymi podpola
Podczas aktualizowania pola MESSAGE zdefiniowanego za pomocą pól podrzędnych bez wyraźnego ustawiania żadnego z tych pól w wiadomości musisz ręcznie dodać każde z zmiennych pól podrzędnych MESSAGE do pola FieldMask, podobnie jak w poprzednim przykładzie, w którym maska pola została utworzona od zera.
Jednym z częstych przykładów jest aktualizacja strategii ustalania stawek w kampanii bez ustawiania żadnych pól w nowej strategii ustalania stawek. W poniższym przykładzie pokazujemy, 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 osiąga 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 czyszczeniu pól. W takim przypadku 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 jawnie 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 nieobowiązkowego pola skalarnego na wartość domyślną (0) jest nieodróżnialne od pozostawienia go bez ustawienia w nowej instancji wiadomości. W rezultacie usługa FieldMaskUtil dodaje do maski pola wartość 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 przeznaczeniem 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.