Pembaruan menggunakan mask kolom

Di Google Ads API, pembaruan dilakukan menggunakan mask kolom. Masker kolom mencantumkan semua kolom yang ingin Anda ubah dengan update, dan kolom tertentu yang tidak ada dalam masker kolom akan diabaikan, meskipun dikirim ke server.

FieldMaskUtil

Cara yang direkomendasikan untuk membuat mask kolom adalah menggunakan utilitas mask kolom bawaan, yang menyembunyikan detail tertentu dan memungkinkan Anda membuat mask kolom secara otomatis dengan memantau perubahan yang Anda buat pada kolom entity.

Contoh berikut menunjukkan cara membuat mask kolom untuk memperbarui kampanye:

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

Kode ini pertama-tama membuat objek Campaign kosong, lalu menetapkan nama resource-nya untuk memberi tahu API tentang kampanye yang sedang diperbarui.

Contoh ini menggunakan metode client.field_mask.with pada kampanye untuk memulai blok yang mencakup pembaruan. Di akhir blok ini, utilitas membandingkan status kampanye saat ini setelah blok dengan status kampanye awal sebelum blok, dan secara otomatis menghasilkan mask kolom yang mencantumkan kolom yang diubah. Anda dapat memberikan mask kolom tersebut ke operasi saat menyusunnya untuk panggilan mutasi sebagai berikut:

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

Metode ini direkomendasikan saat Anda membangun operasi yang kompleks dan menginginkan kontrol yang mendetail atas setiap langkah. Namun, dalam sebagian besar kasus, Anda dapat meneruskan nama resource (atau instance resource yang ada) ke metode factory library 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

Saat diberi string nama resource, metode ini otomatis membuat resource kampanye baru dengan resource_name terisi, membuat mask kolom berdasarkan perubahan yang Anda buat dalam blok, membuat operasi update, dan menampilkan operasi akhir dengan update dan update_mask sudah terisi. Anda juga dapat meneruskan instance proto Campaign yang ada, bukan string nama resource, untuk menentukan status awal kampanye. Pola ini berfungsi untuk semua resource yang mendukung operasi update.

Membuat mask kolom secara manual

Untuk membuat field mask dari awal tanpa menggunakan utilitas library, buat Google::Protobuf::FieldMask, buat array yang diisi dengan nama semua kolom yang ingin Anda ubah, dan tetapkan array ke kolom paths field mask:

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

Memperbarui kolom pesan dan subkolomnya

Kolom MESSAGE dapat memiliki subkolom (seperti MaximizeConversions, yang memiliki tiga subkolom: target_cpa_micros, cpc_bid_ceiling_micros, dan cpc_bid_floor_micros), atau tidak memiliki subkolom sama sekali (seperti ManualCpm).

Kolom pesan tanpa subkolom yang ditentukan

Saat memperbarui kolom MESSAGE yang tidak ditentukan dengan subkolom apa pun, gunakan FieldMaskUtil untuk membuat mask kolom, seperti yang dijelaskan sebelumnya.

Kolom pesan dengan subkolom yang ditentukan

Saat memperbarui kolom MESSAGE yang ditentukan dengan subkolom tanpa menetapkan subkolom apa pun secara eksplisit pada pesan tersebut, Anda harus menambahkan setiap subkolom MESSAGE yang dapat diubah ke FieldMask secara manual, mirip dengan contoh sebelumnya yang membuat field mask dari awal.

Salah satu contoh umum adalah memperbarui strategi bidding kampanye tanpa menetapkan kolom apa pun pada strategi bidding baru. Contoh berikut menunjukkan cara memperbarui kampanye untuk menggunakan strategi bidding MaximizeConversions tanpa menetapkan sub-bidang apa pun pada strategi bidding.

Untuk contoh ini, penggunaan perbandingan bawaan FieldMaskUtil tidak mencapai sasaran yang diinginkan.

Kode berikut menghasilkan mask kolom yang menyertakan maximize_conversions. Namun, Google Ads API tidak mengizinkan perilaku ini untuk mencegah penghapusan kolom secara tidak sengaja dan menghasilkan error 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]
)

Hapus kolom

Beberapa kolom dapat dihapus secara eksplisit. Serupa dengan contoh sebelumnya, Anda harus secara eksplisit menambahkan kolom ini ke mask kolom. Misalnya, anggaplah Anda memiliki kampanye yang menggunakan strategi bidding MaximizeConversions dan kolom target_cpa_micros ditetapkan dengan nilai yang lebih besar dari 0.

Di proto3, menetapkan kolom skalar non-opsional ke nilai defaultnya (0) tidak dapat dibedakan dengan membiarkannya tidak ditetapkan pada instance pesan baru. Akibatnya, FieldMaskUtil menambahkan maximize_conversions ke mask kolom, bukan maximize_conversions.target_cpa_micros, yang menyebabkan error 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]
)

Perhatikan bahwa pendekatan perbandingan otomatis berfungsi sebagaimana mestinya untuk kolom yang ditentukan sebagai optional dalam buffer protokol Google Ads API. Karena target_cpa_micros bukan kolom optional di MaximizeConversions, menambahkan jalur ke update_mask.paths secara eksplisit diperlukan untuk menghapusnya.