Saltar para o conteúdo principal
Depois de executar um leilão de listings, você frequentemente desejará combinar os vencedores com resultados orgânicos. Por exemplo, suponha que você esteja construindo uma seção de categoria de uma loja web que também exibirá uma série de produtos patrocinados. Você precisará de uma forma de “injetar” seus vencedores de leilão nos resultados de categoria regulares. Esta página mostra as etapas envolvidas na construção de tal seção de categoria, mas considerações similares se aplicam a outras páginas ou widgets.

Cenário

A seção de categoria precisa suportar paginação e exibir 3 produtos por página. Se possível, o primeiro produto em cada página será um produto patrocinado. Os produtos nesta página de categoria têm a seguinte estrutura:
{
  "id": "sku-367",
  "categoryId": "Shoes",
  "name": "Running shoes",
  "image": "photo_123.jpg",
  "description": "Beautiful and fast running shoes",
  "resolvedBidId": null
}
O resolvedBidId é null quando o produto não está promovido e contém um ID de string quando está. Nosso objetivo é ter o código pseudo em vigor para um endpoint que possa criar listas de tais produtos.

1. Consultar seus resultados orgânicos

O primeiro passo será consultar seus resultados orgânicos. Os produtos que devem ser exibidos para uma página e categoria específicas. O código para fazer isso pode se parecer com isto:
const pageSize = 3;
let products = queryProductsInCategory(pageSize, cursor, categoryId);

console.log(products);
Digamos que executamos este código para a primeira página da categoria Shoes, e há 3 ou mais produtos disponíveis nesta categoria. Este código então geraria algo similar a isto:
[
  {
    "id": "sku-367",
    "categoryId": "Shoes",
    "name": "Running shoes",
    "image": "photo_123.jpg",
    "description": "Beautiful and fast running shoes"
  },
  {
    "id": "sku-897",
    "categoryId": "Shoes",
    "name": "Slippers",
    "image": "slippers.jpg",
    "description": "A pair of comfortable slippers"
  },
  {
    "id": "sku-343",
    "categoryId": "Shoes",
    "name": "Dress shoes",
    "image": "dress_shoe_original.jpg",
    "description": "Elegant dress shoes for formal events"
  }
]
Observe que esses produtos ainda não têm o campo resolvedBidId, vamos adicioná-lo.
const pageSize = 3;
let products = queryProductsInCategory(pageSize, cursor, categoryId);
products.forEach((prod) => {
  prod.resolvedBidId = null;
});
Agora, precisamos considerar o que acontece se não houver resultados orgânicos para esta página e categoria. Provavelmente queremos retornar um erro 404 e não executar nenhum leilão. Isso nos dá o seguinte código:
const pageSize = 3;
let products = queryProductsInCategory(pageSize, cursor, categoryId);
if (products.length === 0) {
  throw new NotFoundError("no products found");
}

products.forEach((prod) => {
  prod.resolvedBidId = null;
});
Com este tratamento de erros em vigor, estamos prontos para executar um leilão.

2. Executar um leilão

Em nosso cenário, queremos executar um leilão para um único slot:
// skip earlier code...

const slots = 1;
const winners = runAuctionForCategory(slots, categoryId);

console.log(winners);
Não tem certeza de como executar um leilão para uma categoria? Consulte estes exemplos.
Se houver vencedores, a saída do código acima seria algo assim:
[
  {
    "rank": 1,
    "type": "product",
    "id": "sku-444",
    "resolvedBidId": "WyJiX01mazE1IiwiMTJhNTU4MjgtOGVhZC00Mjk5LTgzMjctY2ViYjAwMmEwZmE4IiwibGlzdGluZ3MiLCJkZWZhdWx0IiwiIl0="
  }
]
Se você observar os vencedores, verá que eles não contêm dados de produtos, apenas um monte de IDs. Precisaremos consultar os dados do produto para esses vencedores. Além disso, é possível que não haja vencedores. Pode simplesmente ser que não haja campanhas ativas adequadas para este leilão, mas há muitas outras razões potenciais. Independentemente, precisamos levar em conta este caso e simplesmente retornaremos os resultados orgânicos disponíveis em products.
// skip earlier code...

const slots = 1;
const winners = runAuctionForCategory(slots, categoryId);
if (winners.length === 0) {
  return products;
}

3. Consultar dados de produtos para vencedores

Agora, quando há vencedores. Precisamos consultar os dados do produto para eles.
// skip earlier code...

const ids = winners.map((x) => x.id);
const promoProducts = queryProductsByIds(ids);

console.log(promoProducts);
Seguindo com nossos exemplos anteriores, isso pode registrar algo como:
[
  {
    "id": "sku-444",
    "categoryId": "Shoes",
    "name": "Wooden clogs",
    "image": "clogs.jpg",
    "description": "Original wooden clogs."
  }
]
Novamente, precisamos adicionar o resolvedBidId para completar esses dados. Mas, desta vez não devemos configurá-lo como null, porque agora estamos tratando de produtos promovidos. Se assumirmos que queryProductsByIds retornará produtos na mesma ordem que os ids fornecidos, podemos adicionar os IDs de lance da seguinte forma:
// skip earlier code...

const ids = winners.map((x) => x.id);
const promoProducts = queryProductsByIds(ids);
promoProducts.forEach((prod, i) => {
  prod.resolvedBidId = winners[i].resolvedBidId;
});
Por que este ID de lance é necessário? O ID de lance é vital para permitir que o Topsort atribua eventos a lances e campanhas.
Agora tudo o que resta é fundir nossos produtos promovidos com os resultados orgânicos.

4. Fundir

Queremos exibir os produtos promovidos no início da lista. Para conseguir isso, precisaremos antepor os promoProducts aos products. No entanto, isso pode fazer com que products tenha mais elementos do que nosso tamanho de página pretendido de 3. Portanto, precisamos dividi-lo para permanecer neste tamanho de página.
// skip earlier code...

products.unshift(...promoProducts);
return products.slice(0, pageSize);
Agora nosso código retorna no máximo 3 produtos, dos quais o primeiro produto pode ser um produto patrocinado.

Código completo

// query for organic products.
const pageSize = 3;
let products = queryProductsInCategory(pageSize, cursor, categoryId);
if (products.length === 0) {
  throw new NotFoundError("no products found");
}

products.forEach((prod) => {
  prod.resolvedBidId = null;
});

// run an auction.
const slots = 1;
const winners = runAuctionForCategory(slots, categoryId);
if (winners.length === 0) {
  return products;
}

// query product data for winners.
const ids = winners.map((x) => x.id);
const promoProducts = queryProductsByIds(ids);
promoProducts.forEach((prod, i) => {
  prod.resolvedBidId = winners[i].resolvedBidId;
});

// merge results.
products.unshift(...promoProducts);
return products.slice(0, pageSize);