ใน 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]
)
โปรดทราบว่าแนวทางการเปรียบเทียบอัตโนมัติทำงานตามที่ตั้งใจไว้สำหรับฟิลด์ที่กำหนด
as optional ใน Google Ads API บัฟเฟอร์โปรโตคอล เนื่องจาก
target_cpa_micros ไม่ใช่ฟิลด์ optional ใน
MaximizeConversions คุณจึงต้องเพิ่มเส้นทางไปยัง update_mask.paths อย่างชัดเจน
เพื่อล้างฟิลด์นี้