การอัปเดตโดยใช้ฟิลด์มาสก์

ใน Google Ads API การอัปเดตจะดำเนินการโดยใช้มาสก์ฟิลด์ มาสก์ของช่องจะแสดงรายการช่องทั้งหมดที่คุณต้องการเปลี่ยนแปลงด้วยการอัปเดต และระบบจะไม่สนใจช่องที่ระบุซึ่งไม่ได้อยู่ในมาสก์ของช่อง แม้ว่าจะส่งไปยังเซิร์ฟเวอร์ก็ตาม

FieldMaskUtil

วิธีที่แนะนำในการสร้างมาสก์ของช่องคือการใช้ยูทิลิตีมาสก์ของช่องในตัว ซึ่งจะซ่อนรายละเอียดที่เฉพาะเจาะจงและช่วยให้คุณสร้างมาสก์ของช่องได้โดยอัตโนมัติด้วยการตรวจสอบการเปลี่ยนแปลงที่คุณทำกับช่องของเอนทิตี

ตัวอย่างต่อไปนี้แสดงวิธีสร้างมาสก์ฟิลด์สําหรับการอัปเดตแคมเปญ

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

โค้ดจะสร้างออบเจ็กต์ Campaign เปล่าก่อน จากนั้นจึงตั้งชื่อทรัพยากรเพื่อแจ้ง API เกี่ยวกับแคมเปญที่กำลังอัปเดต

ตัวอย่างนี้ใช้เมธอด client.field_mask.with ในแคมเปญเพื่อเริ่มบล็อกที่ครอบคลุมการอัปเดต เมื่อสิ้นสุดบล็อกนี้ ยูทิลิตีจะเปรียบเทียบสถานะปัจจุบันของแคมเปญหลังบล็อกกับสถานะเริ่มต้นของแคมเปญก่อนบล็อก และสร้างมาสก์ฟิลด์ที่แจกแจงฟิลด์ที่เปลี่ยนแปลงโดยอัตโนมัติ คุณสามารถระบุมาสก์ฟิลด์นั้นให้กับการดำเนินการเมื่อสร้างมาสก์ฟิลด์สำหรับการเรียกใช้ Mutate ดังนี้

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

เราขอแนะนำให้ใช้วิธีนี้เมื่อคุณกำลังสร้างการดำเนินการที่ซับซ้อนและต้องการควบคุมทุกขั้นตอนอย่างละเอียด อย่างไรก็ตาม ในกรณีส่วนใหญ่ คุณสามารถส่งชื่อทรัพยากร (หรืออินสแตนซ์ทรัพยากรที่มีอยู่) ไปยังเมธอด Factory ของไลบรารี 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

เมื่อได้รับสตริงชื่อทรัพยากร เมธอดนี้จะสร้างทรัพยากรแคมเปญใหม่โดยอัตโนมัติพร้อมป้อนข้อมูล resource_name สร้างมาสก์ฟิลด์ตามการเปลี่ยนแปลงที่คุณทำภายในบล็อก สร้างการดำเนินการอัปเดต และแสดงผลการดำเนินการขั้นสุดท้ายพร้อมป้อนข้อมูล update และ update_mask แล้ว นอกจากนี้ คุณยังส่งอินสแตนซ์ Campaign proto ที่มีอยู่แทนสตริงชื่อทรัพยากรเพื่อระบุสถานะเริ่มต้นของแคมเปญได้ด้วย รูปแบบนี้ใช้ได้กับทรัพยากรทั้งหมดที่รองรับการดำเนินการอัปเดต

สร้างมาสก์ของช่องด้วยตนเอง

หากต้องการสร้างมาสก์ฟิลด์ตั้งแต่ต้นโดยไม่ใช้ยูทิลิตีไลบรารี ให้สร้าง Google::Protobuf::FieldMask สร้างอาร์เรย์ที่ป้อนชื่อของฟิลด์ทั้งหมดที่คุณต้องการเปลี่ยนแปลง และกำหนดอาร์เรย์ให้กับฟิลด์ paths ของมาสก์ฟิลด์ ดังนี้

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

อัปเดตช่องข้อความและช่องย่อย

ฟิลด์ MESSAGE สามารถมีฟิลด์ย่อย (เช่น MaximizeConversions ซึ่งมี 3 ฟิลด์ ได้แก่ target_cpa_micros, cpc_bid_ceiling_micros และ cpc_bid_floor_micros) หรือไม่มีเลยก็ได้ (เช่น ManualCpm)

ช่องข้อความที่ไม่มีช่องย่อยที่กำหนดไว้

เมื่ออัปเดตช่อง MESSAGE ที่ไม่ได้กำหนดด้วยช่องย่อยใดๆ ให้ใช้ FieldMaskUtil เพื่อสร้างมาสก์ของช่องตามที่แสดงไว้ก่อนหน้านี้

ช่องข้อความที่มีช่องย่อยที่กำหนดไว้

เมื่ออัปเดตช่อง MESSAGE ที่กำหนดด้วยช่องย่อยโดยไม่ได้ตั้งค่าช่องย่อยใดๆ ในข้อความนั้นอย่างชัดเจน คุณต้องเพิ่มช่องย่อย MESSAGE ที่เปลี่ยนแปลงได้แต่ละช่องลงใน FieldMask ด้วยตนเอง คล้ายกับตัวอย่างก่อนหน้านี้ที่สร้างมาสก์ช่องตั้งแต่ต้น

ตัวอย่างที่พบบ่อยคือการอัปเดตกลยุทธ์การเสนอราคาของแคมเปญโดยไม่ได้ตั้งค่าช่องใดๆ ในกลยุทธ์การเสนอราคาใหม่ ตัวอย่างต่อไปนี้แสดงวิธีอัปเดตแคมเปญเพื่อใช้กลยุทธ์การเสนอราคา MaximizeConversions โดยไม่ต้องตั้งค่าช่องย่อยใดๆ ในกลยุทธ์การเสนอราคา

สำหรับตัวอย่างนี้ การใช้การเปรียบเทียบในตัวของ FieldMaskUtil ไม่บรรลุเป้าหมายที่ต้องการ

โค้ดต่อไปนี้จะสร้างมาสก์ฟิลด์ที่มี maximize_conversions อย่างไรก็ตาม Google Ads API ไม่อนุญาตให้ดำเนินการนี้เพื่อป้องกันการล้างช่องโดยไม่ตั้งใจ และจะแสดงข้อผิดพลาด 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]
)

ล้างช่อง

คุณสามารถล้างข้อมูลบางช่องได้อย่างชัดเจน คุณต้องเพิ่มช่องเหล่านี้ลงในมาสก์ช่องอย่างชัดเจนเช่นเดียวกับตัวอย่างก่อนหน้านี้ เช่น สมมติว่าคุณมีแคมเปญที่ใช้กลยุทธ์การเสนอราคา MaximizeConversions และช่อง target_cpa_micros มีค่ามากกว่า 0

ใน proto3 การตั้งค่าช่องสเกลาร์ที่ไม่บังคับเป็นค่าเริ่มต้น (0) จะแยกไม่ออกจากการปล่อยให้ช่องดังกล่าวไม่ได้ตั้งค่าในอินสแตนซ์ข้อความใหม่ ด้วยเหตุนี้ FieldMaskUtil จึงเพิ่ม maximize_conversions ลงในมาสก์ฟิลด์แทน maximize_conversions.target_cpa_micros ซึ่งทำให้เกิดข้อผิดพลาด 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]
)

โปรดทราบว่าวิธีการเปรียบเทียบอัตโนมัติจะทำงานตามที่ต้องการสำหรับฟิลด์ที่กำหนดเป็น optional ในบัฟเฟอร์โปรโตคอลของ Google Ads API เนื่องจาก target_cpa_micros ไม่ใช่ช่อง optional ใน MaximizeConversions คุณจึงต้องเพิ่มเส้นทางไปยัง update_mask.paths อย่างชัดเจนเพื่อล้างข้อมูล