Guia do desenvolvedor para publicidade programática


Cada vez que um anúncio é carregado em uma página, um leilão geralmente é executado primeiro e deve terminar em menos de um segundo. Esse leilão segue um protocolo real, OpenRTB, com um esquema JSON definido para solicitação e resposta. Este é um passo a passo prático para construir um manipulador de lances que fale esse protocolo corretamente: analisando uma solicitação de lance, aplicando lógica de decisão básica e retornando uma resposta válida antes que o leilão expire.

O que o OpenRTB realmente é

OpenRTB é uma especificação aberta mantida pelo Laboratório Técnico IABum órgão de padronização sem fins lucrativos, que define a estrutura JSON que as trocas e os licitantes usam para realizar um leilão de anúncios em tempo real. Em sua essência, é uma troca no estilo REST: uma troca envia uma solicitação POST contendo uma oportunidade de lance, e um licitante tem um curto período para responder com um lance ou recusar. Visão geral do SitePoint sobre o que realmente é uma API REST é uma boa introdução se você nunca construiu uma API JSON de solicitação/resposta antes, já que o OpenRTB segue o mesmo padrão cliente-servidor, sem estado, apenas com um orçamento de latência estrito em camadas.

Uma solicitação de lance mínimo é semelhante a esta:

JSON

{
  "id": "auction-8841",
  "imp": (
    {
      "id": "1",
      "banner": { "w": 300, "h": 250 },
      "bidfloor": 0.50
    }
  ),
  "site": { "domain": "example.com" },
  "tmax": 100
}

O tmax field é a parte que molda todo o resto sobre como esse código precisa ser escrito: é o número de milissegundos que a exchange esperará antes de tratar uma não resposta como uma recusa. Um licitante que ainda está trabalhando quando a janela se fecha simplesmente perdeu o leilão, com resposta ou não.

Construindo o endpoint do licitante

Um licitante é apenas um endpoint HTTP que aceita uma solicitação POST e responde com um lance ou uma resposta vazia. No Node.js, isso começa como uma rota Express simples:

javascript

const express = require('express');
const app = express();
app.use(express.json());

app.post('/bid', (req, res) => {
  const bidRequest = req.body;
  const bidResponse = evaluateBidRequest(bidRequest);

  if (!bidResponse) {
    return res.status(204).end(); 
  }

  res.status(200).json(bidResponse);
});

Um 204 sem corpo é uma resposta válida e significativa neste protocolo, pois informa explicitamente à exchange que esse licitante está recusando, em vez de deixá-la adivinhar se o tempo limite foi uma recusa ou uma falha.

Avaliando a solicitação e construindo uma resposta

A etapa de avaliação é onde reside a lógica de lance real: verificar se a impressão é a desejada, se o preço mínimo é aceitável e calcular um preço de lance, se for o caso.

javascript

function evaluateBidRequest(bidRequest) {
  const imp = bidRequest.imp && bidRequest.imp(0);
  if (!imp || !imp.banner) return null;

  const floor = imp.bidfloor || 0;
  const bidPrice = calculateBidPrice(bidRequest, imp);

  if (bidPrice < floor) return null; 

  return {
    id: bidRequest.id,
    seatbid: (
      {
        bid: (
          {
            id: `bid-${imp.id}`,
            impid: imp.id,
            price: bidPrice,
            adm: '

ad markup here

'
,
crid: 'creative-101', }, ), }, ), }; } function calculateBidPrice(bidRequest, imp) { return (imp.bidfloor || 0) + 0.10; }

Retornando null quando a proposta não consegue atingir o limite mínimo, em vez de enviar uma oferta que você sabe que perderá, mantém o caminho de resposta honesto e evita desperdício de trabalho construindo marcação para uma proposta que não tem chance.

Respeitando o tempo limite

Porque tmax é curto, geralmente bem menos de 200 milissegundos, qualquer chamada externa dentro da etapa de avaliação (uma verificação de orçamento em um banco de dados, uma chamada para um serviço de precificação) precisa de um prazo explícito e obrigatório, e não apenas de uma esperança de que responda rapidamente.

javascript

async function evaluateWithTimeout(bidRequest, budgetMs) {
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), budgetMs);

  try {
    const budgetCheck = await fetch('http://internal-budget-service/check', {
      signal: controller.signal,
    });
    const budget = await budgetCheck.json();
    return budget.remaining > 0 ? evaluateBidRequest(bidRequest) : null;
  } catch (err) {
    return null; 
  } finally {
    clearTimeout(timeout);
  }
}

Guia do SitePoint para o Buscar API em Node.js cobre o AbortController padrão usado acima com mais detalhes, é o mesmo mecanismo usado para cancelar qualquer chamada de busca que esteja demorando muito, aplicado aqui especificamente para evitar que um serviço downstream lento cause um leilão perdido em vez de apenas um lance perdido.

Definir o orçamento interno visivelmente abaixo do orçamento real da bolsa tmaxem vez de tentar usar a janela completa, deixa espaço para o tempo de trânsito da rede no caminho de volta à central, que não está incluído em tmax em si.

Validando o que entra

Uma solicitação de lance é uma entrada externa de uma exchange que você não controla, e cargas malformadas ou inesperadas são comuns o suficiente neste ecossistema para que a validação pertença ao ponto de entrada, e não espalhada pela lógica de lances.

javascript

function isValidBidRequest(body) {
  return (
    body &&
    typeof body.id === 'string' &&
    Array.isArray(body.imp) &&
    body.imp.length > 0
  );
}

app.post('/bid', (req, res) => {
  if (!isValidBidRequest(req.body)) {
    return res.status(400).end();
  }
  
});

Falhar rapidamente em uma solicitação malformada, antes de qualquer lógica de lance ser executada, evita que uma carga ruim de uma exchange desperdice o tempo destinado à avaliação de uma solicitação legítima.

Onde isso se encaixa no ecossistema mais amplo

O lado do licitante deste protocolo é apenas metade da imagem. Do outro lado do leilão estão as agências e os compradores que definem a estratégia, os orçamentos e a segmentação contra os quais um licitante como o acima executa, trabalho que geralmente é descrito como compra de mídia. Uma empresa como Cresça-ME opera no lado da compra, traduzindo o resumo da campanha nos parâmetros de lance e orçamentos que um sistema como este lê. Compreender essa divisão, a lógica de lances em nível de protocolo, por um lado, e as decisões estratégicas de compra, por outro, é um contexto útil para saber de onde realmente vêm os valores de configuração, pisos, regras de segmentação e ritmo de um manipulador de lances em uma configuração de produção.

Perguntas frequentes

Quanto tempo um licitante realmente tem para responder?

É definido pelo tmax campo na solicitação de lance, geralmente na faixa de 100 a 200 milissegundos, embora varie de acordo com a troca. Faça um orçamento significativamente menor do que isso internamente, já que o tempo de trânsito da rede de volta à central não está incluído na janela.

O que um licitante deve fazer se quiser recusar um leilão?

Retorne um HTTP 204 sem corpo. Isso é uma recusa explícita e válida, e é diferente de um tempo limite ou de um erro, que a exchange pode tratar de forma diferente, incluindo a contagem em relação às métricas de confiabilidade do licitante.

Por que validar a solicitação de lance antes de executar qualquer lógica de lance?

As solicitações de lance vêm de bolsas externas que você não controla, e a validação antecipada da estrutura evita que uma carga útil malformada perca tempo que deveria ser gasto na avaliação de oportunidades legítimas dentro de um período muito apertado.

O OpenRTB é o único protocolo usado em publicidade programática?

É o dominante e o que a maioria das exchanges suporta, mas as implementações variam em quais campos opcionais elas enviam, por isso vale a pena verificar a documentação de uma exchange específica em relação à especificação básica do IAB Tech Lab antes de assumir a compatibilidade total.

Resumo

Um licitante OpenRTB é um endpoint REST operando sob um orçamento de latência rígida: analisa a solicitação, valida-a, decide se deve fazer um lance e responde, tudo dentro de uma janela geralmente bem abaixo de 200 milissegundos. Os padrões que tornam isso confiável são os padrões comuns aplicados sob restrições mais rígidas do que o normal, tempos limites explícitos em qualquer chamada externa, validação rápida antes de trabalhos caros e uma resposta de recusa honesta, em vez de uma resposta atrasada ou malformada. Acertar a mecânica do protocolo é o que faz com que a lógica de lances colocada sobre ele, qualquer que seja essa lógica, realmente chegue ao leilão a tempo de ser importante.



Source link