ב-Google Ads API, העדכונים מתבצעים באמצעות field mask. מסכת השדות (google.protobuf.FieldMask) מכילה רשימה של נתיבי שדות ב-snake_case שרוצים לשנות בעדכון. המערכת מתעלמת מכל השדות שצוינו שלא נכללים במסכת השדות, גם אם הם נשלחים לשרת.
כלי FieldMasks
הדרך המומלצת ליצור מסכות שדות בספריית הלקוח של Java היא להשתמש במחלקה FieldMasks של כלי השירות המובנה, שמאפשרת ליצור מסכות שדות מאובייקט שעבר שינוי במקום לבנות אותן מאפס.
דוגמה לעדכון קמפיין:
// Creates a Campaign object with the proper resource name and any other
// changes.
Campaign campaign =
Campaign.newBuilder()
.setResourceName(ResourceNames.campaign(customerId, campaignId))
.setStatus(CampaignStatus.PAUSED)
.build();
// Constructs an operation that updates the campaign, using the
// FieldMasks.allSetFieldsOf utility to derive the update mask. This mask tells
// the Google Ads API which attributes of the campaign you want to change.
CampaignOperation operation =
CampaignOperation.newBuilder()
.setUpdate(campaign)
.setUpdateMask(FieldMasks.allSetFieldsOf(campaign))
.build();
// Sends the operation in a mutate request.
MutateCampaignsResponse response =
campaignServiceClient.mutateCampaigns(
customerId.toString(), Collections.singletonList(operation));
בדוגמה הזו, קודם נוצר אובייקט ריק של Campaign builder ומוגדר שם המשאב שלו, כדי שממשק ה-API יידע איזה קמפיין מתעדכן.
בדוגמה הבאה מתבצעת קריאה ל-FieldMasks.allSetFieldsOf() בקמפיין כדי ליצור באופן אוטומטי מסכת שדות שמפרטת את כל השדות שהוגדרו. אפשר להעביר את המסכה שמוחזרת ישירות לקריאת העדכון.
אם אתם צריכים לעבוד עם אובייקט קיים ולעדכן כמה שדות, משתמשים בפקודה FieldMasks.compare() באופן הבא:
// Assumes existingCampaign was retrieved from a previous API call.
// Creates a new campaign based on the existing campaign and updates the
// campaign by setting its status to paused.
Campaign campaignToUpdate =
existingCampaign.toBuilder()
.setStatus(CampaignStatus.PAUSED)
.build();
// Constructs an operation that updates the campaign, using the
// FieldMasks.compare utility to derive the update mask. This mask tells the
// Google Ads API which attributes of the campaign you want to change.
CampaignOperation operation =
CampaignOperation.newBuilder()
.setUpdate(campaignToUpdate)
.setUpdateMask(FieldMasks.compare(existingCampaign, campaignToUpdate))
.build();
// Sends the operation in a mutate request.
MutateCampaignsResponse response =
campaignServiceClient.mutateCampaigns(
customerId.toString(), Collections.singletonList(operation));
כדי ליצור מסכת שדות מאפס, יוצרים builder של FieldMask
ומוסיפים את השם snake_case של כל שדה שרוצים לשנות:
FieldMask fieldMask =
FieldMask.newBuilder()
.addPaths("status")
.addPaths("name")
.build();
עדכון של שדות הודעה ושדות משנה שלהם
בשדות MESSAGE יכולים להיות שדות משנה (כמו MaximizeConversions, שיש לו את השדות target_cpa_micros, cpc_bid_ceiling_micros ו-cpc_bid_floor_micros), או שלא יהיו שדות משנה (כמו ManualCpm).
שדות של הודעות ללא שדות משנה מוגדרים
כשמעדכנים שדה MESSAGE שלא מוגדר עם שדות משנה, צריך להשתמש בכלי FieldMasks כדי ליצור מסכת שדה, כמו שמתואר בקטע הקודם.
שדות הודעה עם שדות משנה מוגדרים
כשמעדכנים שדה MESSAGE עם שדות משנה מוגדרים בלי להגדיר באופן מפורש אף אחד משדות המשנה בהודעה הזו, צריך להוסיף ידנית כל אחד משדות המשנה הניתנים לשינוי של MESSAGE אל FieldMask, בדומה ליצירת מסכת שדות מאפס.
דוגמה נפוצה היא עדכון של שיטת הבידינג בקמפיין (שדה oneof campaign_bidding_strategy) בלי להגדיר אף אחד מהשדות בשיטת הבידינג החדשה. בדוגמה הבאה אפשר לראות איך מעדכנים קמפיין כדי להשתמש בשיטת הבידינג MaximizeConversions בלי להגדיר אף אחד משדות המשנה בשיטת הבידינג.
במקרה כזה, שימוש בשיטות allSetFieldsOf() ו-compare() של FieldMasks בלבד לא ישיג את המטרה הרצויה.
בדוגמה הבאה נוצרת מסכת שדות שכוללת את maximize_conversions. עם זאת, Google Ads API לא מאפשר נתיבי הודעות ברמה העליונה שיש להם שדות משנה במסכת עדכון (כדי למנוע ניקוי לא מכוון של שדות משנה), ומחזיר שגיאה FieldMaskError.FIELD_HAS_SUBFIELDS.
// Creates a campaign with the proper resource name and an empty
// MaximizeConversions field.
Campaign campaign =
Campaign.newBuilder()
.setResourceName(ResourceNames.campaign(customerId, campaignId))
.setMaximizeConversions(MaximizeConversions.newBuilder().build())
.build();
// Constructs an operation using FieldMasks.allSetFieldsOf to derive the update
// mask. The field mask includes 'maximize_conversions', which produces a
// FieldMaskError.FIELD_HAS_SUBFIELDS error.
CampaignOperation operation =
CampaignOperation.newBuilder()
.setUpdate(campaign)
.setUpdateMask(FieldMasks.allSetFieldsOf(campaign))
.build();
// Sends the operation in a mutate request that results in a
// FieldMaskError.FIELD_HAS_SUBFIELDS error because empty MESSAGE fields with
// subfields cannot be included directly in a field mask.
MutateCampaignsResponse response =
campaignServiceClient.mutateCampaigns(
customerId.toString(), Collections.singletonList(operation));
בדוגמה הבאה אפשר לראות איך מעדכנים קמפיין לשימוש בשיטת הבידינג MaximizeConversions בלי להגדיר אף אחד משדות המשנה שלה.
מידע נוסף על הקצאת שיטות בידינג רגילות ושיטות בידינג כוללות
// Creates a Campaign object with the proper resource name.
Campaign campaign =
Campaign.newBuilder()
.setResourceName(ResourceNames.campaign(customerId, campaignId))
.build();
// Creates a field mask from the campaign and adds the mutable subfield
// ('maximize_conversions.target_cpa_micros') on the MaximizeConversions
// bidding strategy to the field mask. Because this subfield is included in the
// field mask while excluded from the campaign object, the Google Ads API
// switches the campaign's bidding strategy oneof to MaximizeConversions with
// target_cpa_micros unset.
FieldMask fieldMask =
FieldMasks.allSetFieldsOf(campaign).toBuilder()
.addPaths("maximize_conversions.target_cpa_micros")
.build();
// Creates an operation to update the campaign with the specified fields.
CampaignOperation operation =
CampaignOperation.newBuilder()
.setUpdate(campaign)
.setUpdateMask(fieldMask)
.build();
ניקוי השדות
אפשר לנקות חלק מהשדות באופן מפורש. בדומה לדוגמה הקודמת, צריך להוסיף את השדות האלה באופן מפורש למסכת השדות, אבל להשאיר אותם לא מוגדרים באובייקט ההודעה. לדוגמה, נניח שיש לכם קמפיין שמוגדרת בו שיטת בידינג MaximizeConversions, ושדה target_cpa_micros מוגדר עם ערך שגדול מ-0.
הקוד הבא יפעל, אבל maximize_conversions.target_cpa_micros לא ינוקה כמו שרצינו:
// Creates a campaign with the proper resource name and a MaximizeConversions
// object with target_cpa_micros set to 0L.
Campaign campaign =
Campaign.newBuilder()
.setResourceName(ResourceNames.campaign(customerId, campaignId))
.setMaximizeConversions(
MaximizeConversions.newBuilder().setTargetCpaMicros(0L).build())
.setStatus(CampaignStatus.PAUSED)
.build();
// Constructs an operation using FieldMasks.allSetFieldsOf to derive the
// update mask.
CampaignOperation operation =
CampaignOperation.newBuilder()
.setUpdate(campaign)
.setUpdateMask(FieldMasks.allSetFieldsOf(campaign))
.build();
// Sends the operation in a mutate request that does not clear the field
// cleanly.
MutateCampaignsResponse response =
campaignServiceClient.mutateCampaigns(
customerId.toString(), Collections.singletonList(operation));
בדוגמה הבאה אפשר לראות איך מוחקים את השדה target_cpa_micros בשיטת הבידינג MaximizeConversions בצורה נכונה.
// Creates a Campaign object with the proper resource name.
Campaign campaign =
Campaign.newBuilder()
.setResourceName(ResourceNames.campaign(customerId, campaignId))
.build();
// Constructs a field mask from the campaign and adds the
// 'maximize_conversions.target_cpa_micros' field to the field mask, which
// clears this field from the bidding strategy without impacting any other
// fields on the bidding strategy.
FieldMask fieldMask =
FieldMasks.allSetFieldsOf(campaign).toBuilder()
.addPaths("maximize_conversions.target_cpa_micros")
.build();
// Creates an operation to update the campaign with the specified field.
CampaignOperation operation =
CampaignOperation.newBuilder()
.setUpdate(campaign)
.setUpdateMask(fieldMask)
.build();