המדריך למפתחים של 'אותות אפליקציות מוגנים'

כדי לעזור למפתחים להתחיל להתנסות ב-Protected App Signals API, במסמך הזה מתוארים כל ממשקי ה-API בפלטפורמת ה-API, כולל פירוט להגדיר סביבת בדיקה ותספק דוגמאות לתצורה סקריפטים.

היסטוריית גרסאות

ינואר 2024

גרסה ראשונה של המדריך למפתחים שתומך בגרסת MVP של PAS

מרץ 2024

שינויים ב-API שיתמוך בגרסת M-2024-05 של Android API, מהדורת אפריל 2024 של הרכיבים בצד השרת. השינויים הבולטים ביותר:

  • נוספו פרטים על ההרשאות שנדרשות ל-API במכשיר
  • נוספו פרטים לגבי ניהול המכסה של אותות במכשיר
  • חתימת generateBid עודכנה עם שינויים שקשורים להקשר תמיכה באחזור מודעות ובתעבורת נתונים יוצאת (egress)
  • עודכנו מסמכי reportWin, כולל תמיכה בתעבורת נתונים יוצאת (egress)
  • מעדכנים את התיעוד של Ad Retrieval API כדי להסיר את התמיכה באחזור מודעות מסוג BYOS. ותיעוד ה-UDF לאחזור מודעות.

סקירה כללית על ממשקי API

הפלטפורמה של Protected Signals API כוללת קבוצות משנה שונות של API מערכות:

  • ממשקי API של Android:
    • Signal Curation API, מורכב מ:
    • עדכון ה-API של האותות
    • API לקידוד אותות
    • Protected Auction Support API: לשימוש של ערכות SDK כדי להריץ מכרז בשרתי הבידינג והמכרזים באמצעות אפליקציה מוגנת אותות.
  • ממשקי API בצד השרת:
    • Protected Auction API: סדרת סקריפטים של JS שפועלים ב-Bidding and שרתי מכרזים. ה-API הזה מאפשר למוכרים ולקונים לכתוב את הלוגיקה להטמיע את המכרז המוגן.
    • ממשק API לאחזור מודעות: אחראי לספק רשימת מודעות של מועמדים בבחירות המידע ההקשרי ופרטי המשתמש שזמינים לבידינג של הקונה השרת.

לקוח Android

בצד הלקוח, הפלטפורמה 'אותות של אפליקציות מוגנים' כוללת שלושה ממשקי API שונים:

  • אותות עדכון: Android System API להפעלת איסוף האותות במכשיר.
  • קידוד אותות: ממשק API ב-JavaScript להכנת האותות לשליחה במהלך המכרז.
  • תמיכה במכרז מוגנת: ממשק API לתמיכה בביצוע של Protected מכרז עם שרתי בידינג ומכרזים. ה-API הזה לא ספציפי ל אותות מוגנים של אפליקציות ומשמשים גם לתמיכה במכרזים של הגנה Audience API.

עדכון ה-API של האותות

ה-Update Signals API מספק לטכנולוגיות פרסום אפשרות לרשום משתמשים אותות שקשורים לאפליקציה מטעם הקונה. ה-API פועל לפי מודל הענקת גישה. מבצע הקריאה החוזרת מספק URI שממנו ה-framework מאחזרת את ואת הלוגיקה לקידוד האותות האלה לשימוש במכרז.

ה-API דורש את השדה android.permission.ACCESS_ADSERVICES_PROTECTED_SIGNALS הרשאה.

ה-API updateSignals() יאחזר אובייקט JSON מה-URI שמתאר אילו אותות להוסיף או להסיר, ואיך להכין אותות כאלה במכרז.

Executor executor = Executors.newCachedThreadPool();
ProtectedSignalsManager protectedSignalsManager
     =  ProtectedSignalsManager.get(context);

// Initialize a UpdateSignalsRequest
UpdateSignalsRequest updateSignalsRequest = new
  UpdateSignalsRequest.Builder(Uri.parse("https://example-adtech1.com/signals"))
      .build();

OutcomeReceiver<Object, Exception> outcomeReceiver = new OutcomeReceiver<Object, Exception>() {
  @Override
  public void onResult(Object o) {
    //Post-success actions
  }

  @Override
  public void onError(Exception error) {
    //Post-failure actions
  };

// Call updateSignals
protectedSignalsManager.updateSignals(updateSignalsRequest,
    executor,
    outcomeReceiver);

הפלטפורמה שולחת בקשת https ל-URI שצוין בבקשת האחזור האות מתעדכן. יחד עם עדכוני האות, התשובה יכולה לכלול נקודת הקצה (endpoint) שמארחת את לוגיקת הקידוד להמרת האותות הגולמיים מטען ייעודי (payload) מקודד. עדכוני האות צפויים להיות בפורמט JSON יכולים להיות להם המפתחות הבאים:

המפתחות ברמה העליונה של אובייקט ה-JSON חייבים להתאים לאחת מחמש פקודות:

מפתח

תיאור

put

הוספת אות חדש והחלפה של כל האותות הקיימים באותו מפתח. הערך

באובייקט JSON שבו המפתחות הם מחרוזות בסיס 64 שתואמות למפתח שעבורו יש להזין, והערכים הם מחרוזת של בסיס 64 שתואם לערך שרוצים להציב.

append

מצרף אות/אות חדשים לרצף זמן של אותות, ומסיר את האותות הישנים ביותר

כדי לפנות מקום לסדרות החדשות אם גודל הסדרות חורג מהמקסימום הנתון. הערך של האובייקט הזה הוא אובייקט JSON שבו המפתחות הם מחרוזות בסיס 64 שתואמות למפתח שאליו רוצים לצרף, והערכים הם אובייקטים עם שני שדות: 'ערכים' ו-maxSignals.

'values': רשימה של מחרוזות בסיס 64 שמתאימות לאותות לערכים שיצורפו לסדרות הזמנים.

"maxSignals": מספר הערכים המקסימלי שמותר להזין בסדרת הזמנים הזו. אם

מספר האותות הנוכחי שמשויך למפתח חורג מ-maxSignals. האותות הישנים ביותר יוסרו. לתשומת ליבכם: אפשר לצרף למפתח שנוסף על ידי 'איפה'. חשוב לזכור שאם תוסיפו יותר ממספר הערכים המקסימלי המותר, המערכת תכשל.

put_if_not_present

הוספת אות חדש רק אם אין אותות קיימים עם אותו מפתח. הערך של האובייקט הזה הוא אובייקט JSON שבו המפתחות הם מחרוזות בסיס 64 שתואמות למפתח שעבורו יש להזין, והערכים הם מחרוזת של בסיס 64 שתואם לערך שרוצים להציב.

remove

הסרת האות של מפתח. הערך הזה הוא רשימה של מחרוזות בסיס 64 שתואמות למפתחות של האותות שצריך למחוק.

update_encoder

כאן מוצגת פעולה לעדכון נקודת הקצה ו-URI שאפשר להשתמש בו

כדי לאחזר לוגיקת קידוד. מפתח המשנה לציון פעולת עדכון הוא 'פעולה' את הרצף

הערכים הנתמכים בשלב זה הם רק REGISTER [הרשמה]. לתעד את נקודת הקצה (endpoint) של המקודד אם היא סופקה בפעם הראשונה, או להחליף את נקודת הקצה הקיימת בנקודת הקצה החדשה שסופקה. חובה לציין את נקודת הקצה עבור REGISTER action.מפתח המשנה לציון נקודת הקצה של המקודד הוא 'נקודת קצה' והערך הוא ה-URI

של נקודת הקצה.

בקשת JSON לדוגמה תיראה כך:

{
    "put": {
        "AAAAAQ==": "AAAAZQ==",
        "AAAAAg==": "AAAAZg=="
    },
    "append": {
        "AAAAAw==": {
            "values": [
                "AAAAZw=="
            ],
            "max_signals": 3
        }
    },
    "put_if_not_present": {
        "AAAABA==": "AAAAaQ==",
        "AAAABQ==": "AAAAag=="
    },
    "update_encoder": {
        "action": "REGISTER",
        "endpoint": "https://adtech1.com/Protected App Signals_encode_script.js"
    }
}

מכסת האותות במכשיר תהיה 10 עד 15Kb. אחרי המכסה חריגה מ-PPAPI יחריג אותות באמצעות אסטרטגיית FIFO. תהליך הפינוי תאפשר חריגה קלה מהמיכסה למשך מרווחי זמן קצרים כדי להפחית את תדירות הפינוי.

API לקידוד אותות

הקונים נדרשים לספק פונקציית Java Script כדי להשתמש בה לקידוד לגבי אותות שמאוחסנים במכשיר ולשלוח לשרת במהלך ההגנה מכרז. הקונים יכולים לספק את הסקריפט הזה על ידי הוספת כתובת ה-URL שבה הוא יכול להופיע אוחזרו באמצעות המפתח "update_encoder" בכל אחת מהתגובות בקשת UpdateSignal API. הסקריפט יכלול את החתימה הבאה:

function encodeSignals(signals, maxSize) {
  let result = new Uint8Array(maxSize);
  // first entry will contain the total size
  let size = 1;
  let keys = 0;
  
  for (const [key, values] of signals.entries()) {
    keys++;
    // In this encoding we only care about the first byte
    console.log("key " + keys + " is " + key)
    result[size++] = key[0];
    result[size++] = values.length;
    for(const value of values) {
      result[size++] = value.signal_value[0];
    }
  }
  result[0] = keys;
  
  return { 'status': 0, 'results': result.subarray(0, size)};
}

הפרמטר signals הוא מפה ממפתחות בצורת UInt8Arrays בגודל 4 לרשימות של אובייקטים מוגנים של App Signals. לכל אובייקט של אותות אפליקציות מוגנים יש בשלושה שדות:

  • signal_value: UInt8Array שמייצג את ערך האות.
  • creation_time: מספר שמייצג את זמן היצירה של האותות פרקי זמן של שניות (epoch).
  • package_name: מחרוזת שמייצגת את שם החבילה שנוצרה את האות.

הפרמטר maxSize הוא מספר שמתאר את גודל המערך הגדול ביותר המותר לפלט.

הפונקציה צריכה להפיק אובייקט עם שני שדות:

  • status: צריך להיות 0 אם הסקריפט פעל בהצלחה.
  • results: צריך להיות UInt8Array באורך שקטן מ-maxSize או שווה לו. המערך הזה יישלח לשרת במהלך המכרזים, ויוכן על ידי סקריפט prepareDataForAdRetrieval.

הקידוד מספק לטכנולוגיות פרסום שלב ראשוני של הנדסת פיצ'רים (feature engineering), שבה אפשר לבצע טרנספורמציות כמו דחיסת אותות גולמיים משורשרים לפי לוגיקה מותאמת אישית משלהן. שימו לב שבמהלך מכרז מוגן שמופעל בסביבות ביצוע מהימנות (TEE), פרסום דיגיטלי ללוגיקה בהתאמה אישית תהיה גישת קריאה למטענים הייעודיים (payloads) של האותות שנוצרו על ידי באמצעות הקידוד. הלוגיקה המותאמת אישית, פונקציה בהגדרת המשתמש (UDF), שפועלת ב-B&A TEE של הקונה תהיה לו גישת קריאה לאותות המקודדים ולאותות הקשריים אחרים שסופקו על ידי האפליקציה של בעל התוכן הדיגיטלי כדי לבצע בחירת מודעות (אחזור מודעות בידינג).

קידוד אותות

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

adb shell cmd jobscheduler run -f com.google.android.adservices.api 29
ניהול גרסאות לוגיות של המקודד

כשנשלחת בקשה להוריד את הלוגיקה של המקודד המותאם אישית של הפרסום הדיגיטלי, את טכנולוגיית הפרסום נקודת הקצה יכולה להגיב עם מספר גרסה בכותרות התגובה. הגרסה הזו נשמר יחד עם הלוגיקה של המקודד במכשיר. כשהאותות הגולמיים מתבצע קידוד, המטען הייעודי (payload) המקודד נשמר יחד עם הגרסה ששימשה באמצעות הקידוד. גרסה זו גם נשלחת לשרת B&A במהלך מצב מכירה פומבית, כך שטכנולוגיות המודעות יוכלו להתאים את לוגיקת הבידינג והקידוד שלהם את הגרסה.

Response header for providing encoder version : X_ENCODER_VERSION

Protected Auctionsupport API

בצד המכשיר, הפעלת מכרז עבור אותות של אפליקציות מוגנים היא זהה להפעלת מכרז לקהלים מוגנים.

שירותי בידינג ומכרזים

ממשקי ה-API בצד השרת כוללים את:

  • Protected Auction API: סדרה של פונקציות JS או UDF שהקונים והמוכרים יכולים לפרוס ברכיבי ה-B&A שבבעלותם כדי לקבוע את הלוגיקה של הבידינג ואת הלוגיקה של המכרז.
  • API לאחזור מודעות: הקונים יכולים להטמיע את ה-API הזה על ידי הטמעה של נקודת קצה (endpoint) של REST שיהיה אחראי לספק קבוצה של מודעות מועמדים למכרז אות האפליקציה מוגנת.

Protected Auction API

Protected Auctioned API מורכב מ-JS API או מ-UDF שקונים ומוכרים יכולים שבהם נעשה שימוש כדי להטמיע את הלוגיקה של המכרז והבידינג.

פונקציות UDF של טכנולוגיית מודעות של קונה
פונקציית UDF בהכנה להשקה

לפני שאפשר להשתמש באותות מוגנים של אפליקציות כדי לאחזר מועמדים להצגת מודעות מניסוי המודעות TEE שירות אחזור מודעות, הקונים צריכים לפענח ולהכין את אותות האפליקציות המוגנים. ונתונים אחרים שסופקו על ידי בית העסק. פלט UDF של הקונים prepareDataForAdRetrieval הוא מועברים לשירות אחזור מודעות אל לאחזר את K המודעות המועמדות המובילות לצורך בידינג.

// Inputs
// ------
// encodedOnDeviceSignals: A Uint8Array of bytes from the device.
// encodedOnDeviceSignalsVersion: An integer representing the encoded
//   version of the signals.
// sellerAuctionSignals: Information about auction (ad format, size) derived
//                       contextually.
// contextualSignals: Additional contextual signals that could help in
//                    generating bids.
//
// Outputs
// -------
// Returns a JSON structure to be used for retrieval.
// The structure of this object is left to the adtech.
function prepareDataForAdRetrieval(encodedOnDeviceSignals,encodedOnDeviceSignalsVersion,sellerAuctionSignals,contextualSignals) {
   return {};
}
יצירת הצעת מחיר UDF

אחרי K המודעות המועמדות המובילות, המודעות המועמדות מועברות אל הלוגיקה של הקונה בהתאמה אישית של בידינג, generateBid UDF:

// Inputs
// ------
// ads: Data string returned by the ads retrieval service. This can include Protected App Signals
//   ads and related ads metadata.
// sellerAuctionSignals: Information about the auction (ad format, size),
//                       derived contextually
// buyerSignals: Any additional contextual information provided by the buyer
// preprocessedDataForRetrieval: This is the output of this UDF.
function generateBid(ads, sellerAuctionSignals, buyerSignals,
                    preprocessedDataForRetrieval,
                    rawSignals, rawSignalsVersion) {
    return { "ad": <ad Value Object>,
             "bid": <float>,
             "render": <render URL string>,
             'adCost': <optional float ad cost>,
             "egressPayload": <limitedEgressPayload>,
             "temporaryUnlimitedEgressPayload": <temporaryUnlimitedEgressPayload>
    };
}

הפלט של הפונקציה הזו הוא הצעת מחיר יחידה למועמד למודעה, שמיוצגת כמו JSON מקביל ל- ProtectedAppSignalsAdWithBidMetadata הפונקציה יכולה גם להחזיר שני מערכים שמועברים אל reportWin כדי להפעיל אימון מודלים (לקבלת פרטים נוספים על תעבורת נתונים יוצאת (egress) ואימון מודלים (בקטע בנושא דיווח בהסבר על מודעת PAS)

פונקציית UDF של reportWin

כשהמכרז יסתיים, שירות המכרזים ייצור כתובות URL לדיווח עבור קונים ורושמים משׂואות רשת (beacons) באמצעות reportWin UDF (זהו אותו הפונקציה reportWin שמשמשת עבור 'קהלים מוגנים'). יישלח פינג למכשיר לאחר שהלקוח יציג את המודעה. החתימה של השיטה הזו כמעט זהה ל-Protected Audience API version מלבד שני פרמטרים נוספים egressPayload ו temporaryUnlimitedEgressPayload שמשמשים לאימון מודלים, מאוכלסים בתוצאות מ-generateBid.

// Inputs / Outputs
// ----------------
// See detailed documentation here.
function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
                   buyerReportingSignals,
                   egressPayload, temporaryUnlimitedEgressPayload) {
  // ...
}
פונקציות UDF של בית עסק בתחום המודעות הדיגיטליות
מדד UDF של מודעה

ה-UDF הזה משמש את המוכרים כדי לבחור אילו מודעות קיבלו מקונים יזכו במכרז.

function scoreAd(adMetadata, bid, auctionConfig,
                 trustedScoringSignals, bid_metadata) {
  // ...
  return {desirability: desirabilityScoreForThisAd,
              allowComponentAuction: true_or_false};
}
UDF של דוח התוצאה

ה-UDF הזה מאפשר למפיץ לבצע (בסופו של דבר) את רמת האירוע דיווח עם המידע לגבי המודעה הזוכה.

function reportResult(auctionConfig, reporting_metadata) {
  // ...
  registerAdBeacon({"click", clickUrl,"view", viewUrl});
  sendReportTo(reportResultUrl);
  return signalsForWinner;
}

API לאחזור מודעות

בגרסת MVP , שירות אחזור המודעות יהיה בניהול הקונה ובאירוח בשירות הבידינג ובשירות הבידינג יאחזר הצעות למודעות מהשירות הזה. החל מאפריל 2024, שרת אחזור המודעות יהיה חייב לפעול סביבת הפעלה (TEE) ותחשוף ממשק GRPC/proto. פרסום דיגיטלי חברות חייבות להגדיר את השרת הזה ולספק את כתובת ה-URL שלו כחלק מה-B&A פריסת סטאק. יישום של שירות זה שפועל בסביבת TEE ב-GitHub של ארגז החול לפרטיות תיעוד. אנחנו מניחים שזה הקוד שנעשה בו שימוש בפריסה.

החל מאפריל 2024, גרסאות של B&A תומכות במודעות נתיב לפי הקשר באחזור. במקרה כזה, שרת הבידינג יקבל רשימה של מזהי מודעות שנשלחים על ידי שרת ה-RTB במהלך החלק ההקשרי של המכרז. המזהים יישלחו אל שרת TEE KV כדי לאחזר את כל המודעות מידע קשור שייעשה בו שימוש בשלב הבידינג (לדוגמה: כתובת URL לעיבוד מודעות, מטא-נתונים והטמעות של מודעות לשימוש בחירה למעלה). הנתיב השני לא צריך לוגיקה ספציפית ולכן נתאר כאן רק איך להגדיר את המודל TEE באחזור מודעות.

ידית בקשה ל-UDF
function HandleRequest(requestMetadata, preparedDataForAdRetrieval,
                      deviceMetadata, contextualSignals) {
    return adsMetadataString;
}

כאשר:

  • requestMetadata: JSON. מטא-נתונים של שרת לפי בקשה ל-UDF. ריק כרגע.
  • preparedDataForAdRetrieval: התוכן בשדה הזה תלוי במודעה ואסטרטגיית אחזור. במקרה של אחזור מודעות לפי הקשר , הפרמטר הזה מכילה את האותות הגולמיים שמקורם במכשיר, ועוברים שירות להגשת הצעות מחיר. במקרה של אחזור מודעות ב-TEE באמצעות שרת אחזור המודעות, הפרמטר הזה יכיל את התוצאה של ה-UDF prepareDataForAdRetrieval. הערה: בשלב הזה, 'אותות של אפליקציות מוגנים' יהיו מפוענחים ולא מוצפנים.
  • deviceMetadata: אובייקט JSON שמכיל מטא-נתונים של המכשיר שהועברו על ידי שירות המודעות של בית העסק. לקבלת פרטים נוספים, יש לעיין בתיעוד של B&A.
    • X-Accept-Language: השפה של המכשיר.
    • X-User-Agent: סוכן משתמש שנעשה בו שימוש במכשיר.
    • X-BnA-Client-IP: כתובת ה-IP של המכשיר.
  • contextualSignals: מחרוזת שרירותית הגיעה מבידינג לפי הקשר שמופעל על ידי אותו DSP. ה-UDF צפוי להיות מסוגל לפענח את ולהשתמש בהם. אותות לפי הקשר עשויים להכיל כל מידע כמו למידת מכונה פרטי גרסת מודל של ההטמעה המוגנת שמועברת באמצעות אותות מוגנים של אפליקציות.

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

הגדרת המערכת לפיתוח

Android

כדי להגדיר את סביבת הפיתוח של Android, צריך לבצע את הפעולות הבאות:

  1. יצירה של אמולטור (מועדף) או מכשיר פיזי שבו פועלת התמונה של תצוגה מקדימה למפתחים 10
  2. מריצים את הפקודה הבאה:
adb shell am start -n com.google.android.adservices.api/com.android.adservices.ui.settings.activities.AdServicesSettingsMainActivity

לאחר מכן בוחרים באפשרות שמוצגת כדי להביע הסכמה למודעות שאפליקציות מציעות.

  1. מריצים את הפקודה הבאה כדי להפעיל את ממשקי ה-API הרלוונטיים. יכול להיות שיהיה צריך להריץ מחדש מדי פעם, כי הגדרת ברירת המחדל של ההשבתה תסונכרן מדי פעם.
adb shell device_config put adservices fledge_custom_audience_service_kill_switch false;  adb shell device_config put adservices fledge_select_ads_kill_switch false; adb shell device_config put adservices fledge_on_device_auction_kill_switch false; adb shell device_config put adservices fledge_auction_server_kill_switch false; adb shell "device_config put adservices disable_fledge_enrollment_check true";  adb shell device_config put adservices ppapi_app_allow_list '\*'; adb shell device_config put adservices fledge_auction_server_overall_timeout_ms 60000;
  1. להפעיל מחדש את המכשיר.
  2. שינוי מפתחות המכרז של המכשיר כדי שיפנו לשרת של מפתחות המכרז. חשוב להריץ את השלב הזה לפני שמנסים להפעיל מכרז, כדי למנוע שמירה במטמון של מפתחות שגויים.

בידינג ו שירותי מכרזים

כדי להגדיר את השרתים של B&A, צריך לעיין מסמכי הגדרה בשירות עצמי.

מסמך זה יתמקד באופן הגדרת השרתים הספציפיים של הקונה, לא נדרשים שינויים לאתרי המכירה.

דרישות מוקדמות

לפני הפריסה של סטאק שירותי B&A, טכנולוגיית הפרסום של הקונה צריכה:

  • לוודא שהם פרסו שירות משלהם לאחזור מודעות TEE (עיינו ב הקטע הרלוונטי).
  • צריך לוודא שלטכנולוגיית הפרסום יש את כל ה-UDF הנדרשים (prepareDataForAdRetrieval, generateBid, reportWin, HandleRequest) מוגדר ומתארח.

הבנה של אופן הפעולה של מכרז מוגן עם Protected Audience API גם צימר יועיל לכם, אבל זו לא חובה.

הגדרות אישיות של Terraform

כדי להשתמש באותות מוגנים של אפליקציות, טכנולוגיות הפרסום צריכות:

  • הפעלת התמיכה באותות מוגנים של אפליקציות ב-B&A.
  • צריך לספק נקודות קצה של כתובות URL שמהן ניתן לאחזר את רכיבי ה-UDF החדשים ל-prepareDataForAdRetrieval, generateBid ול-reportWin.

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

הגדרות טכנולוגיית הפרסום של הקונה

נשתמש בקובץ ההדגמה הזה כדוגמה, וקונים צריכים להגדיר את הדגלים הבאים:

  • הפעלת אותות מוגנים של אפליקציות: מופעלת לאיסוף אותות מוגנים של אפליקציות .
  • כתובות URL של אותות מוגנים של אפליקציות: מוגדרים ככתובות ה-URL של אותות האפליקציות המוגנים. שרתים.

טכנולוגיות הפרסום צריכות להחליף את כתובות ה-URL הנכונות ב-placeholders של הערכים הבאים שדות:

module "buyer" {
  # ... More config here.

  runtime_flags = {
    # ... More config here.

    ENABLE_PROTECTED_APP_SIGNALS                  = "true"
    PROTECTED_APP_SIGNALS_GENERATE_BID_TIMEOUT_MS = "60000"
    TEE_AD_RETRIEVAL_KV_SERVER_ADDR               = "<service mesh address of the instance>"
    AD_RETRIEVAL_TIMEOUT_MS                       = "60000"
    BUYER_CODE_FETCH_CONFIG                       = <<EOF
    {
        "protectedAppSignalsBiddingJsUrl": "<URL to Protected App Signals generateBid UDF>",
        "urlFetchTimeoutMs": 60001, # This has to be > 1 minute.
        "urlFetchPeriodMs": 13000000,
        "prepareDataForAdsRetrievalJsUrl": "<URL to the UDF>"
    }
    EOF

  }  # runtime_flags

}  # Module "buyer"

הגדרת טכנולוגיית פרסום של בית העסק

בתור דוגמה, המוכרים צריכים להגדיר את קובץ ההדגמה הזה סימונים הבאים. (הערה: מודגשת רק הגדרה שקשורה לאותות מוגנים של אפליקציות (Protected App Signals) כאן). טכנולוגיות הפרסום צריכות לוודא שהן מחליפות את כתובות ה-URL הנכונות placeholders:

module "seller" {
  # ... More config here.

  runtime_flags = {
    # ... More config here.

    ENABLE_PROTECTED_APP_SIGNALS                  = "true"

    SELLER_CODE_FETCH_CONFIG                           = <<EOF
  {
    "urlFetchTimeoutMs": 60001, # This has to be > 1 minute.
    "urlFetchPeriodMs": 13000000,
    "protectedAppSignalsBuyerReportWinJsUrls": {"<Buyer Domain>": "URL to reportWin UDF"}
  }
  EOF

  }  # runtime_flags

}  # Module "seller"

שירותי KV ואחזור מודעות

בהתאם לאסטרטגיות שנבחרו לתמיכה באחזור מודעות, המערכת מחייבת פריסה של מופע אחד או שניים של שירות KV. אנחנו נתייחס למכונת KV שמשמשת לאחזור מודעות מבוססת TEE בתור ה- Ad Retrieval Server ולמכונה כדי לתמוך בנתיב תלוי-הקשר אחזור כ-KV Lookup Server.

בשני המקרים, פריסת השרתים תואמת למסמכי התיעוד הזמינים ב-GitHub Server, ההבדל בין שני המקרים הוא שהחיפוש שהנרתיק פועל מחוץ לאריזה ללא צורך בהגדרות נוספות, בעוד כדי שאפשר יהיה לאחזר אחת, צריך לפרוס את ה-UDF HandleRequest לוגיקת השליפה. לפרטים נוספים אפשר לעיין בשרת KV המדריך למשתמשים חדשים. שימו לב ש-B&A מצפה ששני השירותים פרוסות באותה רשת שירות כמו שירות הבידינג.

הגדרה לדוגמה

למשל, שימו לב לתרחיש הבא: שימוש ב-Protected App Signals API, טכנולוגיית פרסום שומרת אותות רלוונטיים על סמך השימוש של המשתמשים באפליקציה. בדוגמה שלנו, האותות מאוחסנים שמייצגים רכישות מתוך האפליקציה מכמה אפליקציות. במהלך במכרז, האותות המוצפנים נאספים ומועברים למכירה פומבית מוגנת לריצה. פונקציות UDF של הקונה שפועלות באזור B&A משתמשות באותות כדי לאחזר מודעה ומחשבים הצעת מחיר.

[קונה] דוגמאות לאותות

הפונקציה מוסיפה אות עם מפתח של 0 וערך של 1.

{
  "put": {
    "AA==": "AQ=="
  },
  "update_encoder": {
    "action": "REGISTER",
    "endpoint": "https://example.com/example_script"
  }
}

הפונקציה מוסיפה אות עם מפתח של 1 וערך של 2.

{
  "put": {
    "AQ==": "Ag=="
  },
  "update_encoder": {
    "action": "REGISTER",
    "endpoint": "https://example.com/example_script"
  }
}

דוגמה לקידוד encodeSignals של [קונה]

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

function encodeSignals(signals, maxSize) {
  // if there are no signals don't write a payload
  if (signals.size === 0) {
      return {};
  }

  let result = new Uint8Array(signals.size * 2);
  let index = 0;
  
  for (const [key, values] of signals.entries()) {
    result[index++] = key[0];
    result[index++] = values[0].signal_value[0];
  }
  
  return { 'status': 0, 'results': result};
}

[Buyer] דוגמה של generateDataForAdRetrieval

/**
 * `encodedOnDeviceSignals` is a Uint8Array and would contain
 * the app signals emanating from device. For purpose of the
 * demo, in our sample example, we assume that device is sending
 * the signals with pair of bytes formatted as following:
 * "<id><In app spending>". Where id corresponds to an ad category
 * that user uses on device, and the in app spending is a measure
 * of how much money the user has spent in this app category
 * previously. In our example, id of 0 will correspond to a
 * fitness ad category and a non-zero id will correspond to
 * food app category -- though this info will be useful
 * later in the B&A pipeline.
 *
 * Returns a JSON object indicating what type of ad(s) may be
 * most relevant to the user. In a real setup ad techs might
 * want to decode the signals as part of this script.
 *
 * Note: This example script makes use of only encoded device signals
 * but adtech can take other signals into account as well to prepare
 * the data that will be useful down stream for ad retrieval and
 * bid generation. The max length of the app signals used in this
 * sample example is arbitrarily limited to 4 bytes.
 */
function prepareDataForAdRetrieval(encodedOnDeviceSignals,
                                   encodedOnDeviceSignalsVersion,
                                   sellerAuctionSignals,
                                   contextualSignals) {
  if (encodedOnDeviceSignals.length === 0 || encodedOnDeviceSignals.length > 4 ||
      encodedOnDeviceSignals.length % 2 !== 0) {
     throw "Expected encoded signals length to be an even number in (0, 4]";
  }

  var preparedDataForAdRetrieval = {};
  for (var i = 0; i < encodedOnDeviceSignals.length; i += 2) {
    preparedDataForAdRetrieval[encodedOnDeviceSignals[i]] = encodedOnDeviceSignals[i + 1];
  }
  return preparedDataForAdRetrieval;
}

[קונים] UDF לאחזור מודעות לדוגמה

בדוגמה שלנו, שרת אחזור המודעות שולח מטא-נתונים (כלומר מזהה לכל מודעה את הדוגמה הזו, אבל היא יכולה לכלול נתונים אחרים לגבי כל אחד מהם שיכולים לעזור (יצירת הצעות מחיר מאוחר יותר) לכל אחד מ-K המועמדים המובילים.

function HandleRequest(requestMetadata, protectedSignals, deviceMetadata,
                      contextualSignals) {
 return "[{\"adId\":\"0\"},{\"adId\":\"1\"}]"

דוגמה ליצירה של הצעת מחיר [קונים]

/**
 * This script receives the data returned by the ad retrieval service
 * in the `ads` argument. This argument is supposed to contain all
 * the Protected App Signals related ads and the metadata obtained from the retrieval
 * service.
 *
 * `preparedDataForAdRetrieval` argument contains the data returned
 * from the `prepareDataForAdRetrieval` UDF.
 *
 * This script is responsible for generating bids for the ads
 * collected from the retrieval service and ad techs can decide to
 * run a small inference model as part of this script in order to
 * decide the best bid given all the signals available to them.
 *
 * For the purpose of the demo, this sample script assumes
 * that ad retrieval service has sent us most relevant ads for the
 * user and this scripts decides on the ad render URL as well as
 * what value to bid for each ad based on the previously decoded
 * device signals. For simplicity sake, this script only considers
 * 2 types of app categories i.e. fitness and food.
 *
 * Note: Only one bid is returned among all the
 * input ad candidates.
 */
function generateBid(ads, sellerAuctionSignals, buyerSignals, preparedDataForAdRetrieval) {
  if (ads === null) {
    console.log("No ads obtained from the ad retrieval service")
    return {};
  }     
        
  const kFitnessAd = "0";
  const kFoodAd = "1";
  const kBuyerDomain = "https://buyer-domain.com";
        
  let resultingBid = 0;
  let resultingRender = kBuyerDomain + "/no-ad";
  for (let i = 0 ; i < ads.length; ++i) {
    let render = "";
    let bid = 0;
    switch (ads[i].adId) {
      case kFitnessAd:
        render = kBuyerDomain + "/get-fitness-app";
        bid = preparedDataForAdRetrieval[kFitnessAd];
        break;
      case kFoodAd:
        render = kBuyerDomain + "/get-fastfood-app";
        bid = preparedDataForAdRetrieval[kFoodAd];
        break;
      default:
        console.log("Unknown ad category");
        render = kBuyerDomain + "/no-ad";
        break;
    }
    console.log("Existing bid: " + resultingBid + ", incoming candidate bid: " + bid);
    if (bid > resultingBid) {
      resultingBid = bid;
      resultingRender = render;
    }
  }
  return {"render": resultingRender, "bid": resultingBid};
}

[קונים] reportWin דוגמה

ערך UDF של reportWin מדווח לקונה שהוא זכה במכרז.

function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
                                       buyerReportingSignals, directFromSellerSignals,
                                       egressPayload,
                                       temporaryUnlimitedEgressPayload) {
  sendReportTo("https://buyer-controlled-domain.com/");
  registerAdBeacon({"clickEvent":"https://buyer-controlled-domain.com/clickEvent"});
  return;
}

[בית עסק] הגדרת שרת KV

המפיצים חייבים להגדיר שרת KV של אותות כדי שיהיה מיפוי זמין מכתובות ה-URL של עיבוד המודעות לאותות ניקוד תואמים, לדוגמה: אם https:/buyer-domain.com/get-fitness-app וגם סכום של https:/buyer-domain.com/get-fastfood-app הוחזר על ידי הקונה, בית העסק יכול לפעול לפי אותות ציון לדוגמה בתגובה לשאילתות ה-SFE באמצעות GET ב-https://key-value-server-endpoint.com?client_type=1&renderUrls=<render-url-returned-by-the-buyer>:

{
   "renderUrls" : {
      "https:/buyer-domain.com/get-fitness-app" : [
         "1",
         "2"
      ],
      "https:/buyer-domain.com/get-fastfood-app" : [
         "3",
         "4"
      ]
   }
}

דוגמה לדירוג מודעה [מפיץ]

/**
 * This module generates a random desirability score for the Protected App
 * Signals ad in this example. In a production deployment,
 * however, the sellers would want to use all the available signals to generate
 * a score for the ad.
 */
function getRandomInt(max) {
  return Math.floor(Math.random() * max);
}

function scoreAd(adMetadata, bid, auctionConfig,
                                   trustedScoringSignals, deviceSignals,
                                   directFromSellerSignals) {
  return {
    "desirability": getRandomInt(10000),
    "allowComponentAuction": false
  };
}

דוגמה לתוצאה בדוח [בית עסק]

function reportResult(auctionConfig, sellerReportingSignals, directFromSellerSignals){
  let signalsForWinner = {};
    sendReportTo("https://seller-controlled-domain.com");
    registerAdBeacon({"clickEvent":
                    "https://seller-controlled-domain.com/clickEvent"});
    return signalsForWinner;
}

אפליקציה לדוגמה

דוגמה לאופן שבו אפשר להשתמש ב-API כדי ליצור אפליקציה שמשתמשת כמו שתיארנו למעלה, יצרנו אפליקציה לדוגמה של 'אותות אפליקציות מוגנים', במאגר לדוגמה הזה.