Servidor a servidor: Guía de configuración del servidor de subastas

La mediación interna no está disponible para el público

Por el momento, la puja interna con Audience Network se encuentra en una versión en beta cerrada y no está disponible al público. Brindaremos actualizaciones si se produce algún cambio.

De manera alternativa, puedes acceder a las pujas en Audience Network a través de alguna de las plataformas de mediación con las que estamos asociados.

En esta guía, se describe cómo crear un servidor de subastas propio. En la siguiente guía paso a paso, utilizaremos el ejemplo de puja en un anuncio intersticial. Asegúrate de estar familiarizado con los anuncios intersticiales de Audience Network. Las pujas también admiten formatos de banner publicitario y de anuncio nativo, intersticial, con video instream y con video con premio. Puedes verificar nuestros formatos de anuncios admitidos a continuación para integrar un formato de anuncio diferente.

Requisitos previos

El código de ejemplo que proporcionamos solo sirve para mostrar cómo funciona la API de puja y cómo puedes integrarla con tu servidor de subastas propio. El servidor de subastas de ejemplo está escrito en Python con Flask, con mínimas consideraciones de estabilidad y seguridad para mantener la simplicidad del código fuente.


Pasos para configurar el servidor de subastas

Paso 1: Definir las plataformas en tu servidor

Paso 2: Generar solicitudes de ORTB desde tu servidor

Paso 3: Ejecutar solicitudes de ORTB desde tu servidor

Paso 4: Ejecutar la subasta en tu servidor

Paso 5: Activar notificación de éxito/pérdida/tiempo agotado

Paso 6: Entregar el ganador a tu lado del cliente

Pasos para configurar el servidor de subastas

Paso 1: Definir las plataformas en tu servidor

El campo de ORTB imp.tagid contiene el identificador de inventario de Audience Network. El inventario está representado en Audience Network como el identificador.

La solicitud de ORTB que se envía al punto de conexión de pujas de Audience Network debe contener la información de la app y del dispositivo. Aquí hay un ejemplo de la carga en una solicitud de 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,
}
Parámetro Tipo Uso

${PLATFORM_ID}

string

Si eres socio de mediación, es el identificador de socio que te proporcionó tu contacto de Facebook.

Si eres editor e integras una solución propia, es el identificador de la app por la que envías la solicitud de puja. Es la primare parte del identificador de ubicación antes del guion bajo.

${AUTHENTICATION_ID}

string

Token de autenticación para validar el autor de la solicitud. Consulta esta página.

${AN_SECURITY_APP_MY_SECURITY_APP_ID}

string

Identificador de la app de seguridad para generar "authentication_id". Consulta esta página.

${VERSION_NUMBER}

string

Versión de la integración. Máx. de 16 caracteres, generados por el editor.

Audience Network requiere la carga de la solicitud de ORTB indicada anteriormente. Sin embargo, en tu propio servidor de subastas, puedes definir algunas especificaciones de la app, como el identificador de la app, el identificador de ubicación y algunos otros parámetros de la configuración del servidor. Luego, tu app del lado del cliente solo necesita enviar una solicitud simplificada. Tu servidor puede conectar en bucle la información de ubicación y crear la solicitud de ORTB final. A continuación, se muestra la configuración del servidor de subastas de ejemplo:

{
"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}"
}
]
}
]
}
]
}
Parámetro Uso

${PLATFORM_ID}

Si eres socio de mediación, es el identificador de socio que te proporcionó tu contacto de Facebook.

Si eres editor e integras una solución propia, es el identificador de la app por la que envías la solicitud de puja. Es la primare parte del identificador de ubicación antes del guion bajo.

Con la configuración del servidor de subastas que se indicó anteriormente, la app del lado del cliente solo necesita enviar una solicitud simplificada con "app_id":"101" y "placement_id":"1" a tu servidor. Luego, tu servidor podrá buscar información completa de ubicación, como placement_id, ad_format, platform_name, etc. Aquí se muestra una carga de solicitud de ejemplo simplificada del lado del cliente:

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

Una vez que se envíe tu solicitud simplificada a tu servidor de subasta, podrás buscar la información completa referida a la ubicación, al dispositivo y a la app en función de app_id y placement_id, que se encuentra en la configuración del servidor de subastas. Aquí puedes ver un ejemplo del resultado de la búsqueda:

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

Paso 2: Generar solicitudes de ORTB desde tu servidor

Después de que el servidor de subastas recibe la solicitud de subasta, necesita crear las solicitudes de puja de los orígenes de demanda. Aquí se encuentra el punto de conexión en app.py que recibe la solicitud de puja:

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

En bid_manager.py, la solicitud de puja del cliente contiene el app_id y el placement_id, que se usarán para buscar la información completa de la ubicación en la configuración del servidor.

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

Luego, en audience_network.py, la función get_bid_request generará la solicitud de ORTB final de Audience Network en función de la información de ubicación completa.

El campo de ORTB imp.tagid contiene el identificador de inventario de Audience Network. El inventario se representa en Audience Network como el identificador de ubicación.

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)

Formatos de anuncios admitidos

Por el momento, admitimos cuatro tipos de anuncios que se pueden solicitar a través de OpenRTB: banner, nativo (nativo o banner nativo), video (video con premio o instream) e intersticial. Nota: Los objetos banner, nativo y video son mutuamente exclusivos, pero es obligatorio usar uno de ellos.

Esta es una lista de los formatos de anuncios admitidos en la solicitud de puja:

Formato de anuncio Parámetros en la solicitud de puja

Nativo

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

Banner nativo

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

Intersticial

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

Video con premio

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

Intersticial con premio

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

Banner - Altura: 50

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

Banner - Altura: 250*

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

* Puedes crear una ubicación de un banner o medio rectángulo en el administrador de monetización para este formato de anuncio

Paso 3: Ejecutar la solicitud de ORTB de tu servidor

Una vez creado el objeto de la solicitud de ORTB, como se muestra más arriba, podemos enviar la solicitud al punto de conexión de Audience Network en https://an.facebook.com/${PLATFORM_ID}/placementbid.ortb mediante una solicitud HTTP, con post y Content-Type: application/json.

En bid_manager.py, una vez que recopila todas las solicitudes de puja de las plataformas, hará una llamada a exec_bid_requests en relación con cada una de las plataformas:

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

Los siguientes encabezados HTTP (tanto de pujas como de no pujas) de la respuesta estarán configurados para que contengan información útil para solucionar problemas y deben registrarse en el servidor de subastas:

  • X-FB-AN-Request-ID: Audience Network necesita el identificador de la solicitud para depurar una solicitud específica. Haz una captura de pantalla cuando solicites asistencia.
  • X-FB-AN-Errors: una lista de los errores que se encontraron, que resulta útil para comprender las razones que no llevan a pujas.
  • X-FB-Debug: la información de depuración referida a esta solicitud que puedes enviar a tu representante de la cuenta en Audience Network para solucionar problemas.

Nota: Con el fin de minimizar la latencia, se te solicita que agregues el encabezado X-FB-Pool-Routing-Token en tu solicitud de puja.

  • X-FB-Pool-Routing-Token: este token se usa para enrutar la solicitud a nuestro centro de datos más cercano, y su valor es igual a user.buyeruid.

En audience_network.py, la solicitud de ORTB se enviará a Audience Network, y la respuesta de la puja se enviará de forma correspondiente al servidor de subastas:

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)

Puedes pasar el cuerpo de una solicitud binaria comprimido en formato gzip si proporcionas un encabezado Content-Encoding:gzip en tu solicitud.

Paso 4: Ejecutar la subasta en tu servidor

Ahora ya tenemos respuestas de subastas de diferentes plataformas (red). En bid_manager.py, la función get_bid_response será responsable de comparar las respuestas de pujas y decidir el mejor postor: el ganador.

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

Dado que Audience Network es el único que realizó pujas en nuestro ejemplo, el método de subasta ejecutado simplemente compara la puja devuelta con cierto valor de precio y decide si gana la subasta. Como resultado, si la oferta que se devuelve desde Audience Network es superior a 1 dólar, respondemos que Audience Network ganó la puja; caso contrario, consideramos que perdió la subasta.

Paso 5: Activar notificación de capacidad de facturación/éxito/pérdida/tiempo agotado

Requerimos notificaciones de éxito, pérdida, capacidad de facturación y tiempo agotado con los códigos de pérdida correspondientes, según se define en ORTB. ORTB nurl, lurl y burl se proporcionan en la respuesta de puja. Consulte la sección anterior para ver ejemplos de respuestas de puja. En caso de una puja con tiempo agotado, proporcionamos una ruta de informe alternativa.

Notificación de éxito

La nurl de éxito se incluye en la respuesta de puja. Debes completar el precio de adjudicación en 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}: debe reemplazarse con el precio de adjudicación para la subasta, en la misma unidad que la puja (p. ej., USD o CPM).

Notificación de pérdida

La lurl de pérdida contiene dos marcas que debes completar:

"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}: debe reemplazarse con el código de pérdida de ORTB.
  • ${AUCTION_PRICE}: debe reemplazarse con el precio de adjudicación para la subasta, en la misma unidad que la puja (p. ej., USD o CPM).

A continuación, se incluye una lista con diferentes códigos de pérdida y sus correspondientes motivos de pérdida.

Motivo de pérdidaDescripciónCódigo de pérdida de ORTB v2.5

Respuesta de puja no válida

Puja no válida (pero a tiempo; no es sin puja y es lo suficientemente válida para extraer la nurl)

3

Tiempo agotado de la puja *

Respuesta de la puja recibida, pero demasiado tarde para el corte de la subasta

2

Sin puja

Los casos sin puja se indican como HTTP 204 (p. ej., sin una nurl para llamar), pero puede interpretarse la respuesta como sin puja (posible problema de integración). También puedes solicitar pujas para varias impresiones; pujaremos por algunas, pero no todas.

9

No es el pujador RTB más alto

Otro pujador nos ganó, incluso en pujas sintéticas (p. ej., intercambios que no son RTB) si se incluyen en la misma subasta.

102

El inventario no se materializó

Nuestra puja ganó la subasta, pero la impresión no se materializó (la página no era lo suficientemente larga para incluir esta posición o el usuario salió de la aplicación antes de que se utilizara el anuncio almacenado en caché). No todos los socios pueden ofrecer esto (es un no evento), por lo que inferimos que no se proporcionó.

4902

Envío a un servidor de anuncios

Envía esto si el último punto de contacto en el proceso de decisión envía nuestra puja alta al servidor de anuncios. Es posible que la impresión se pierda de todos modos entre los elementos de la línea faltante, que el servidor de anuncios anule la subasta o que el inventario no se materialice.

4900

Ganador de RTB no elegido por el servidor de anuncios

Ganamos la subasta de RTB, pero el servidor de anuncios anuló la subasta (de forma directa).

4903

Ganador

Ganamos el árbol de decisiones completo, y se colocó una etiqueta en la página (web) o se almacenó en caché el objeto de anuncio (aplicación). Es posible que la impresión visualizable no se materialice de todos modos.

0

Notificación de capacidad de facturación

Requerimos una notificación de capacidad de facturación en caso de que se active una devolución de llamada a la impresión en el SDK de Audience Network. Debes completar el precio de adjudicación en 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}: debe reemplazarse con el precio de adjudicación para la subasta, en la misma unidad que la puja (p. ej., USD o CPM).

Notificación de tiempo agotado

En caso de una puja con tiempo agotado, proporcionamos una ruta de informe alternativa. Es la nurl genérica a la que puede llamarse sin necesidad de esperar que llegue la puja. El formato es el siguiente:

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

Nota:${PARTNER_FBID}, ${APP_FBID} y ${AUCTION_ID} deben completarse con los valores correspondientes. Estos valores se explican en la tabla a continuación.

ParámetroTipoDescripción

PARTNER_FBID

int

Identificador del servidor de subasta de anuncios emitido por Facebook. Utiliza el identificador de la aplicación aquí si no tienes un socio exclusivo para la subasta de anuncios.

APP_FBID

int

Identificador que Facebook emite para la aplicación/la empresa que inició una subasta.

AUCTION_ID

cadena

Identificador de la subasta, generado por el cliente, que se utiliza para emitir una solicitud de puja.

Paso 6: Entregar el ganador a tu lado del cliente

Después de ejecutar la subasta, creamos el objeto de respuesta y lo devolvemos a la app del cliente. Aquí se encuentra el método de ejemplo en bid_manager.py que crea la respuesta final del servidor de subasta:

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

Por último, nuestro servidor de ejemplo puede crear esta respuesta para que el cliente notifique qué plataforma se utilizará:

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