ad techproject_path: /_project.yaml book_path: /_book.yaml keywords: api:ProtectedAppSignals, docType:Guide, skill:Beginner, audienceAdBuyer, audienceAdSeller, topicAdAuction, contentTypeFundamental, category:Mobile, apiGroupAds
כדי לעזור למפתחים להתחיל להתנסות ב-Protected App Signals API, במסמך הזה מתואר כל ממשק API ב-API surface, מוסבר איך להגדיר סביבת בדיקה ומובאות דוגמאות להגדרות ולסקריפטים.
היסטוריית גרסאות
ינואר 2024
השקה ראשונה של המדריך למפתחים שתומך בהשקת ה-MVP של PAS
מרץ 2024
שינויים ב-API לתמיכה בגרסה M-2024-05 של Android API ובגרסה מאפריל 2024 של רכיבי צד השרת. השינויים הבולטים ביותר:
- הוספנו פרטים על ההרשאות שנדרשות ל-API במכשיר
- נוספו פרטים על ניהול מכסות של אותות במכשיר
- עדכון החתימה
generateBid
עם שינויים שקשורים לאחזור מודעות בהקשר ולתמיכה ביציאה - עדכון של מסמכי
reportWin
, כולל תמיכה ביציאה - עדכון התיעוד של Ad Retrieval API כדי להסיר את התמיכה באחזור מודעות BYOS ותיעוד של UDF לאחזור מודעות
סקירה כללית על ממשקי API
המשטח של Protected Signals API כולל קבוצות משנה שונות של API במערכות שונות:
- Android APIs:
- Signal Curation API, שכולל:
- Update Signals API
- Signals Encoding API
- Protected Auction Support API: ממשק API לשימוש ב-SDK כדי להריץ את המכרז המוגן בשרתי הבידינג והמכרז (B&A) באמצעות Protected App Signals.
- ממשקי API בצד השרת:
- Protected Auction API: סדרה של סקריפטים ב-JS שפועלים בשרתים של הבידינג והמכרז. ה-API הזה מאפשר למוכרים ולקונים לכתוב את הלוגיקה להטמעה של המכרז המוגן.
- Ad Retrieval API (ממשק API לאחזור מודעות): אחראי לספק רשימה של מודעות פוטנציאליות בהתאם למידע ההקשרי ולמידע על המשתמש שזמין לשרת הבידינג של הקונה.
לקוח Android
בצד הלקוח, הממשק Protected App Signals מורכב משלושה ממשקי API שונים:
- עדכון אותות: Android System API שמאפשר אוסף של אותות במכשיר.
- קידוד אותות: JavaScript API להכנת האותות לשליחה לשרת במהלך המכרז.
- תמיכה במכרזים מוגנים: API לתמיכה בהפעלת מכרז מוגן בשרתי הבידינג והמכרזים. ה-API הזה לא ספציפי ל-Protected App Signals, והוא משמש גם לתמיכה במכרזים של Protected Audience API.
Update Signals API
ה-API של עדכון אותות מספק לטכנולוגיות פרסום אפשרות לרשום אותות שקשורים למשתמש ולאפליקציה בשם הקונה. ה-API פועל לפי מודל של הקצאת הרשאות. המתקשר מספק URI שממנו המסגרת מאחזרת את האותות המתאימים ואת הלוגיקה לקידוד האותות האלה לשימוש במכרז.
נדרשת הרשאה מסוג android.permission.ACCESS_ADSERVICES_PROTECTED_SIGNALS
ל-API.
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 שצוין בבקשה כדי לאחזר את עדכוני האותות. בנוסף לעדכוני האותות, התשובה יכולה לכלול נקודת קצה שמארחת את לוגיקת הקידוד להמרת האותות הגולמיים למטען ייעודי (payload) מקודד. העדכונים של האותות צריכים להיות בפורמט JSON, והם יכולים לכלול את המפתחות הבאים:
המפתחות ברמה העליונה של אובייקט ה-JSON צריכים להתאים לאחת מחמש הפקודות הבאות:
key |
תיאור |
|
הוספת אות חדש, שדורס אותות קיימים עם אותו מפתח. הערך הערך של המאפיין הזה הוא אובייקט JSON שבו המפתחות הם מחרוזות base 64 שמתאימות למפתח שצריך להזין, והערכים הם מחרוזות base 64 שמתאימות לערך שצריך להזין. |
|
הוספת אות חדש או אותות חדשים לסדרת אותות לפי זמן, והסרת האות הכי ישן האותות כדי לפנות מקום לאותות החדשים אם גודל הסדרה חורג מהמקסימום שצוין. הערך של המאפיין הזה הוא אובייקט JSON שבו המפתחות הם מחרוזות base 64 שתואמות למפתח שאליו רוצים לצרף, והערכים הם אובייקטים עם שני שדות: values ו-maxSignals. values: רשימה של מחרוזות base 64 שתואמות לערכי האותות שצריך לצרף לסדרת הזמן. maxSignals: מספר הערכים המקסימלי שמותר בסדרת הזמן הזו. אם המספר הנוכחי של האותות שמשויכים למפתח חורג מהערך של maxSignals, האותות הכי ישנים יוסרו. שימו לב: אפשר לצרף למפתח שנוסף באמצעות put. שימו לב: הוספה של יותר מהמספר המקסימלי של ערכים תגרום לכשל. |
|
הוספת אות חדש רק אם אין אותות קיימים עם אותו מפתח. הערך של המאפיין הזה הוא אובייקט JSON שבו המפתחות הם מחרוזות base 64 שמתאימות למפתח שצריך להזין, והערכים הם מחרוזות base 64 שמתאימות לערך שצריך להזין. |
|
הסרת האות למפתח. הערך של המאפיין הזה הוא רשימה של מחרוזות בקידוד Base64 שמתאימות למפתחות של אותות שצריך למחוק. |
|
מספק פעולה לעדכון נקודת הקצה ו-URI שאפשר להשתמש בו כדי לאחזר לוגיקת קידוד. מפתח המשנה לאספקת פעולת עדכון הוא 'action' וה הערך הנתמך היחיד הוא REGISTER, שיגרום לרישום של נקודת הקצה של המקודד אם היא סופקה בפעם הראשונה, או להחלפה של נקודת הקצה הקיימת בנקודת הקצה החדשה שסופקה. חובה לספק את נקודת הקצה לפעולה 'REGISTER'. מפתח המשנה לציון נקודת קצה של מקודד הוא 'endpoint', והערך הוא ה-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 (ראשון נכנס, ראשון יוצא). תהליך ההוצאה מהזיכרון יאפשר חריגה קלה מהמכסה למשך פרקי זמן קצרים, כדי להפחית את התדירות של ההוצאות מהזיכרון.
Signals Encoding 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 לרשימות של אובייקטים של Protected App Signals. לכל אובייקט Protected App Signals יש שלושה שדות:
-
signal_value
: UInt8Array שמייצג את ערך האות. -
creation_time
: מספר שמייצג את זמן היצירה של האותות בשניות מאז ראשית התקופה (epoch). -
package_name
: מחרוזת שמייצגת את שם החבילה שיצרה את האות.
הפרמטר maxSize
הוא מספר שמתאר את הגודל המקסימלי המותר של מערך בפלט.
הפונקציה צריכה להפיק אובייקט עם שני שדות:
status
: הערך צריך להיות 0 אם הסקריפט פעל בהצלחה.-
results
: צריך להיות UInt8Array באורך שקטן או שווה ל-maxSize. המערך הזה יישלח לשרת במהלך המכרזים, ויוכן על ידי הסקריפטprepareDataForAdRetrieval
.
הקידוד מספק לטכנולוגיות פרסום שלב ראשוני של הנדסת תכונות, שבו הן יכולות לבצע טרנספורמציות כמו דחיסת אותות גולמיים לגרסאות משורשרות על סמך הלוגיקה המותאמת אישית שלהן. שימו לב: במהלך מכרז מוגן שמופעל בסביבות מחשוב אמינות (TEE), ללוגיקה מותאמת אישית של טכנולוגיות פרסום תהיה גישת קריאה למטענים הייעודיים (payloads) של האותות שנוצרו על ידי הקידוד. הלוגיקה המותאמת אישית, שנקראת פונקציה מוגדרת על ידי המשתמש (UDF), שפועלת ב-TEE של כלי B&A של הקונה, תהיה לה גישת קריאה לאותות המוצפנים ולאותות הקשריים האחרים שסופקו על ידי אפליקציית בעל האתר כדי לבצע בחירת מודעות (אחזור מודעות והגשת הצעות מחיר).
קידוד אותות
בכל שעה, הקונים שסיפקו לוגיקת קידוד עם האותות הרשומים שלהם יקבלו קידוד של האותות במטען ייעודי (payload) של המכרז.מערך הבייטים של המטען הייעודי (payload) של המכרז נשמר במכשיר, מוצפן וייאסף על ידי המוכרים כחלק מנתוני בחירת המודעות, כדי להיכלל כחלק ממכרז מוגן. לצורך בדיקה, אפשר להפעיל את הקידוד הזה מחוץ לקצב השעתי שלו על ידי הרצת הפקודה הבאה:
adb shell cmd jobscheduler run -f com.google.android.adservices.api 29
ניהול גרסאות של לוגיקת המקודד
כשמתבצעת בקשה להורדת הלוגיקה של מקודד בהתאמה אישית של טכנולוגיית פרסום, נקודת הקצה של טכנולוגיית הפרסום יכולה להגיב עם מספר גרסה בכותרות התגובה. הגרסה הזו נשמרת יחד עם לוגיקת ההצפנה במכשיר. כשמקודדים את האותות הגולמיים, מטען הייעודי המקודד נשמר יחד עם הגרסה ששימשה לקידוד. הגרסה הזו נשלחת גם לשרת B&A במהלך מכרז מוגן, כדי שספקי טכנולוגיית פרסום יוכלו להתאים את לוגיקת הבידינג והקידוד שלהם על סמך הגרסה.
Response header for providing encoder version : X_ENCODER_VERSION
Protected Auction Support API
בצד המכשיר, הפעלת מכרז לאותות מוגנים מאפליקציות זהה להפעלת מכרז לקהלים מוגנים.
שירותי בידינג ומכרזים
ממשקי ה-API בצד השרת כוללים:
- Protected Auction API: סדרה של פונקציות JS או UDF שקונים ומוכרים יכולים לפרוס ברכיבי B&A שבבעלותם, כדי לקבוע את הצעות המחיר ואת לוגיקת המכרז.
- Ad Retrieval API: קונים יכולים להטמיע את ה-API הזה על ידי הטמעה של נקודת קצה של REST שתהיה אחראית על אספקת קבוצה של מודעות פוטנציאליות למכרז של Protected App Signal.
Protected Auction API
Protected Auction API מורכב מ-JS API או מ-UDF שקונים ומוכרים יכולים להשתמש בהם כדי להטמיע את הלוגיקה של המכרז והבידינג שלהם.
פונקציות מוגדרות על ידי המשתמש (UDF) של טכנולוגיות פרסום לקונים
פונקציית UDF prepareDataForAdRetrieval
כדי להשתמש באותות מוגנים מהאפליקציה כדי לאחזר מועמדים להצגת מודעות משירות אחזור המודעות של 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 ad tech.
function prepareDataForAdRetrieval(encodedOnDeviceSignals,encodedOnDeviceSignalsVersion,sellerAuctionSignals,contextualSignals) {
return {};
}
פונקציית UDF generateBid
אחרי שהמערכת מחזירה את 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
כדי לאפשר אימון מודלים (לפרטים נוספים על יציאה ואימון מודלים, אפשר לעיין בקטע הדיווח בהסבר על PAS).
פונקציית UDF reportWin
בסיום המכרז, שירות המכרזים ייצור כתובות URL לדיווח עבור הקונים וירשום משואות באמצעות reportWin
UDF (זו אותה פונקציה שמשמשת ל-Protected Audience).reportWin
המכשיר ישלח פינג לכתובת הזו אחרי שהלקוח יעבד את המודעה.
החתימה של השיטה הזו כמעט זהה לגרסה של Protected Audience, למעט שני פרמטרים נוספים egressPayload
ו-temporaryUnlimitedEgressPayload
שמשמשים להפעלת אימון המודל ומאוכלסים בתוצאות מ-generateBid
.
// Inputs / Outputs
// ----------------
// See detailed documentation here.
function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
buyerReportingSignals,
egressPayload, temporaryUnlimitedEgressPayload) {
// ...
}
פונקציות מוגדרות על ידי המשתמש (UDF) של ספקי טכנולוגיות פרסום (ATP)
פונקציית UDF scoreAd
ה-UDF הזה משמש מוכרים כדי לבחור איזו מבין המודעות שהתקבלו מקונים תזכה במכרז.
function scoreAd(adMetadata, bid, auctionConfig,
trustedScoringSignals, bid_metadata) {
// ...
return {desirability: desirabilityScoreForThisAd,
allowComponentAuction: true_or_false};
}
פונקציית UDF reportResult
ה-UDF הזה מאפשר למוכר (בסופו של דבר) ליצור דוחות ברמת האירוע עם המידע לגבי המודעה הזוכה.
function reportResult(auctionConfig, reporting_metadata) {
// ...
registerAdBeacon({"click", clickUrl,"view", viewUrl});
sendReportTo(reportResultUrl);
return signalsForWinner;
}
Ad Retrieval API
בגרסת ה-MVP, שירות אחזור המודעות יהיה שירות שמנוהל ומארח על ידי הקונה, ושירות הבידינג יאחזר מועמדים למודעות מהשירות הזה. החל מאפריל 2024, שרת אחזור המודעות יפעל בסביבת ביצוע מהימנה (TEE) ויחשוף ממשק GRPC/proto. חברות טכנולוגיות פרסום צריכות להגדיר את השרת הזה ולספק את כתובת ה-URL שלו כחלק מהפריסה של חבילת B&A. הטמעה של השירות הזה שפועלת בסביבת מחשוב אמינה זמינה ב-GitHub של ארגז החול לפרטיות. בשאר המסמכים אנחנו מניחים שזה הקוד שמשמש לפריסה.
החל מאפריל 2024, גרסאות B&A תומכות באחזור מודעות לפי נתיב הקשר. במקרה כזה, שרת הבידינג יקבל רשימה של מזהי מודעות שנשלחו על ידי שרת ה-RTB במהלך החלק ההקשרי של המכרז. המזהים יישלחו אל שרת TEE KV כדי לאחזר את כל המידע שקשור למודעה, שישמש במהלך שלב הבידינג (למשל, כתובת URL של הצגת מודעה, מטא-נתונים והטמעות של מודעות שישמשו בבחירה של k הפריטים המובילים). לא צריך להטמיע לוגיקה ספציפית בנתיב השני, ולכן נסביר כאן רק איך להגדיר את תרחיש השימוש של אחזור מודעות שמבוסס על TEE.
פונקציית UDF getCandidateAds
function getCandidateAds(requestMetadata, preparedDataForAdRetrieval,
deviceMetadata, contextualSignals, contextualAdIds,) {
return adsMetadataString;
}
כאשר:
-
requestMetadata
: JSON. מטא-נתונים של השרת לכל בקשה ל-UDF. כרגע אין כאן כלום. -
preparedDataForAdRetrieval
: התוכן של השדה הזה תלוי באסטרטגיית אחזור המודעות. במקרה של שליפת מודעות בהקשר , הפרמטר הזה יכיל את האותות הגולמיים שמקורם במכשיר, ויועברו משירות הבידינג. במקרה של שליפת מודעות TEE באמצעות שרת שליפת המודעות, הפרמטר הזה יכיל את התוצאה שלprepareDataForAdRetrieval
UDF. הערה: בשלב הזה, האותות של האפליקציה המוגנת יפוענחו ויבוטלו ההצפנה שלהם. -
deviceMetadata
: אובייקט JSON שמכיל מטא-נתונים של המכשיר שהועברו על ידי שירות הפרסום של המוכר. פרטים נוספים זמינים במסמכי התיעוד של B&A.-
X-Accept-Language
: השפה שמוגדרת במכשיר. -
X-User-Agent
: סוכן המשתמש שבו נעשה שימוש במכשיר. -
X-BnA-Client-IP
: כתובת ה-IP של המכשיר.
-
-
contextualSignals
: מחרוזת שרירותית שמקורה בשרת של הצעת מחיר בהקשר, שמנוהל על ידי אותה פלטפורמת DSP. הפונקציה המוגדרת על ידי המשתמש אמורה להיות מסוגלת לפענח את המחרוזת ולהשתמש בה. אותות לפי הקשר עשויים להכיל כל מידע, כמו פרטי גרסת מודל ה-ML להטמעה המוגנת שעוברת באמצעות אותות מוגנים של אפליקציות. -
contextualAdIds
: אובייקט JSON שמכיל רשימה אופציונלית של מזהי מודעות.
ה-UDF צריך להחזיר מחרוזת אם הפעולה הצליחה. המחרוזת מוחזרת לשרת הבידינג, שמעביר אותה ל-UDF generateBid
. למרות שהמחרוזת יכולה להיות מחרוזת בסיסית, סביר להניח שהיא צריכה להיות אובייקט שעבר סריאליזציה, שהסכימה שלו מוגדרת על ידי כל טכנולוגיית פרסום בנפרד.
אין הגבלה על הסכימה כל עוד הלוגיקה של טכנולוגיית הפרסום יכולה לזהות את המחרוזת ולהשתמש בה.generateBid
הגדרת המערכת לפיתוח
Android
כדי להגדיר את סביבת הפיתוח של Android, צריך לבצע את הפעולות הבאות:
- יוצרים אמולטור (מומלץ) או מכשיר פיזי שמופעל בו קובץ אימג' של Developer Preview 10
- מריצים את הפקודה הבאה:
adb shell am start -n com.google.android.adservices.api/com.android.adservices.ui.settings.activities.AdServicesSettingsMainActivity
לאחר מכן בוחרים באפשרות שמוצגת כדי להביע הסכמה להצגת מודעות בהמלצות על אפליקציות.
- מריצים את הפקודה הבאה כדי להפעיל את ממשקי ה-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;
- מפעילים מחדש את המכשיר.
- עוקפים את מפתחות המכרז של המכשיר כדי להפנות לשרת מפתחות המכרז שלכם. חשוב לבצע את השלב הזה לפני שמנסים להריץ מכרז, כדי למנוע שמפתחות שגויים יישמרו במטמון.
שירותי בידינג ומכרזים
כדי להגדיר את השרתים של B&A, אפשר לעיין במסמכי ההגדרה בשירות העצמי.
המאמר הזה מתמקד בהגדרת השרתים הספציפיים לקונים, כי לא נדרשים שינויים למוכרים.
דרישות מוקדמות
לפני שמפעילים חבילת שירותים של B&A, טכנולוגיית הפרסום של הקונים צריכה:
- מוודאים שהם הטמיעו שירות משלהם לאחזור מודעות TEE (ראו את הקטע הרלוונטי).
- צריך לוודא שלטכנולוגיית הפרסום יש את כל הפונקציות הנדרשות להגדרת משתמש (UDF) (
prepareDataForAdRetrieval
,generateBid
,reportWin
,getCandidateAds
) שמוגדרות ומאוחסנות.
מומלץ גם להבין איך מכרז מוגן עם Protected Audience API עובד עם B&A, אבל זה לא חובה.
הגדרות של Terraform
כדי להשתמש באותות מוגנים מאפליקציות, ספקי טכנולוגיות פרסום צריכים:
- הפעלת התמיכה ב-Protected App Signals ב-B&A.
- צריך לספק נקודות קצה של כתובות URL שאפשר לאחזר מהן את הפונקציות החדשות להגדרת משתמש (UDF) עבור
prepareDataForAdRetrieval, generateBid
ו-reportWin
.
בנוסף, במדריך הזה אנחנו מניחים שספקי טכנולוגיות פרסום שרוצים להשתמש ב-B&A לרימרקטינג ימשיכו להגדיר את כל דגלי ההגדרה הקיימים למכרז רימרקטינג כרגיל.
הגדרות טכנולוגיות פרסום של קונים
בדוגמה הזו של קובץ הדגמה, הקונים צריכים להגדיר את הדגלים הבאים:
- הפעלת אותות מוגנים מאפליקציות: מופעל כדי לאסוף נתונים של אותות מוגנים מאפליקציות.
- כתובות URL של Protected App Signals: מגדירים את כתובות ה-URL של השרתים של Protected App Signals.
ספקי טכנולוגיות פרסום צריכים להחליף את כתובות ה-URL הנכונות במחזיקי המקום בשדות הבאים:
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"
הגדרות של טכנולוגיות פרסום אצל המוכר
המוכרים צריכים להגדיר את הדגלים הבאים, על סמך קובץ ההדגמה הזה. (הערה: רק ההגדרה שקשורה לאותות מוגנים מהאפליקציה מודגשת כאן). ספקי טכנולוגיות פרסום צריכים לוודא שהם מחליפים את כתובות ה-URL הנכונות במחזיקי המקום:
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 שמשמש לאחזור מודעות שמבוסס על TEE בתור Ad Retrieval Server
, ולמופע שתומך באחזור מבוסס-נתיב לפי הקשר בתור KV Lookup Server
.
בשני המקרים, הפריסה של השרתים מתבצעת בהתאם לתיעוד שזמין ב-KV server GitHub. ההבדל בין שני המקרים הוא שבמקרה של בדיקת המיקום, הפעולה מתבצעת באופן אוטומטי ללא צורך בהגדרה נוספת, ואילו במקרה של אחזור, נדרשת פריסה של getCandidateAds
UDF כדי ליישם את לוגיקת האחזור. פרטים נוספים זמינים במדריך לתחילת העבודה עם שרת KV. שימו לב: B&A מצפה ששני השירותים יופעלו באותה רשת שירותים כמו שירות הבידינג.
הגדרה לדוגמה
תארו לעצמכם את התרחיש הבא: טכנולוגיית פרסום משתמשת ב-Protected App Signals API כדי לאחסן אותות רלוונטיים על סמך השימוש של המשתמש באפליקציה. בדוגמה שלנו, האותות שנשמרים מייצגים רכישות מתוך האפליקציה מכמה אפליקציות. במהלך מכרז, האותות המוצפנים נאספים ומועברים למכרז מוגן שפועל ב-B&A. הפונקציות להגדרת משתמש של הקונה שפועלות ב-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] דוגמה ל-prepareDataForAdRetrieval
/**
* `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, an 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 ad tech 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 getCandidateAds(requestMetadata, protectedSignals, deviceMetadata,
contextualSignals, contextualAdIds,) {
return "[{\"adId\":\"0\"},{\"adId\":\"1\"}]"
[Buyers] generateBid example
/**
* 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 בדוח [קונים]
reportWin
הפונקציה UDF מדווחת לקונה שהוא זכה במכרז.
function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
buyerReportingSignals, directFromSellerSignals,
egressPayload,
temporaryUnlimitedEgressPayload) {
sendReportTo("https://buyer-controlled-domain.com/");
registerAdBeacon({"clickEvent":"https://buyer-controlled-domain.com/clickEvent"});
return;
}
[Seller] הגדרת שרת 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"
]
}
}
[Seller] scoreAd example
/**
* 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
};
}
[Seller] reportResult example
function reportResult(auctionConfig, sellerReportingSignals, directFromSellerSignals){
let signalsForWinner = {};
sendReportTo("https://seller-controlled-domain.com");
registerAdBeacon({"clickEvent":
"https://seller-controlled-domain.com/clickEvent"});
return signalsForWinner;
}
אפליקציה לדוגמה
כדי להמחיש איך אפשר להשתמש ב-API כדי ליצור אפליקציה שמשתמשת בתהליך הזה, יצרנו אפליקציה לדוגמה של אותות מוגנים מאפליקציות. אפשר למצוא אותה במאגר הדוגמאות הזה.