API להטמעת נתוני קריאייטיב של וידאו

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

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

בשלב השני, מערכת המודעות מקבלת את המזהים האלה ומוסיפה אותם למסמכי ה-VAST שמפנים לקריאייטיב שנשלח, באמצעות מזהה המודעה האוניברסלי (VAST 4.0 ואילך) או באמצעות תוסף קריאייטיב מסוג UniversalAdId. כשמתגלה מסמך VAST ממערכת המודעות בזמן קבלת ההחלטה ב-DAI או ב-YouTube, מערכת הקריאייטיב מחלצת את המזהים האלה מה-VAST ומאחזרת את הקריאייטיב המתאים מתשתית הווידאו של Google כדי להוסיף אותו להפעלה.

דרישות לגבי מדיה

כדי שהמערכת תוכל לעבד את נכסי הקריאייטיב שנשלחים ל-API, הם צריכים לעמוד בקריטריונים הבאים.

סוגי מדיה

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

  • video/mp4
  • video/webm
  • video/quicktime
  • video/avi
  • video/mpeg
  • video/x-flv
  • flv-application/octet-stream
  • application/octet-stream
  • video/3gpp
  • video/ogg
  • audio/mp4
  • audio/mpeg

מאפייני מדיה

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

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

שליחת נכסי קריאייטיב להטמעה

תרשים זרימה של תהליך הטמעת הנתונים

  1. מערכת מודעות של צד שלישי שולחת בקשת HTTP ל-Video Creative Ingest API עם רשימה של קובצי מדיה שמשויכים לקריאייטיב.
  2. ה-Video Creative Ingest API בוחר את הקריאייטיב באיכות הגבוהה ביותר מהרשימה שסופקה ומוריד אותו מה-CDN.
  3. באמצעות Video Creative Ingest API, המערכת מעבירה את הקריאייטיב שהורדתם לתשתית הווידאו של Google, כך שהוא יהיה זמין גם למוצרים של YouTube וגם למוצרים של DAI.
  4. התראה ב-Pub/Sub נשלחת בחזרה למערכת המודעות של הצד השלישי עם סטטוס הקריאייטיב. בהודעה יצוין אם ההעלאה בוצעה בהצלחה גם ב-YouTube וגם ב-DAI. אם טעינת הקריאייטיב נכשלה, ההתראה תציין את הסיבה לכך.

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

אימות

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

אחרי שיסופקו פרטי החשבון ל-Google דרך creativeingestion@google.com, תקבלו גישה לנקודות הקצה של ה-API ולנושאים של Cloud PubSub שמיועדים לפרסום התראות.

כדי להתחיל בתהליך האימות, פועלים לפי השלבים הבאים:

  1. יוצרים חשבון Google Cloud.
  2. מגדירים פרויקט עם החשבון לשליחת בקשות ל-DAI API.
  3. בפרויקט, עוברים לכרטיסייה IAM & Admin בצד ימין ויוצרים חשבון שירות חדש. הבקשות נשלחות באמצעות חשבון השירות.
  4. מפעילים את PubSub API ויוצרים נושא ייחודי אחד של התראות לשותפים, שאליו ה-API מפרסם את כל ההתראות על הצלחה וכשל בהטמעה.

    אם יש לכם מדיניות ארגונית של הגבלת דומיינים, עליכם להוסיף את מזהה הלקוח ב-Google לרשימת הלקוחות המורשים. אפשר לפנות אל creativeingestion@google.com כדי לקבל את המזהה. לאחר מכן, תוכלו להוסיף חשבונות משתמשים (חשבון הרובוט שלנו) מרשימות של לקוחות מורשים (מזהה הלקוח של ה-API) למדיניות IAM (PubSub Publisher).

    מוסיפים את video-creative-library-discovery@system.gserviceaccount.com כ-PubSub Publisher לנושא.

  5. כדי לרשום את המידע הזה ב-API, מציינים ב-creativeingestion@google.com את כתובת האימייל של חשבון השירות ואת נושא ה-PubSub.

  6. מפעילים את DAI API אחרי שמוסיפים את החשבון כצרכן שירות.

  7. כדי להגדיר את פרטי הכניסה לגישה ל-API:

    • מורידים את פרטי הכניסה מחשבון השירות: לוחצים על חשבון השירות בקטע Service accounts בכרטיסייה IAM & Admin, לוחצים על Create Key ושומרים את פרטי הכניסה.

    • אימות מבצע הקריאה ל-API. מגדירים את GOOGLE_APPLICATION_CREDENTIALS לנתיב של קובץ ה-JSON. דוגמאות קוד לאימות לקוחות gRPC בשפות נפוצות.

הטמעת נכסי קריאייטיב

בכל פעם שקריאייטיב חדש זמין במערכת הפרסום של שותף, המערכת של השותף צריכה לשלוח את הקריאייטיב אל Creative Ingest API.

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

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

בקשות לקריאייטיב

הנתונים נשלחים ל-API כ-Protocol Buffers או כאובייקטים של JSON. מומלץ להשתמש במאגרי פרוטוקולים שנשלחים באמצעות gRPC, כי הם נחוצים לשימוש בהתראות PubSub, ויש סיבוכים נוספים בפעולה של ביטול הפורמט של ה-JSON בגלל שדות google.protobuf.Any בתגובה.

תגובות לקריאייטיב

אם הבקשה תאושר, השרת יחזיר תגובה של Protocol Buffer או תגובה של JSON, בהתאם לסוג הבקשה. התשובה כוללת את שם פעולת הטמעת הנתונים שנוצרה ואת פרטי הפעולה.

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

חשוב לזכור שצריך לבצע unmarshaling של המטא-נתונים מ-proto של Any ל-proto של CreateCreativeOperationMetadata, ושל התגובה (אם יש כזו) ל-proto של Creative.

ספריית לקוח לגישה ל-API

כדי לשלב את ה-API:

  1. מורידים את היחסי התלות של מאגר הפרוטוקול ומעבירים את כל התיקייה google לספרייה src. אפשר לדלג על השלב הזה אם משתמשים ב-Google Cloud App Engine.
  2. משתמשים בפלאגין protoc כדי ליצור קוד gRPC מקובץ ה-proto ולשים את הקוד שנוצר בתיקייה הרלוונטית.
  3. יוצרים קובץ proto חדש ל-proto שהוחזר בהתראה של PubSub, וחוזר על השלב הקודם כדי ליצור קוד מה-proto.
  4. משתמשים ב-gRPC כדי לשלוח בקשות ל-API:

    1. אחזור פרטי כניסה שמוגדרים כברירת מחדל עם ההיקפים הבאים:

    https://www.googleapis.com/auth/video-ads,

    https://www.googleapis.com/auth/pubsub

    1. שולחים את הבקשה ל-Creative Ingest.
    • מתחברים ל-dai.googleapis.com:443 באמצעות פרטי הכניסה שמוגדרים כברירת מחדל.
    • יוצרים סטאב של לקוח לשירות הטמעת הקריאייטיב באמצעות הקוד שנוצר על ידי ה-proto של gRPC.
    • קוראים ל-CreateCreative באמצעות סטאב הלקוח.

    לחלופין, אפשר ליצור stub לשירות Operations באמצעות קוד gRPC של פעולות ממושכות – שמופיע בספרייה googleapis שהורדתם בשלב 2 – שאפשר להשתמש בו כדי לקבל את הסטטוס של פעולה נתונה (GetOperation).

  5. בודקים את PubSub אם יש התראות:

    1. משתמשים בספריית הלקוח של PubSub או ב-gRPC כדי להתחבר לשירות PubSub ולבצע סקירה של התראות PubSub שפורסמו בנושא שצוין.

    2. מבצעים ביטול שרשור (unmarshal) של הודעת ה-PubSub ל-proto משלב 4.

    3. בכל פעם שמוחזרת פעולה ממושכת מקריאות ל-CreateCreative, ל-GetOperation או בהתראה של PubSub, צריך לבצע unmarshal למטא-נתונים ב-CreateCreativeOperationMetadata ב-discovery.proto מה-proto של google.protobuf.Any, וכל תשובה ב-Creative ב-discovery.proto.

דוגמה לקוד לקוח ב-Go

// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
  dai "google.golang.org/genproto/googleapis/ads/dai/v1"
  psnotif "protos/dai"
  "google.golang.org/genproto/googleapis/longrunning"
  "cloud.google.com/go/pubsub"
  "golang.org/x/net/context"
  "google.golang.org/grpc"
  "google.golang.org/grpc/credentials"
  "google.golang.org/grpc/credentials/oauth"
  "github.com/golang/protobuf/proto"
  anypb "github.com/golang/protobuf/ptypes/any"
)

var scopes = []string{"https://www.googleapis.com/auth/video-ads", "https://www.googleapis.com/auth/pubsub"}

const (
  subID = "sub-id" // The ID for the subscription to the topic you provided us (projects/<project ID>/subscriptions/<subscription ID>)
  project = "your-project-id" // Your Google Cloud Project ID
)

func main() {
  ctx := context.Background()
  crpc, err := oauth.NewApplicationDefault(ctx, scopes...)
  if err != nil {
    // TODO: Handle error
  }

  conn, err := grpc.Dial("dai.googleapis.com:443",
    grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")),
    grpc.WithPerRPCCredentials(crpc))
  if err != nil {
    // TODO: Handle error 
  }

  apiclient := dai.NewPartnerDiscoveryServiceClient(conn)
  opclient := longrunning.NewOperationsClient(conn)

  op, err := apiclient.CreateCreative(ctx, &dai.CreateCreativeRequest{
    // TODO: Add Creative with metadata and media files.
  })
  if err != nil {
    // TODO: Handle error
  }

  pubsubClient, err := pubsub.NewClient(ctx, project)
  if err != nil {
    // TODO: Handle error
  }
  sub := pubsubClient.Subscription(subID)

  // TODO: Pull from Pub/Sub subscription to receive messages, and acknowledge them
  var msg *pubsub.Message // Assume msg = a received Pub/Sub message

  // Unmarshal the Pub/Sub message into the proto created in step 9a of guide
  var n psnotif.CreateCreativeStatus
  if err := proto.Unmarshal(msg.Data, &n); err != nil {
    // TODO: Handle error
  }
  op = n.GetDetails()
  md, err = anyToMetadata(op.GetMetadata())
  if err != nil {
    // TODO: Handle error
  }
  // TODO: Check if ingest was successful and get Google Video ID from md.GetGvRegistryId()
  // TODO: Enable serving of creative using Google Video ID in VAST document

  // Optionally check the status of an ingest request using the status endpoint
  op, err = opclient.GetOperation(ctx, &longrunning.GetOperationRequest{Name:   op.Name})
  if err != nil {
    // TODO: Handle error
  }
}

// anyToMetadata converts the metadata Any field in an Operation message to
// CreateCreativeOperationMetadata.
func anyToMetadata(msg *anypb.Any) (*dai.CreateCreativeOperationMetadata, error) {
  var md dai.CreateCreativeOperationMetadata
  return &md, proto.Unmarshal(msg.Value, &md)
}

// anyToCreative converts the response Any field in an Operation message to
// Creative.
func anyToCreative(msg *anypb.Any) (*dai.Creative, error) {
  var cr dai.Creative
  return &cr, proto.Unmarshal(msg.Value, &cr)
}

חיפוש קריאייטיב במהלך ההפעלה

תרשים זרימה של תהליך החיפוש של נכסי הקריאייטיב

  1. המשתמש מבקש לצפות בתוכן ב-YouTube או ב-DAI.
  2. מערכת YouTube / DAI מקבלת תגובה מסוג VAST ממערכת מודעות של צד שלישי, כדי להוסיף מודעות לתוכן.
  3. המודעות שחוזרות ממפות לקריאייטיבים שנוספו בעבר. נכסי הקריאייטיב האלה מוכנים להפעלה – הם מאוחזרים מ-Google Video Infrastructure ומשודרים למשתמש.

מסמכי VAST ששותף שינה

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

יש שתי דרכים להפנות לנכס קריאייטיב שעבר עיבוד במסמך VAST: הוספת רכיב UniversalAdId חדש למסמך VAST 4 ואילך או הוספת תוסף בהתאמה אישית.

מזהה מודעה אוניברסלי

הערך gvRegistryID שמוחזר על ידי Video Creative Ingest API הוא מזהה ציבורי אוניברסלי שמשמש לזיהוי ייחודי של קריאייטיב וידאו במספר מערכות פרסום. צריך להוסיף את המזהה הזה למסמכי VAST 4 ואילך של מערכת המודעות, כדי שכאשר YouTube או DAI יקבלו מסמך VAST, אפשר יהיה להשתמש במזהה כדי למפות אותו בחזרה לנכס הקריאייטיב שנשלח במקור.

מערכות פרסום צריכות להוסיף רכיב UniversalAdId חדש למסמכי VAST 4 ואילך, מתחת לצומת Creative. צריך להגדיר את המאפיין idRegistry כ-"googlevideo", והערך צריך להיות הערך שצוין בסטטוס של ההודעה על הקריאייטיב שעובד בהצלחה.

לפניכם דוגמה למסמך VAST 4 שבו נוסף מזהה המודעה האוניברסלי החדש:

<VAST xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vast.xsd" version="4.0">
  <Ad id="318230556">
    <InLine>
      <AdSystem>DCM</AdSystem>
      <AdTitle>In-Stream Video</AdTitle>
      <Creatives>
        <Creative id="79534759" AdID="" sequence="1">
          <UniversalAdId idRegistry="googlevideo">dQw4w9WgXcQ</UniversalAdId>
          <Linear>
            <Duration>00:00:15</Duration>
            <MediaFiles>
              <Mezzanine>
                <![CDATA[https://cdn.com/media.mp4]]>
              </Mezzanine>
              <MediaFile delivery="progressive" width="640" height="360" type="video/mp4" bitrate="313">
                <![CDATA[https://cdn.com/low-res-media.mp4]]>
              </MediaFile>
            </MediaFiles>
          </Linear>
        </Creative>
      </Creatives>
    </InLine>
  </Ad>
</VAST>

CreativeExtension

מאחר שהרכיב Universal Ad ID הוצג רק ב-VAST 4.0, צריך להשתמש בתוסף מותאם אישית כדי לחשוף את אותם נתונים במסמכי VAST בגרסה נמוכה מ-4.0. כדי לעשות זאת, משתמשים ברכיב CreativeExtension בקטע Creative של מפרט ה-VAST.

התוסף החדש הוא תוסף כללי שמאפשר לאכלס כל ערך של מזהה Universal AD. במקרה הזה, מזהה המודעה האוניברסלי שייך למרשם googlevideo והמזהה יהיה מזהה הסרטון ב-Google.

<VAST version="3.0">
  <Ad id="318230556">
    <InLine>
      <AdSystem>My Ad Server</AdSystem>
      <AdTitle>Car Company</AdTitle>
      <Creatives>
        <Creative id="79534759" AdID="" sequence="1">
          <Linear>...</Linear>
          <CreativeExtensions>
            <CreativeExtension type="UniversalAdId">
              <UniversalAdId idRegistry="googlevideo">dQw4w9WgXcQ</UniversalAdId>
            </CreativeExtension>
          </CreativeExtensions>
        </Creative>
      </Creative>
    </InLine>
  </Ad>
</VAST>

אפשר להשתמש בגישה של CreativeExtension גם ב-VAST 4 ואילך, במקרה שה-UniversalAdId כבר מאוכלס במזהה של מאגר UniversalAdId אחר:

<VAST xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vast.xsd" version="4.0">
  <Ad id="318230556">
    <InLine>
      <AdSystem>DCM</AdSystem>
      <AdTitle>In-Stream Video</AdTitle>
      <Creatives>
        <Creative id="79534759" AdID="" sequence="1">
          <UniversalAdId idRegistry="other-registry">other-id</UniversalAdId>
          <Linear>
            <Duration>00:00:15</Duration>
            <MediaFiles>
              <Mezzanine>
                <![CDATA[https://cdn.com/media.mp4]]>
              </Mezzanine>
              <MediaFile delivery="progressive" width="640" height="360" type="video/mp4" bitrate="313">
                <![CDATA[https://cdn.com/low-res-media.mp4]]>
              </MediaFile>
            </MediaFiles>
          </Linear>
          <CreativeExtensions>
            <CreativeExtension type="UniversalAdId">
              <UniversalAdId idRegistry="googlevideo">dQw4w9WgXcQ</UniversalAdId>
            </CreativeExtension>
          </CreativeExtensions>
        </Creative>
      </Creatives>
    </InLine>
  </Ad>
</VAST>