Server-zu-Server: Einrichtungsleitfaden für den Auktionsserver

Die interne Mediation ist nicht öffentlich verfügbar.

Interne Gebote mit Audience Network befinden sich aktuell in der geschlossenen Beta-Phase und sind nicht öffentlich verfügbar. Sollte sich dies ändern, werden wir dies bekanntgeben.

Du kannst alternativ über eine der Mediationsplattformen, mit denen wir eine Partnerschaft unterhalten, auf Gebote im Audience Network zugreifen.

In diesem Leitfaden wird die Einrichtung eines internen Auktionsservers beschrieben. Die folgende Schritt-für-Schritt-Anleitung verwendet ein Gebot auf eine Interstitial Ad als Beispiel. Du solltest dich zuvor mit Interstitial Ads im Audience Network vertraut machen. Gebote unterstützen außerdem die Formate Native, Banner, Interstitial, In-Stream-Video und Rewarded Video. In unserer Liste der unterstützten Werbeformate weiter unten findest du Hinweise zur Integration anderer Werbeanzeigenformate.

Voraussetzungen

Der gezeigte Beispielcode demonstriert die Funktionsweise der Gebots-API und die Integration der API mit deinem internen Auktionsserver. Der Beispiel-Auktionsserver ist in Python mit Flask geschrieben. Dabei wurde kaum auf Stabilität und Sicherheit geachtet, um den Quellcode einfach zu halten.


Schritte zur Einrichtung des Auktionsservers

Schritt 1: Definieren der Plattformen auf deinem Server

Schritt 2: Generieren von ORTB-Anfragen von deinem Server

Schritt 3: Ausführen von ORTB-Anfragen von deinem Server

Schritt 4: Ausführen der Auktion auf deinem Server

Schritt 5: Auslösen der Gewinn-, Verlust-, Rechnungs- und Zeitüberschreitungsbenachrichtigungen

Schritt 6: Übergabe des Gewinners zurück zu deiner Clientseite

Schritte zur Einrichtung des Auktionsservers

Schritt 1: Definieren der Plattformen auf deinem Server

Das ORTB-Feld imp.tagid enthält die Audience Network-ID für den Katalog. Der Katalog wird im Audience Network als ID dargestellt.

Die an den Gebotsendpunkt im Audience Network gesendete ORTB-Anfrage muss sowohl Geräte- als auch App-Informationen enthalten. Beispiel für die Payload in einer ORTB-Anfrage:

{
    // Device information from client side
    'device': {
        'ifa': '${DEVICE_ID}',
        'dnt': '0',
        'ip': '127.0.0.1'
    },
    // Application information
    'app': {
        'ver': '1.0',
        'bundle': 'com.facebook.audiencenetwork.AdUnitsSample',
        'publisher': {
            // For server to server bidding integration, this is your application id on Facebook
            'id': '${APP_ID}',
        }
    },
    // Placement information we can store on server
    'imp': [
        {
            'id': 'banner_test_bid_req_id',
            // This is the placement id for Audience Network
            'tagid': '${PLACEMENT_ID}',
            'banner': {
                'w': -1,
                'h': 50,
            },
        },
    ],
    // Optional regulations object from client side
    'regs': {
        'coppa': 0,
    },
    // In server to server integration, you can use the Facebook app id as platform id here
    'ext': {
        'platformid': '${PLATFORM_ID}',
        // Mediation partner Platform ID or publisher FB app ID, mandatory.
        'authentication_id': '${AUTHENTICATION_ID}',
        // Authentication token to validate the originator of the request.
        'security_app_id': '${AN_SECURITY_APP_MY_SECURITY_APP_ID}',
        // Security app id used to generate authentication_id.
        's2s_version': '${VERSION_NUMBER}',
        // Version of the integration. Max 16 characters.
    },
    // buyeruid is the user bidder token generated on client side, using the `getBidderToken` method from the Audience Network SDK. 
    // It's constant through out app session so you could cache it on the client side
    'user': {
        'buyeruid': 'mybuyeruid',
    },
    // Test mode flag
    'test': '1',
    // Time out setting we can store on server
    'tmax': 1000,
    // Request ID we can generate on server
    'id': 'banner_test_bid_req_id',
    // Auction setting we can store on server
    'at': 1,
}
Parameter Typ Nutzung

${PLATFORM_ID}

string

Wenn du Mediationspartner bist, ist dies die Partner-ID, die du von deiner Kontaktperson bei Facebook erhalten hast.

Wenn du ein Publisher*in bist, der*die eine interne Lösung integriert, ist dies die App-ID, für die du die Gebotsanfrage sendest. Dies ist der erste Teil der Placement ID vor dem Unterstrich.

${AUTHENTICATION_ID}

string

Authentifizierungstoken zur Validierung des*der Absender*in der Anfrage. Weitere Informationen findest du auf dieser Seite.

${AN_SECURITY_APP_MY_SECURITY_APP_ID}

string

Zur Generierung der authentication_id verwendete Sicherheits-App-ID (siehe diese Seite).

${VERSION_NUMBER}

string

Version der Integration. Maximal 16 Zeichen, von dem*der Publisher*in generiert.

Die gezeigte Payload einer ORTB-Anfrage ist für das Audience Network erforderlich. Auf deinem eigenen Auktionsserver kannst du jedoch einige der App-Merkmale wie App-ID, Placement ID und andere Parameter in der Serverkonfiguration selbst definieren. Anschließend muss deine clientseitige App nur eine vereinfachte Anfrage senden. Dein Server kann die Platzierungsinformationen durchlaufen und die endgültige ORTB-Anfrage erstellen. Konfigurationsbeispiel für den Auktionsserver:

{
"bidding_source_platforms": [
{
"platform_name": "audience_network",
"end_point": "https://an.facebook.com/${PLATFORM_ID}/placementbid.ortb",
"timeout": 1000,
"timeout_notification_url": "https://www.facebook.com/audiencenetwork/nurl/?partner=${PARTNER_FBID}&app=${APP_FBID}&auction=${AUCTION_ID}&ortb_loss_code=2"
}
],
"apps": [
{
"app_id": "101",
"app_name": "My example app",
"placements": [
{
"placement_id": "1",
"placement_name": "My example placement",
"ad_format": "interstitial",
"bidding_source_placement_ids":[
{
"platform_name": "audience_network",
"platform_app_id": "${APP_ID}",
"platform_placement_id": "${PLACEMENT_ID}"
}
]
}
]
}
]
}
Parameter Nutzung

${PLATFORM_ID}

Wenn du Mediationspartner bist, ist dies die Partner-ID, die du von deiner Kontaktperson bei Facebook erhalten hast.

Wenn du ein Publisher*in bist, der*die eine interne Lösung integriert, ist dies die App-ID, für die du die Gebotsanfrage sendest. Dies ist der erste Teil der Placement ID vor dem Unterstrich.

Mit den gezeigten Einstellungen für den Auktionsserver muss die clientseitige App nur eine vereinfachte Anfrage mit "app_id":"101" und "placement_id":"1" an deinen Server senden. Der Server kann anschließend die vollständigen Platzierungsinformationen wie placement_id, ad_format, platform_name usw. nachschlagen. Hier eine Beispiel-Payload einer vereinfachten Anfrage von deiner Clientseite:

{
// App ID and placement ID are used to look up settings from
// server settings
'app_id': '101',
'placement_id': '1',

'bundle': 'com.facebook.samples.s2sbiddingclient',
'bundle_version': '1.0',

// Device specifics
'ifa': '${DEVICE_ID}',
'coppa': 0,
'dnt': 0,

// buyer_tokens are the user tokens required for different networks
'buyer_tokens': {
// Token for audience network from BidderTokenProvider.getBidderToken(context)
// This can be cached for the same app session
'audience_network': 'my-buyeruid',
},
}

Sobald die vereinfachte Anfrage an deinen Auktionsserver geschickt wurde, kannst du die vollständigen Platzierungs-, Geräte- und App-Informationen für app_id und placement_id in den Einstellungen deines Auktionsservers suchen. Hier ein Beispielergebnis für diese Suche:

{
    "placement_id": "1",
    "placement_name": "My example placement",
    "ad_format": "interstitial",
    "bidding_source_placement_ids": [{
        "platform_name": "audience_network",
        "platform_app_id": "${APP_ID}",
        "platform_placement_id": "${PLACEMENT_ID}"
    }]
}

Schritt 2: Generieren von ORTB-Anfragen von deinem Server

Wenn der Auktionsserver die Auktionsanfrage erhält, muss er die Gebotsanfragen für die einzelnen Bedarfsquellen erstellen. Der folgende Endpunkt in app.py empfängt die Auktionsanfrage:

@app.route('/get_bid', methods=['POST'])
def get_bid():
'''
The actual endpoint that expects a ClientRequest in the parameters
'''
# Initialize the server settings
ServerSettings.initialize(
app.config['bidding_source_platforms'],
app.config['apps']
)

request_params = request.get_json(force=True)

# See the code sample below for this function in `bid_manager.py`
(code, response) = get_bid_response(
request.remote_addr,
request.user_agent.string,
request_params)

app.logger.debug('server response: {0} {1}'.format(code, response))
return Response(
json.dumps(response),
status=code,
mimetype='application/json'
)

In bid_manager.py enthält die Auktionsanfrage des Clients die Werte app_id und placement_id, mit denen die vollständigen Platzierungsinformationen in den Servereinstellungen gesucht werden.

# Return Auction Result - Winner - back to client side
def get_bid_response(ip, user_agent, request_params):
"""Get the winner bid response for the current request"""
try:
app_id = request_params['app_id']
placement_id = request_params['placement_id']
auction_id = get_auction_id()
...
# Find placement in the settings
placement = ServerSettings.get_placement(app_id, placement_id)

# Collect bid requests for different platforms
bid_requests = get_bid_requests(
ip,
user_agent,
auction_id,
placement,
request_params)

except Exception as e:
raise ParameterError("Error in request parameters: {}".format(str(e)))
...
return final_response

# Get all bid requests for different platforms
def get_bid_requests(ip, user_agent, auction_id, placement, request_params):
"""Create bid requests based on the internal placement setting"""

...

(end_point, data, timeout_notification_url) = get_bid_request(
ip,
user_agent,
auction_id,
platform_name,
platform_app_id,
platform_placement_id,
ad_format,
request_params)

if data is not None:
results.append({
'platform_name': platform_name,
'end_point': end_point,
'data': data,
'timeout_notification_url': timeout_notification_url,
})

# current_app.logger.debug("requests: {}".format(results))
return results

# Get bid request for each platform
def get_bid_request(
ip,
user_agent,
auction_id,
platform_name,
platform_app_id,
platform_placement_id,
ad_format,
request_params
):
"""Create bid request for a specific platform"""
if platform_name == 'audience_network':

return audience_network.get_bid_request(
ip,
user_agent,
auction_id,
platform_app_id,
platform_placement_id,
ad_format,
request_params)

else:
return (None, None, None)

Anschließend generiert die Funktion audience_network.py in get_bid_request die endgültige ORTB-Anfrage für das Audience Network anhand der vollständigen Platzierungsinformationen.

Das ORTB-Feld imp.tagid enthält die Audience Network-ID für den Katalog. Der Katalog wird im Audience Network als Placement ID dargestellt.

def get_bid_request(
ip,
user_agent,
auction_id,
platform_app_id,
platform_placement_id,
ad_format,
request_params
):
'''
Gather the required bid request parameters for networks. The parameters
consist of platform settings like app id, placement ids, ad sizes etc., and
client side information such as device information, user agent etc. We use
the `settings.json` file to store platform specific settings, and the
client request to retrieve the clietn specific information.
'''
platform = ServerSettings.get_platform('audience_network')
end_point = platform['end_point']
timeout = platform['timeout']
timeout_notification_url = platform['timeout_notification_url']

timeout_notification_url.replace('${PARTNER_FBID}', platform_app_id)
timeout_notification_url.replace('${APP_FBID}', platform_app_id)
timeout_notification_url.replace('${AUCTION_ID}', auction_id)

imp = []
if ad_format == 'native':
imp.append({
'id': auction_id,
'native': {
'w': -1,
'h': -1,
},
'tagid': platform_placement_id,
})
elif ad_format == 'banner':
imp.append({
'id': auction_id,
'banner': {
'w': -1,
'h': 50,
},
'tagid': platform_placement_id,
})
elif ad_format == 'interstitial':
imp.append({
'id': auction_id,
'banner': {
'w': 0,
'h': 0,
},
'tagid': platform_placement_id,
'instl': 1,
})
elif ad_format == 'rewarded_video':
imp.append({
'id': auction_id,
'video': {
'w': 0,
'h': 0,
'linearity': 2,
},
'tagid': platform_placement_id,
})
elif ad_format == 'instream_video':
imp.append({
'id': auction_id,
'video': {
'w': 0,
'h': 0,
'linearity': 1,
},
'tagid': platform_placement_id,
})
else:
raise ParameterError("Incorrect ad format")

typed_ip = ipaddress.ip_address(ip)
device = {
'ifa': request_params['ifa'],
'ua': user_agent,
'dnt': request_params['dnt'],
}
if type(typed_ip) is ipaddress.IPv6Address:
device['ipv6'] = ip
else:
device['ip'] = ip

# Construct the ORTB request
request = {
'id': auction_id,
'imp': imp,
'app': {
'bundle': request_params['bundle'],
'ver': request_params['bundle_version'],
'publisher': {
'id': platform_app_id,
}
},
'device': device,
'regs': {
'coppa': request_params['coppa'],
},
'user': {
'buyeruid': request_params['buyer_tokens']['audience_network'],
},
'ext': {
'
': platform_app_id,
},
'at': 1,
'tmax': timeout,
'test': request_params['test'],
}

return (end_point, request, timeout_notification_url)

Unterstützte Werbeanzeigenformate

Es werden derzeit vier Arten von Anzeigen unterstützt, die du über OpenRTB anfordern kannst: Banner Ads, Native Ads (Native oder Native Banner Ads) und Video (Rewarded Video oder In-Stream Video) sowie Interstitial Ads. Hinweis: Die Objekte Banner, Native und Video schließen einander aus, jedoch ist eines von ihnen erforderlich.

Dies ist eine Liste der unterstützten Anzeigenformate in der Gebotsanfrage:

Anzeigenformat Parameter in der Gebotsanfrage

Native

{'id': ${AUCTION_ID}, 'native': { 'h': -1, 'w': -1 }, 'tagid': ${PLACEMENT_ID}}

Native Banner

{'id': ${AUCTION_ID}, 'native': { 'h': -1, 'w': -1 }, 'tagid': ${PLACEMENT_ID}}

Interstitial

{'id': ${AUCTION_ID}, 'banner': { 'h': 0, 'w': 0 }, 'tagid': ${PLACEMENT_ID}, 'instl': 1}

Rewarded Video

{'id': ${AUCTION_ID}, 'video': { 'h': 0, 'w': 0, 'ext': { 'videotype': 'rewarded' } }, 'tagid': ${PLACEMENT_ID}}

Rewarded Interstitial

{'id': ${AUCTION_ID}, 'video': { 'h': 0, 'w': 0, 'ext': { 'videotype': 'rewarded_interstitial' } }, 'tagid': ${PLACEMENT_ID}}

Banner – Höhe: 50 (in cm: 5000)

{'id': ${AUCTION_ID}, 'banner': { 'h': 50, 'w': -1 }, 'tagid': ${PLACEMENT_ID}}

Banner – Höhe: 250*

{'id': ${AUCTION_ID}, 'banner': { 'h': 250, 'w': -1 }, 'tagid': ${PLACEMENT_ID}}

* Für dieses Anzeigenformat kannst du im Monetization Manager eine Banner- oder eine Medium Rectangle-Platzierung erstellen

Schritt 3: Ausführen von ORTB-Anfragen von deinem Server

Nachdem das ORTB-Anfrageobjekt wie oben beschrieben erstellt wurde, können wir die Anfrage an den Audience Network-Endpunkt unter https://an.facebook.com/${PLATFORM_ID}/placementbid.ortb schicken. Dazu verwenden wir eine HTTP-Anfrage mit post und Content-Type: application/json.

bid_manager.py sammelt zunächst alle Gebotsanfragen für die einzelnen Plattformen und ruft anschließend „exec_bid_requests“ für jede Plattform auf:

# Return Auction Result - Winner - back to client side
def get_bid_response(ip, user_agent, request_params):
"""Get the winner bid response for the current request"""
...
# Execute bid requests by network
bid_responses = []
for bid_request in bid_requests:
(code, response) = exec_bid_request(
bid_request['platform_name'],
bid_request['end_point'],
bid_request['data'],
bid_request['timeout_notification_url'])

bid_responses.append({
'platform_name': bid_request['platform_name'],
'code': code,
'response': response,
})

final_response = run_auction(bid_responses, placement)
return final_response

# Execute bid request for different platform (network)
def exec_bid_request(
platform_name,
end_point,
request_params,
timeout_notification_url
):
'''
Actually run the bid requests for the networks.
'''
if platform_name == 'audience_network':
return audience_network.exec_bid_request(
end_point,
request_params,
timeout_notification_url,
)
else:
raise InternalError("Invalid platform: {}".format(platform_name))

Die folgenden HTTP-Header (für Gebote und nicht-Gebote) in der Antwort enthalten hilfreiche Informationen für die Fehlerbehebung und sollten auf dem Auktionsserver protokolliert werden:

  • X-FB-AN-Request-ID: Die Anfrage-ID wird für das Debuggen einzelner Anfragen im Audience Network benötigt. Erfasse diese ID immer, wenn du Support benötigst.
  • X-FB-AN-Errors: Eine Liste der aufgetretenen Fehler, hilfreich bei der Ursachensuche für nicht-Gebote.
  • X-FB-Debug: Debuginformationen zu dieser Anfrage, die du zur Fehlerbehebung an deine*n Audience Network-Ansprechpartner*in schicken kannst.

Hinweis: Um die Latenz zu minimieren, muss deine Gebotsanfrage den Header X-FB-Pool-Routing-Token enthalten.

  • X-FB-Pool-Routing-Token: Dieser Schlüssel wird verwendet, um die Anfrage zu unserem nächstgelegenen Rechenzentrum zu routen, und hat denselben Wert wie user.buyeruid.

In audience_network.py wird die ORTB-Anfrage an das Audience Network geschickt, und die entsprechende Gebotsantwort wird an den Auktionsserver zugestellt:

def exec_bid_request(
end_point,
request_params,
timeout_notification_url
):
try:
platform = ServerSettings.get_platform('audience_network')
headers = {
'Content-Type': 'application/json; charset=utf-8',
'X-FB-Pool-Routing-Token': request_params['user']['buyeruid'],
}
timeout = platform['timeout']
r = requests.post(
end_point,
json=request_params,
headers=headers,
# Timeout in settings.json in ms
timeout=(timeout / 1000),
)
except Exception as e:
current_app.logger.error(BID_TIMEOUT)

# Send time out notification
r = requests.get(timeout_notification_url, timeout)
return (500, BID_TIMEOUT)

if r.status_code == requests.codes.ok:
try:
data = json.loads(r.text)
current_app.logger.debug('Audience Network response: {}'.format(
data
))
# Parse response from Audience Network with the ORTBResponse
ortb_response = ORTBResponse(data)
except Exception as e:
current_app.logger.error(
PARSE_ERROR + "{}".format(e)
)
return (500, PARSE_ERROR + "{}".format(e))

return (r.status_code, ortb_response)

else:
# The error message is stored in the X-FB-AN-Errors header
error_header = r.headers.get('x-fb-an-errors')
debug_header = r.headers.get('x-fb-debug')
bid_request_id = r.headers.get('x-fb-an-request-id')

if r.status_code == 400:
error_message = INVALID_BID + error_header + INVALID_BID_ADVICE
elif r.status_code == 204:
error_message = NO_BID + error_header
else:
error_message = UNEXPECTED_ERROR

# Log error information for debugging
error = {
'bid_request_id': bid_request_id,
'debug_header': debug_header,
'error_message': error_message,
}
current_app.logger.error(error)

# Respond error status code to client
return (r.status_code, error_message)

Du kannst einen binären, gzip-komprimierten Anfrageinhalt übergeben, wenn du deiner Anfrage einen Content-Encoding:gzip-Header hinzufügst.

Schritt 4: Ausführen der Auktion auf deinem Server

Wir haben die Gebotsantworten von unterschiedlichen Plattformen (Netzwerken) erhalten. Die Funktion bid_manager.py in get_bid_response ist dafür zuständig, die ausgefüllten Gebotsantworten zu vergleichen und das höchste Gebot – den Gewinner – auszuwählen.

def get_bid_response(ip, user_agent, request_params):
"""Get the winner bid response for the current request"""
...
final_response = run_auction(bid_responses, placement)
return final_response

def run_auction(bid_responses, placement):
"""Run auction based on raw responses and create the response object"""
other_bid = 1
response = (204, None)  # default is 204 no fill

for bid_response in bid_responses:
if bid_response['platform_name'] == 'audience_network':
if bid_response['code'] == 200:
ortb_response = bid_response['response']
if ortb_response.price > other_bid:
response = create_response(bid_response, placement)
current_app.logger.debug(
'Audience Network bid: {} won!'.format(
ortb_response.price
)
)
notify_result(bid_response)
else:
current_app.logger.debug(
'Audience Network bid: {} lost!'.format(
ortb_response.price
)
)
notify_result(bid_response, 102)
else:
current_app.logger.debug(bid_response['response'])

return response

Da das Audience Network der einzige Bieter in unserem Beispiel ist, vergleicht die Auktionsmethode einfach das zurückgegebene Gebot mit einem festgelegten Preis und entscheidet, ob das Gebot die Auktion gewinnt. Wenn das vom Audience Network zurückgegebene Gebot höher als 1 Dollar ist, geben wir das Audience Network in unserer Antwort als Gewinner bekannt. Andernfalls wird das Audience Network behandelt, als hätte es die Auktion verloren.

Schritt 5: Auslösen der Gewinn-, Verlust-, Rechnungs- und Zeitüberschreitungsbenachrichtigungen

Wir benötigenGewinn-, Verlust-, Rechnungs- und Zeitüberlaufbenachrichtigungen mit den entsprechenden in ORTB definierten Verlustcodes. ORTB nurl, lurl und burl werden in der Gebotsantwort angegeben. Im vorherigen Abschnitt findest du ein Beispiel für eine Gebotsantwort. Im Fall einer Zeitüberschreitung erhältst du von uns eine alternative Meldungsroute.

Gewinnerbenachrichtigung

Die Gewinn-nurl wird in der Gebotsantwort angegeben. Du musst den Vergabepreis in der nurl ausfüllen:

"https://www.facebook.com/audiencenetwork/nurl/?partner=${PARTNER_FBID}&app=${APP_FBID}&placement=${PLACEMENT_FBID}&auction=${AUCTION_ID}&impression=${IMPRESSION_ID}&request=${BID_REQUEST_ID}&bid=${BID_ID}&ortb_loss_code=0&clearing_price=${AUCTION_PRICE}"
  • ${AUCTION_PRICE}: Ersetze diesen Wert durch den Vergabepreis für die Auktion in der gleichen Währung wie unser Gebot (z. B. USD auf CPM-Basis).

Verlustbenachrichtigung

Unsere Verlust-lurl enthält zwei Flags, die ausgefüllt werden müssen:

"https://www.facebook.com/audiencenetwork/nurl/?partner=${PARTNER_FBID}&app=${APP_FBID}&placement=${PLACEMENT_FBID}&auction=${AUCTION_ID}&impression=${IMPRESSION_ID}&request=${BID_REQUEST_ID}&bid=${BID_ID}&ortb_loss_code=${AUCTION_LOSS}&clearing_price=${AUCTION_PRICE}"
  • ${AUCTION_LOSS}: Ersetze dieses Flag durch den ORTB-Verlustcode.
  • ${AUCTION_PRICE}: Ersetze diesen Wert durch den Vergabepreis für die Auktion in der gleichen Währung wie unser Gebot (z. B. USD auf CPM-Basis).

Die folgende Liste enthält verschiedene Verlustcodes und entsprechende Begründungen.

VerlustgrundBeschreibungORTB v2.5-Verlustcode

Ungültige Gebotsantwort

Gebot ist ungültig (jedoch pünktlich, kein nicht-Gebot und hinreichend gültig, um die nurl zu extrahieren)

3

Zeitüberschreitung bei Gebot *

Gebotsantwort erhalten, aber erst nach Auktionsende

2

Nicht-Gebot

Nicht-Gebote sind als HTTP 204 definiert (keine aufrufbare nurl), aber du kannst unsere Antwort als nicht-Gebot interpretieren (vermutlich ein Integrationsproblem). Möglicherweise hast du Gebote für mehrere Impressionen angefordert, und wir haben nicht für alle Impressionen Gebote abgegeben.

9

Nicht höchster RTB-Bieter

Wir wurden überboten, inklusive synthetischer Gebote (z. B. nicht-RTB-Vorgänge), falls diese in derselben Auktion abgegeben wurden.

102

Bestand hat sich nicht konkretisiert

Unser Gebot hat die Auktion gewonnen, aber die Impression hat sich nicht konkretisiert (z. B. Seite war nicht lang genug für den Slot, oder ein Benutzer hat die App verlassen, bevor eine zwischengespeicherte Werbeanzeige verwendet wurde). Diese Antwort (ein nicht-Event) wird nicht von jedem Partner geliefert und wird daher abgeleitet falls nicht angegeben.

4902

An Werbeanzeigenserver gesendet

Sende diese Antwort, wenn die Übermittlung unseres höchsten Gebots an den Werbeanzeigenserver dein letzter Berührungspunkt mit dem Entscheidungsprozess ist. Die Impression kann immer noch verloren gehen, wenn Einzelpositionen fehlen, der Auktionsserver das Auktionsergebnis aufhebt oder sich der Bestand nicht konkretisiert.

4900

RTB-Gewinner nicht vom Werbeanzeigenserver ausgewählt

Wir haben die RTB-Auktion gewonnen, aber der Werbeanzeigenserver hat die Auktion aufgehoben (z. B. direkt).

4903

Gewinner

Wir haben den kompletten Entscheidungsbaum gewonnen und ein Tag wurde auf der Seite platziert (Web) bzw. ein Werbeanzeigenobjekt wurde zwischengespeichert (App). Diese Nachricht garantiert immer noch keine sichtbare Impression.

0

Rechnungsbenachrichtigung

Wir benötigen eine Rechnungsbenachrichtigung, wenn der Impression-Rückruf im Audience Network-SDK aufgerufen wird. Du musst den Vergabepreis in der burl ausfüllen:

"https://www.facebook.com/audiencenetwork/burl/?partner=${PARTNER_FBID}&app=${APP_FBID}&placement=${PLACEMENT_FBID}&auction=${AUCTION_ID}&impression=${IMPRESSION_ID}&request=${BID_REQUEST_ID}&bid=${BID_ID}&ortb_loss_code=0&clearing_price=${AUCTION_PRICE}"
  • ${AUCTION_PRICE}: Ersetze diesen Wert durch den Vergabepreis für die Auktion in der gleichen Währung wie unser Gebot (z. B. USD auf CPM-Basis).

Zeitüberlaufbenachrichtigung

Bei einer Zeitüberschreitung erhältst du von uns eine alternative Meldungsroute. Diese generische nurl kann aufgerufen werden, bevor das Gebot eintrifft. Das Format sieht folgendermaßen aus:

"https://www.facebook.com/audiencenetwork/nurl/?partner=${PARTNER_FBID}&app=${APP_FBID}&auction=${AUCTION_ID}&ortb_loss_code=2"

Hinweis:${PARTNER_FBID}, ${APP_FBID} und ${AUCTION_ID} müssen mit den passenden Werten ausgefüllt werden. Die folgende Tabelle enthält eine Erklärung dieser Werte.

ParameterTypBeschreibung

PARTNER_FBID

Int

Werbeanzeigenserver-ID wird von Facebook ausgestellt. Gib hier deine App-ID an, wenn du keinen dedizierten Partner für Anzeigenauktionen hast.

APP_FBID

Int

Von Facebook ausgestellte ID der App bzw. des Unternehmens, das eine Auktion gestartet hat.

AUCTION_ID

String

Vom Client generierte ID der Auktion, die du in deiner Gebotsanfrage verwendet hast.

Schritt 6: Übergabe des Gewinners zurück zu deiner Clientseite

Im Anschluss an die Auktion erstellen wir das Antwortobjekt und geben es an die Client-App zurück. Die folgende Methode in bid_manager.py erstellt die Antwort des Auktionsservers:

def create_response(bid_response, placement):
"""Create response object based on the auction result"""
ad_format = placement['ad_format']
platform_name = bid_response['platform_name']
platform_placement_id = None

for bidding_source_placement_id in placement[
'bidding_source_placement_ids'
]:
if bidding_source_placement_id['platform_name'] == platform_name:
platform_placement_id = bidding_source_placement_id[
'platform_placement_id'
]

if platform_placement_id is None:
raise InternalError("Platform placement ID not found!")

bid_payload = None
if platform_name == 'audience_network':
bid_payload = bid_response['response'].adm
else:
raise InternalError("Invalid platform")

return (200, {
'placement_id': placement['placement_id'],
'ad_format': ad_format,
'platform_name': platform_name,
'platform_placement_id': platform_placement_id,
'bid_payload': bid_payload,
})

Unser Beispielserver kann dem Client jetzt in seiner Antwort mitteilen, welche Plattform er verwenden soll:

{
'placement_id': string, // Placement identifier for the auction server
'ad_format': string, // Format of the placement
'platform_name': string, // Which platform won the auction, for example 'audience_network'
'platform_placement_id': string, // Placement ID for the platform, for example the placement ID for Audience network
'bid_payload': string, // The JSON string payload for the platform SDK to load the final ad
}

Als Nächstes: Schritt-für-Schritt-Integration für Clients