מסכות שדה

ב-Google Ads API, העדכונים מתבצעים באמצעות מסכת שדה. באנונימיזציה של השדות מפורטים כל השדות שאתם מתכוונים לשנות באמצעות העדכון, וכל שדה שצוין ולא נכלל באנונימיזציה של השדות יטופל כנתון לא רלוונטי, גם אם הוא נשלח לשרת. אפשר ליצור מסכת שדה באופן ידני על ידי יצירת Google\Protobuf\FieldMask, יצירת מערך שמאוכלס בשמות של כל השדות שאתם רוצים לשנות, ואז הקצאה של המערך לשדה הנתיב של מסכת השדה.

אפשר גם להשתמש בכלי המובנה שלנו למסכת שדות (FieldMasks), שמסתיר הרבה מהפרטים הספציפיים ומאפשר ליצור מסכות שדות באופן אוטומטי על ידי מעקב אחר השינויים שאתם מבצעים בשדות של הישות.

דוגמה לעדכון קמפיין:

    $campaign = new Campaign([
        'resource_name' => ResourceNames::forCampaign($customerId, $campaignId),
        'status' => CampaignStatus::PAUSED
    ]);

    $campaignOperation = new CampaignOperation();
    $campaignOperation->setUpdate($campaign);
    $campaignOperation->setUpdateMask(FieldMasks::allSetFieldsOf($campaign));

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

לאחר מכן הקוד יוצר אובייקט CampaignOperation ומגדיר בו את הקמפיין שנוצר קודם. לאחר מכן, המערכת משתמשת ב-FieldMasks::allSetFieldsOf() כדי ליצור מסכת שדות לקמפיין באמצעות כל השדות שהשתנו. לבסוף, הוא מעביר את המסכה שהוחזרה לאובייקט הפעולה של הקמפיין.

הערה: FieldMasks::allSetFieldsOf היא שיטה נוחה ל-FieldMasks::compare(). הפונקציה משווה את האובייקט שהוענק לה לאובייקט ריק מאותו סוג. לדוגמה, בקוד הקודם אפשר היה להשתמש ב-FieldMasks::compare(new Campaign(), $campaign) במקום ב-allSetFieldsOf().

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

לשדות MESSAGE יכולים להיות שדות משנה (למשל, MaximizeConversions שיש לו שלושה: target_cpa_micros,‏ cpc_bid_ceiling_micros ו-cpc_bid_floor_micros), או שאין להם שדות משנה בכלל (למשל, ManualCpm).

שדות של הודעות ללא שדות משנה מוגדרים

כשמעדכנים שדה MESSAGE שלא מוגדר עם שדות משנה, משתמשים ב-FieldMasks כדי ליצור מסכת שדה, כפי שמתואר למעלה.

שדות של הודעות עם שדות משנה מוגדרים

כשמעדכנים שדה MESSAGE שמוגדר עם שדות משנה בלי להגדיר באופן מפורש אף אחד משדות המשנה בהודעה, צריך להוסיף ידנית את כל שדות המשנה הניתנים לשינוי של MESSAGE אל FieldMask, בדומה לדוגמה הקודמת שבה נוצרה מסכת שדה מאפס.

דוגמה נפוצה לכך היא עדכון שיטת הבידינג של קמפיין בלי להגדיר אף אחד מהשדות בשיטת הבידינג החדשה. הקוד הבא מראה איך מעדכנים קמפיין כך שישתמש בשיטת הבידינג 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 = new Campaign([
    'resource_name' => ResourceNames::forCampaign($customerId, $campaignId),
    'maximize_conversions' => new MaximizeConversions()
]);

// Constructs an operation, using the FieldMasks' allSetFieldsOf utility to
// derive the update mask. The field mask will include 'maximize_conversions`,
// which will produce a FieldMaskError.FIELD_HAS_SUBFIELDS error.
$campaignOperation = new CampaignOperation();
$campaignOperation->setUpdate($campaign);
$campaignOperation->setUpdateMask(FieldMasks::allSetFieldsOf($campaign));

// 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.
$campaignServiceClient = $googleAdsClient->getCampaignServiceClient();
$response = $campaignServiceClient->mutateCampaigns($customerId, [$campaignOperation]);

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

// Creates a Campaign object with the proper resource name.
$campaign = new Campaign([
    'resource_name' => ResourceNames::forCampaign($customerId, $campaignId)
]);

// Creates a field mask from the existing campaign and adds all of the mutable
// fields (only one in this case) on the MaximizeConversions bidding strategy to
// the field mask. Because this field is included in the field mask but
// excluded from the campaign object, the Google Ads API will set the campaign's
// bidding strategy to a MaximizeConversions object without any of its subfields
// set.
fieldMask = FieldMasks::allSetFieldsOf($campaign);
// Only include 'maximize_conversions.target_cpa_micros' in the field mask
// as it is the only mutable subfield on MaximizeConversions when used as a
// standard bidding strategy.
//
// Learn more about standard and portfolio bidding strategies here:
// https://developers.google.com/google-ads/api/docs/campaigns/bidding/assign-strategies
$fieldMask->setPaths(array_merge(
    iterator_to_array($fieldMask->getPaths()->getIterator()),
    ['maximize_conversions.target_cpa_micros']
));

// Creates an operation to update the campaign with the specified fields.
$campaignOperation = new CampaignOperation();
$campaignOperation->setUpdate($campaign);
$campaignOperation->setUpdateMask($fieldMask);

ניקוי שדות

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

הקוד הבא פועל, אבל השדה maximize_conversions.target_cpa_micros לא יתווסף למסיכת השדה, ולכן לא יבוצעו שינויים בשדה target_cpa_micros:

// Creates a campaign with the proper resource name and a MaximizeConversions
// object with target_cpa_micros set to 0.
$campaign = new Campaign([
    'resource_name' => ResourceNames::forCampaign($customerId, $campaignId),
    'maximize_conversions' => new MaximizeConversions(['target_cpa' => 0]),
    'status' => CampaignStatus::PAUSED
]);

// Constructs an operation, using the FieldMasks' allSetFieldsOf utility to
// derive the update mask. However, the field mask will NOT include
// 'maximize_conversions.target_cpa_micros'.
$campaignOperation = new CampaignOperation();
$campaignOperation->setUpdate($campaign);
$campaignOperation->setUpdateMask(FieldMasks::allSetFieldsOf($campaign));

// Sends the operation in a mutate request that will succeed but will NOT update
// the 'target_cpa_micros' field because
// 'maximize_conversions.target_cpa_micros' was not included in the field mask.
$campaignServiceClient = $googleAdsClient->getCampaignServiceClient();
$response = $campaignServiceClient->mutateCampaigns($customerId, [$campaignOperation]);

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

// Creates a Campaign object with the proper resource name.
$campaign = new Campaign([
    'resource_name' => ResourceNames::forCampaign($customerId, $campaignId)
]);

// Constructs a field mask from the existing campaign and adds the
// 'maximize_conversions.target_cpa_micros' field to the field mask, which will
// clear this field from the bidding strategy without impacting any other fields
// on the bidding strategy.
$fieldMask = FieldMasks::allSetFieldsOf($campaign);
$fieldMask->setPaths(array_merge(
    iterator_to_array($fieldMask->getPaths()->getIterator()),
    ['maximize_conversions.target_cpa_micros']
));

// Creates an operation to update the campaign with the specified field.
$campaignOperation = new CampaignOperation();
$campaignOperation->setUpdate($campaign);
$campaignOperation->setUpdateMask($fieldMask);

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