Cập nhật bằng cách sử dụng mặt nạ tại hiện trường

Trong API Google Ads, quá trình cập nhật được thực hiện bằng cách sử dụng mặt nạ trường (field mask). Mặt nạ cho trường (field mask) liệt kê tất cả các trường bạn dự định thay đổi trong quá trình cập nhật và mọi trường được chỉ định không có trong mặt nạ trường (field mask) sẽ bị bỏ qua, ngay cả khi được gửi đến máy chủ.

FieldMaskUtil

Bạn nên dùng tiện ích mặt nạ trường tích hợp sẵn của chúng tôi để tạo mặt nạ cho trường (field mask) giúp ẩn nhiều thông tin cụ thể và cho phép bạn tự động tạo mặt nạ cho trường bằng cách theo dõi những thay đổi mà bạn thực hiện đối với các trường của thực thể.

Dưới đây là cách tạo mặt nạ cho trường (field mask) để cập nhật một chiến dịch:

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

Trước tiên, mã này sẽ tạo một đối tượng Chiến dịch trống, sau đó đặt tên tài nguyên của đối tượng đó để thông báo cho API của chiến dịch đang được cập nhật.

Ví dụ này sử dụng phương thức client.field_mask.with trên chiến dịch để bắt đầu khối bao gồm nội dung cập nhật. Ở cuối khối này, tiện ích so sánh trạng thái hiện tại của chiến dịch sau khối với trạng thái ban đầu của chiến dịch trước khi bị chặn và tự động tạo một mặt nạ trường để liệt kê các trường đã thay đổi. Bạn có thể cung cấp mặt nạ trường đó cho thao tác khi tạo mặt nạ cho lệnh gọi biến đổi như sau:

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

Bạn nên sử dụng phương thức này khi thực hiện một thao tác phức tạp và muốn kiểm soát chính xác từng bước. Tuy nhiên, đối với hầu hết các trường hợp, bạn có thể sử dụng tiện ích thư viện Ruby đơn giản hơn:

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

Phương thức này tự động tạo một tài nguyên chiến dịch trống mới, tạo mặt nạ trường dựa trên những thay đổi bạn thực hiện trong khối, tạo thao tác cập nhật và trả về thao tác cuối cùng với updateupdate_mask đã điền sẵn. Bạn cũng có thể chuyển một chiến dịch sang phương thức campaign để chỉ định trạng thái bắt đầu của chiến dịch. Mẫu này phù hợp với tất cả tài nguyên hỗ trợ thao tác cập nhật.

Tạo mặt nạ theo cách thủ công

Để tạo mặt nạ trường từ đầu mà không cần sử dụng bất kỳ tiện ích thư viện nào, trước tiên, bạn cần tạo Google::Protobuf::FieldMask, sau đó điền một mảng bằng tên của tất cả các trường mà bạn định thay đổi, rồi cuối cùng chỉ định mảng đó cho trường path của mặt nạ trường.

mask = Google::Protobuf::FieldMask.new
mask.path = ["status", "name"]

Cập nhật các trường thông báo và trường phụ của các trường đó

Các trường MESSAGE có thể có các trường phụ (chẳng hạn như MaximizeConversions có ba trường: target_cpa_micros, cpc_bid_ceiling_microscpc_bid_floor_micros) hoặc hoàn toàn không có trường con nào (chẳng hạn như ManualCpm).

Các trường thông báo chưa có trường phụ xác định

Khi cập nhật trường MESSAGE không được xác định bằng bất kỳ trường phụ nào, hãy sử dụngFieldMaskUtil để tạo mặt nạ trường, như đã trình bày trước đó.

Các trường thông báo có trường phụ xác định

Khi cập nhật trường MESSAGE được xác định bằng các trường phụ mà không đặt rõ ràng bất kỳ trường con nào trên thông báo đó, bạn phải thêm từng trường con MESSAGE có thể biến đổi vào FieldMask theo cách thủ công, tương tự như ví dụ trước đó đã tạo mặt nạ trường từ đầu.

Một ví dụ phổ biến là cập nhật chiến lược đặt giá thầu của chiến dịch mà không đặt bất kỳ trường nào trên chiến lược đặt giá thầu mới. Ví dụ sau đây minh hoạ cách cập nhật một chiến dịch để sử dụng chiến lược đặt giá thầu MaximizeConversions mà không cần đặt bất kỳ trường phụ nào trong chiến lược đặt giá thầu.

Trong ví dụ này, việc sử dụng phép so sánh tích hợp của Trường mặt nạUtil không giúp bạn đạt được mục tiêu dự kiến.

Mã sau đây sẽ tạo một mặt nạ cho trường (field mask) chứa maximize_conversions. Tuy nhiên, API Google Ads không cho phép hành vi này để ngăn chặn việc vô tình xoá các trường và tạo ra lỗi 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 will result 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],
)

Mã sau đây minh hoạ cách cập nhật đúng cách một chiến dịch để sử dụng chiến lược đặt giá thầu MaximizeConversions mà không cần đặt bất kỳ trường phụ nào.

# Create the operation directly from the campaign's resource name. Don't do
# anything in the block so that the field mask is empty. You could modify other
# fields in this block, just not the message field that is intended to have a
# blank subfield. We'll add that below.
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],
)

Xoá trường

Bạn có thể xoá một số trường một cách rõ ràng. Tương tự như ví dụ trước, bạn phải thêm các trường này một cách rõ ràng vào mặt nạ trường (field mask). Ví dụ: giả sử bạn có một chiến dịch sử dụng chiến lược đặt giá thầu MaximizeConversions và trường target_cpa_micros được đặt với giá trị lớn hơn 0.

Các mã sau đây sẽ chạy; tuy nhiên, maximize_conversions.target_cpa_micros sẽ không được thêm vào mặt nạ cho trường (field mask), nên sẽ không có thay đổi nào đối với trường target_cpa_micros:

# 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 will include 'maximize_conversions',
# but not 'maximize_conversions.target_cpa_micros', so it will result 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 will fail since field mask is incorrect.
response = client.service.campaign.mutate_campaigns(
  customer_id: customer_id,
  operations: [operation],
end

Mã sau đây minh hoạ cách xoá đúng trường target_cpa_micros cho chiến lược đặt giá thầu MaximizeConversions.

# Create a campaign including the maximize conversions fields right away, since
# we're going to manually add them 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 may add a block here with
# other changes that will automatically get 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 will succeed since we specified the correct field mask.
response = client.service.campaign.mutate_campaigns(
  customer_id: customer_id,
  operations: [operation],
end

Xin lưu ý rằng mã "không chính xác" hoạt động như dự kiến cho các trường được xác định là optional trong API Google Ads protocol buffers. Tuy nhiên, vì target_cpa_micros không phải là trường optional, nên mã "không chính xác" sẽ không cập nhật chiến lược đặt giá thầu để xoá trường target_cpa.