עדכונים באמצעות מסכות שדה

ב-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

הקוד יוצר תחילה אובייקט קמפיין ריק, ולאחר מכן מגדיר את שם המשאב שלו כך שיעדכן את ה-API של הקמפיין שמתעדכן.

בדוגמה זו נעשה שימוש בשיטה client.field_mask.with בקמפיין על מנת להתחיל את החסימה שכוללת את העדכונים. בסוף החסימה, כלי העזר משווה בין הסטטוס הנוכחי של הקמפיין אחרי החסימה לבין הסטטוס הראשוני של הקמפיין לפני החסימה, ויוצר באופן אוטומטי מסכת שדה שמסכמת את השדות שהשתנו. אפשר לספק את מסכת השדה הזו לפעולה כשיוצרים אותה לקריאה לשינוי באופן הבא:

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

מומלץ להשתמש בשיטה הזו כשמבצעים פעולה מורכבת ורוצים לשלוט היטב בכל שלב. עם זאת, ברוב המקרים תוכלו להשתמש בכלי הפשוט יותר של ספריית Ruby:

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

השיטה הזו יוצרת באופן אוטומטי משאב חדש של קמפיין ריק, יוצרת את מסכת השדות על סמך השינויים שמבצעים בבלוק, יוצרת את פעולת העדכון ומחזירה את הפעולה הסופית עם הנתונים של update ו-update_mask. אפשר גם להעביר קמפיין לשיטה campaign כדי לציין גם את מצב ההתחלה של הקמפיין. התבנית הזו מתאימה לכל המשאבים שתומכים בפעולת העדכון.

יצירת מסכה באופן ידני

כדי ליצור מסכת שדות מאפס, בלי להשתמש בכלי עזר של ספרייה, קודם צריך ליצור Google::Protobuf::FieldMask, ליצור מערך שאוכלס עם השמות של כל השדות שאתם מתכוונים לשנות ולבסוף להקצות את המערך לשדה path של מסכת השדות.

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

עדכון של השדות של ההודעות ושדות המשנה שלהם

שדות MESSAGE יכולים לכלול שדות משנה (כמו MaximizeConversions שכוללים שלושה: 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 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],
)

הקוד הבא מראה איך לעדכן בצורה נכונה את הקמפיין כך שישתמש בשיטת הבידינג MaximizeConversions בלי להגדיר אף אחד משדות המשנה שלו.

# 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],
)

ניקוי השדות

אפשר למחוק באופן מפורש חלק מהשדות. בדומה לדוגמה הקודמת, צריך להוסיף את השדות האלה באופן מפורש לאנונימיזציה של השדות. לדוגמה, נניח שיש לכם קמפיין עם שיטת בידינג MaximizeConversions, ושהשדה target_cpa_micros מוגדר עם ערך שגדול מ-0.

הקוד הבא פועל. עם זאת, maximize_conversions.target_cpa_micros לא יתווסף למסכת השדות ולכן לא יבוצעו שינויים בשדה 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

הקוד הבא מראה איך לנקות בצורה נכונה את השדה target_cpa_micros בשיטת הבידינג 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

שימו לב שהקוד "שגוי" פועל כמו שצריך בשדות שמוגדרים כ-optional ב-Google Ads API protocol buffers. אבל מכיוון שהשדה target_cpa_micros הוא לא השדה optional, הקוד "שגוי" לא מעדכן את שיטת הבידינג ומסיר את השדה target_cpa.