Serveur à serveur : Guide de configuration d’un serveur d’enchères

La médiation interne n’est pas publique

La médiation interne avec Audience Network est actuellement en version bêta fermée et n’est pas publique. Nous procéderons à une mise à jour en cas de changement.

En attendant, vous pouvez accéder aux enchères de l’Audience Network par le biais de l’une des plateformes de médiation avec lesquelles nous sommes partenaires.

Ce guide détaille la marche à suivre pour construire un serveur d’enchères. Dans le guide étape par étape ci-dessous, nous utiliserons l’exemple d’enchères sur une publicité interstitielle. Vous devez avoir déjà l’habitude d’utiliser les publicités interstitielles de l’Audience Network. Les enchères prennent également en charge les formats Publicité native, Bandeau publicitaire, Publicité interstitielle, Vidéo in-stream et Vidéo avec récompense. Vous pouvez consulter nos formats publicitaires pris en charge ci-dessous pour intégrer un autre format publicitaire.

Conditions requises

L’exemple de code que nous fournissons sert uniquement à démontrer comment fonctionne l’API d’enchères et comment vous pouvez l’intégrer à votre serveur d’enchères interne. L’exemple de serveur d’enchères est écrit en Python avec Flask, avec des considérations minimales de stabilité et de sécurité pour la simplicité du code source.


Étapes de configuration d’un serveur d’enchères

Étape 1 : Définition des plateformes sur votre serveur

Étape 2 : Génération des demandes ORTB à partir de votre serveur

Étape 3 : Exécution des demandes ORTB à partir de votre serveur

Étape 4 : Lancement de l’enchère sur votre serveur

Étape 5 : Envoi d’une notification de gain/perte/expiration

Étape 6 : Renvoi du gagnant ou de la gagnante côté client

Étapes de configuration d’un serveur d’enchères

Étape 1 : Définition des plateformes sur votre serveur

Le champ ORTB imp.tagid contient l’identifiant de l’Audience Network pour l’inventaire. L’inventaire est représenté par l’ID dans l’Audience Network.

La demande ORTB envoyée au point de terminaison des enchères Audience Network doit contenir des informations sur l’appareil et sur l’application. Voici un exemple de charge utile dans une demande ORTB :

{
    // 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,
}
Paramètre Type Utilisation

${PLATFORM_ID}

string

Si vous êtes un·e partenaire de médiation, il s’agit de l’ID de partenaire fourni par votre contact Facebook.

Si vous êtes une éditrice ou un éditeur qui intègre une solution interne, il s’agit de l’ID d’application pour lequel vous envoyez la demande d’enchère. Il constitue la première partie de l’ID de placement, avant le trait de soulignement.

${AUTHENTICATION_ID}

string

Token d’authentification pour valider l’auteur·ice de la demande. Reportez-vous à cette page.

${AN_SECURITY_APP_MY_SECURITY_APP_ID}

string

ID de l’application de sécurité utilisée pour générer authentication_id. Reportez-vous à cette page.

${VERSION_NUMBER}

string

Version de l’intégration. 16 caractères maximum, générés par l’éditrice ou l’éditeur.

La charge utile de la demande ORTB ci-dessus est requise par l’Audience Network. Cependant, sur votre propre serveur d’enchères, vous pouvez en fait définir certaines des spécifications de l’application, telles que l’ID d’application, l’ID de placement et d’autres paramètres dans la configuration du serveur. Ensuite, votre application côté client n’a qu’à envoyer une demande simplifiée. Votre serveur peut mettre en boucle les informations de placement et construire la demande ORTB finale. Vous trouverez ci-dessous un exemple de paramètres du serveur d’enchères :

{
"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}"
}
]
}
]
}
]
}
Paramètre Utilisation

${PLATFORM_ID}

Si vous êtes un partenaire de médiation, il s’agit de l’ID de partenaire fourni par votre contact Facebook.

Si vous êtes une éditrice ou un éditeur qui intègre une solution interne, il s’agit de l’ID d’application pour lequel vous envoyez la demande d’enchère. Il constitue la première partie de l’ID de placement, avant le trait de soulignement.

Avec les paramètres du serveur d’enchères ci-dessus, l’application côté client n’a qu’à envoyer une demande simplifiée avec "app_id":"101" et "placement_id":"1" à votre serveur. Ensuite, votre serveur sera en mesure de rechercher les informations complètes sur le placement, telles que placement_id, ad_format, platform_name, etc. Voici un exemple simplifié de charge utile de demande côté client :

{
// 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',
},
}

Une fois que la demande simplifiée est envoyée à votre serveur d’enchères, vous devriez être en mesure de rechercher les informations complètes sur le placement, l’appareil et l’application sur la base des valeurs app_id et placement_id dans les paramètres de votre serveur d’enchères. Voici un exemple de résultat de recherche :

{
    "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}"
    }]
}

Étape 2 : Génération des demandes ORTB à partir de votre serveur

Une fois que le serveur d’enchères a reçu la demande d’enchère, il doit élaborer les demandes d’enchère pour chacune des sources de demande. Voici le point de terminaison dans app.py pour recevoir la demande d’enchère :

@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'
)

Dans bid_manager.py, la demande d’enchère du client contient les valeurs app_id et placement_id qui seront utilisées pour rechercher les informations complètes de placement dans les paramètres du serveur.

# 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)

Ensuite, dans audience_network.py, la fonction get_bid_request générera la demande ORTB finale pour l’Audience Network en fonction des informations complètes de placement.

Le champ ORTB imp.tagid contient l’identifiant de l’Audience Network pour l’inventaire. L’inventaire est représenté dans l’Audience Network en tant qu’ID de placement.

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)

Formats publicitaires pris en charge

Nous prenons actuellement en charge quatre types de publicités qui peuvent être demandées via OpenRTB : bannière, native (publicité native ou bannière native), vidéo (avec récompense ou intégrée) et interstitielle. Remarque : la bannière, et les objets natifs et vidéo s’excluent mutuellement, mais l’un d’eux est requis.

Voici une liste des formats publicitaires pris en charge dans les demandes d’enchère :

Format publicitaire Paramètres de la demande d’enchère

Publicité native

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

Bannière native

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

Publicité interstitielle

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

Vidéo avec récompense

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

Publicité interstitielle avec récompense

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

Bannière - Hauteur : 50

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

Bannière - Hauteur : 250*

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

* Vous pouvez créer une bannière ou un placement rectangulaire de taille moyenne dans le Gestionnaire de monétisation pour ce format publicitaire

Étape 3 : Exécution des demandes ORTB à partir de votre serveur

Une fois que l’objet demande ORTB a été créé comme indiqué ci-dessus, nous pouvons envoyer la demande au point de terminaison Audience Network à l’adresse https://an.facebook.com/${PLATFORM_ID}/placementbid.ortb via une requête HTTP utilisant post et Content-Type: application/json.

Dans bid_manager.py, une fois que toutes les demandes d’enchère ont été recueillies, exec_bid_requests est appelé pour chaque plateforme :

# 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))

Les en-têtes HTTP suivants (à la fois sur les enchères et l’absence d’enchères) définis dans la réponse contiennent des informations utiles pour le dépannage et doivent être consignés sur le serveur d’enchères :

  • X-FB-AN-Request-ID : l’ID de la demande est nécessaire pour permettre à l’Audience Network de débuguer une demande spécifique. N’hésitez pas à le capturer pour l’utiliser lorsque vous demandez de l’aide.
  • X-FB-AN-Errors : liste des erreurs rencontrées, utile pour comprendre les raisons de l’absence d’enchères.
  • X-FB-Debug : informations de débogage concernant cette demande que vous pouvez envoyer à votre chargé·e de compte à l’Audience Network à des fins de dépannage.

Note : afin de minimiser la latence, vous devez ajouter un en-tête X-FB-Pool-Routing-Token dans votre demande d’enchère.

  • X-FB-Pool-Routing-Token : ce token est utilisé pour acheminer la demande vers notre data center le plus proche, et sa valeur est identique à celle de user.buyeruid.

Dans audience_network.py, la demande ORTB sera envoyée à l’Audience Network et la réponse à l’enchère correspondante sera transmise au serveur d’enchères :

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)

Vous pouvez transmettre un corps de requête binaire compressé avec gzip si vous fournissez un en-tête Content-Encoding:gzip à votre requête.

Étape 4 : Lancement de l’enchère sur votre serveur

Maintenant, nous avons déjà des réponses aux enchères de différentes plateformes (réseau). Dans bid_manager.py, la fonction get_bid_response permet de comparer les réponses aux enchères et de choisir l’enchère la plus élevée et donc le gagnant ou la gagnante.

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

Comme l’Audience Network est le seul enchérisseur dans notre exemple, la méthode utilisée compare simplement l’enchère renvoyée avec une certaine valeur de prix et décide si elle remporte l’enchère. Par conséquent, si l’enchère renvoyée par l’Audience Network est supérieure à 1 dollar, nous répondons que l’Audience Network a remporté l’enchère. Sinon, nous considérons que cet enchérisseur a perdu l’enchère.

Étape 5 : Envoi d’une notification de gain/perte/facturation/expiration

Nous demandons des notifications de gain, de perte, de facturation et d’expiration accompagnée des codes de perte correspondants, comme défini dans l’ORTB. La nurl, la lurl et la burl ORTB sont fournies dans la réponse d’enchère. Consultez la section précédente pour un exemple de réponse d’enchère. En cas d’expiration de l’enchère, nous vous proposons une autre démarche de signalement.

Notification du gagnant

La nurl gagnante sera fournie dans la réponse d’enchère. Vous devez renseigner le prix d’adjudication dans la nurl :

"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} : cette variable doit être remplacée par le prix d’adjudication de la vente aux enchères dans la même devise que notre enchère (USD sur une base CPM).

Notification de perte

Notre lurl de perte contient deux indicateurs que vous devez renseigner :

"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} : cette variable doit être remplacée par le code de perte ORTB.
  • ${AUCTION_PRICE} : cette variable doit être remplacée par le prix d’adjudication de la vente aux enchères dans la même devise que notre enchère (USD sur une base CPM).

Vous trouverez ci-dessous une liste des différents codes de perte et des motifs de perte correspondants.

Motif de perteDescriptionCode de perte ORTB version 2.5

Réponse d’enchère non valide

L’enchère n’est pas valide (mais a été effectuée dans les temps, n’est pas une absence d’enchère et reste suffisamment valide pour pouvoir en extraire la nurl)

3

Expiration de l’enchère*

La réponse d’enchère a été reçue, mais trop tard pour la coupure de la vente aux enchères

2

Absence d’enchères

Les absences d’enchères sont indiquées par le code HTTP 204 (pas de nurl à appeler), mais vous pouvez interpréter notre réponse comme une absence d’enchères (probablement un problème d’intégration) Vous pouvez également demander des enchères pour plusieurs impressions ; nous enchérirons sur certains, mais pas sur toutes.

9

N’est pas le plus fort enchérisseur RTB

Un autre enchérisseur participant à la même vente aux enchères nous a battus, enchérisseurs synthétiques compris (échanges non RTB).

102

L’inventaire ne s’est pas matérialisé

Notre enchère a remporté la vente, mais l’impression ne s’est pas matérialisée (la page n’était pas assez longue pour inclure cet emplacement ou l’utilisateur a quitté l’app avant la diffusion de la publicité mise en cache). Tous les partenaires ne peuvent pas fournir ce motif (c’est un non-évènement), nous partirons donc du principe que le motif n’est pas fourni.

4902

Envoyé au serveur publicitaire

Envoyez ceci si le dernier point de contact que vous avez avec le processus de décision envoie notre enchère haute au serveur publicitaire. L’impression peut toujours être perdue du fait de lignes manquantes, du serveur publicitaire passant outre la vente aux enchères ou d’une absence de matérialisation de l’inventaire.

4900

Gagnant RTB non sélectionné par le serveur publicitaire

Nous avons remporté la vente aux enchères RTB, mais le serveur est passé outre la vente (direct).

4903

Gain

Nous avons remporté l’intégralité de l’arbre de décision et une balise a été placée sur la page (web) ou un objet publicitaire mis en cache (app). Il est possible que cette situation n’engendre pas d’impression visible.

0

Notification facturable

Nous demandons une notification facturable en cas de rappel d’impression déclenché dans le SDK Audience Network. Vous devez renseigner le prix d’adjudication dans la burl :

"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} : cette variable doit être remplacée par le prix d’adjudication de la vente aux enchères dans la même devise que notre enchère (USD sur une base CPM).

Notification d’expiration

En cas d’expiration de l’enchère, nous vous proposons une autre démarche de signalement. Il s’agit de la nurl générique qui pourrait être appelée sans devoir attendre l’arrivée de l’enchère. Le format est le suivant :

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

Remarque : les champs ${PARTNER_FBID}, ${APP_FBID} et ${AUCTION_ID} doivent être renseignés avec les valeurs appropriées. Le tableau ci-dessous fournit une explication de ces valeurs.

ParamètreTypeDescription

PARTNER_FBID

entier

ID de serveur de vente aux enchères publicitaire émis par Facebook. Utilisez votre ID d’app ici si vous n’avez pas de partenaire de vente aux enchères publicitaire dédié.

APP_FBID

entier

ID émis par Facebook de l’application/l’entreprise à l’initiative de la vente aux enchères.

AUCTION_ID

Chaîne

ID généré par le client de la vente aux enchères utilisée pour émettre une demande d’enchère.

Étape 6 : Renvoi du gagnant ou de la gagnante côté client

Après avoir lancé l’enchère, nous créons l’objet réponse et le renvoyons à l’application cliente. Voici la méthode de l’exemple dans bid_manager.py qui crée la réponse finale du serveur d’enchères :

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,
})

Enfin, notre exemple de serveur peut créer cette réponse au client pour lui indiquer quelle plateforme utiliser :

{
'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
}