Callback funkce

Callback je metoda, kterou prohlížeč zavolá poté, co obdrží odezvu z SSP serveru. Cílem je vykreslení reklamy do webové stránky a zajištění správného měření impresí. V nejjednodušší verzi má callback funkce dva parametryadvert – objekt obsahující informace o reklamě – a data – objekt s definicí zóny.


function callback (advert, data) {
  advert = {
    // odpoved ze serveru
    data: "kod banneru"
    type: "typ",
    width: 970,
    height: 310,
    dsp: "ADVERT",
    responsive: 0,
    iframe: 0,
    ...
  }

  data = {
    // definice pozice ze stranky
    zoneId: 123456
    id: "leader",
    width: 970,
    height: 310,
    ...
  }
}

Při výdeji reklamy s využitím dat v JSONu je nezbytné, aby callbacková funkce na partnerském webu zajistila správné hitování měřicích pixelů pro zaznamenání imprese, viditelné imprese nebo nezobrazení reklamy dle definice IAB, které v případě typu Iframe provádí výdejový JavaScript automaticky. Pokud by měření neprobíhalo správně, případně vůbec, nebylo by možné spočítat výši provize partnera a výdej do příslušných zón by se zablokoval.

Měření imprese a nevydání reklamy

Po provedení JavaScriptu, který má v callbacku za úkol vykreslit reklamu do stránky, zavolejte funkci sssp.served(ads.tracking.served). Ta zajistí zaznamenání imprese (impress), resp. nevydání reklamy (miss) do reklamního systému.

Pokud položka ads.data obsahuje hodnotu empty, nebo hodnotu error, znamená to, že systém reklamu nedodal. Tomu je potřeba přizpůsobit další kroky – například opakovat požadavek, vykkreslit reklamu z jiného systému, nebo plochu pro reklamu skrýt, pokud byla na stránce předem vyhrazena. Přehled chybových hlášek, z nichž právě jedna se bude v případě chyby nacházet v položce ads.dbgInfo.error, a jejich bližší popis jsou k dispozici v dokumentaci odezev SPP.

Měření viditelné imprese

Podle standardu IAB se za viditelnou impresi považuje takové zobrazení reklamy, kdy je v okně prohlížeče viditelných alespoň 50 % reklamní plochy po dobu delší než 1 sekunda.

Měření visibilní imprese je součástí funkce sssp.served(), není tedy nutné volat žádnou speciální funkci. Je však nezbytné, aby byl v požadavku na vydání reklamy uvedený parametr id a jeho hodnota (i při použití vlastního callbacku je kvůli měření nutné identifikovat element s reklamou).

Při neuvedení parametru id je třeba provést vlastní měření viditelné imprese (podle standardu IAB) – URL měřicího pixelu je v poli ads.tracking.visible.

Výdejový skript Seznam SSP obsahuje jak veřejné, tak privátní funkce, jejichž název začíná prefixem _ (podtržítkem). Důrazně varujeme před použitím privátních funkcí ve vašich JS – mohou být kdykoli bez náhrady a předchozího upozornění z výdejového skriptu odstraněny, přejmenovány nebo upravena jejich funkcionalita, vstupní parametry či výstupní hodnoty. Jejich použitím se vystavujete riziku, že se reklama na vašich webech přestane vydávat, nebo výdej nebude probíhat korektně (nefunkční cílení, měření a podobně). Odpovědnost za škody vzniklé v souvislosti s privátními funkcemi Seznam SSP dopadá plně na partnera, který je na svém webu použije.

Příklad callback funkce pro vykreslení textové reklamy „pod článkem“


(function () {
  /**
   * Konfigruace volání SSP
   */
  var config = {
    zoneId: 124852,
    id: "ssp-zone-124852",
    width: 480,
    height: 300,
    callback: handleResponse
  };

  /**
   * Zavoláme si reklamu
   */
  sssp.getAds(config);

  /**
   *  Zpracujeme výsledek volání
   */
  function handleResponse(advert, data) {
    // Ošetříme prázdnou odpověď
    if (advert.type === "empty" || advert.type === "error") {
      // Zpracujeme error, pro náš příklad vypíšeme pouze text do konzole.
      console.log("Nevydala se žádná reklama!");

      // Zaznamenáme "served" miss
      sssp.served(advert.tracking.served);

      return;
    }

    // Vykresíme reklamu
    renderAd(advert);
  }

  /**
   * Vykreslíme reklamu
   */
  function renderAd(advert) {
    // Vyparsujeme data
    var data = JSON.parse(advert.data.trim());

    // Získáme URL stránky s informacemi o vydané reklamě
    var adInfoUrl = advert.adInfoUrl;

    // Element, do kterého se vykreslí reklama
    var el = document.getElementById(config.id);

    // Nastavíme velikost elementu
    el.style.width = config.width + "px";
    el.style.height = config.height + "px";

    // Zjistíme typ reklamy podle první položky
    var adType = data.ads[0].adType;

    // Vykreslíme reklamu podle typu
    if(adType === "COMBINED") {
      renderCombined(el, data, adInfoUrl)
    }

    if(adType === "DRTG") {
      renderDRTG(el, data, adInfoUrl)
    }

    // Zaznamenáme "served" impress
    sssp.served(advert.tracking.served);
  }

  /**
   * Vykreslíme "DRTG" reklamu
   */
  function renderDRTG(el, data, adInfoUrl) {
    data.ads.forEach(function(ad) {
      if(ad.adType !== "SHOP") {
        // Vytvoříme elementy
        var item = document.createElement("a");
        var item_inner = document.createElement("div");
        var image_wrapper = document.createElement("div");
        var image = document.createElement("img");
        var content = document.createElement("div");
        var title = document.createElement("h2");
        var price = document.createElement("p");

        // Nastavíme atributy
        item.setAttribute("class", "ad-item");
        item.setAttribute("href", ad.clickUrl);
        item_inner.setAttribute("class", "ad-item__inner");
        image_wrapper.setAttribute("class", "inner_item__image");
        image.setAttribute("src", ad.imageUrl);
        content.setAttribute("class", "inner_item__content");
        price.setAttribute("class", "content_item__price");

        // Naplníme daty
        title.innerText = ad.title;
        price.innerText = ad.price;

        // Sestavíme
        item.appendChild(item_inner);
        item_inner.appendChild(image_wrapper);
        image_wrapper.appendChild(image);
        item_inner.appendChild(content);
        content.appendChild(title);
        content.appendChild(price);

        //Vykreslíme položku
        el.appendChild(item);

      } else {

        // Přidáme datail obchodu ke každé položce
        var items = el.querySelectorAll('.inner_item__content');
        items.forEach(function (item) {
          var a = document.createElement("a");
          a.innerText = ad.shopName.toLowerCase();
          item.appendChild(a);
        })
      }
    });

    // Vykreslíme označení reklamy
    var label = adLabel(adInfoUrl);
    el.appendChild(label);
  }

  /**
   * Vykreslíme "COMBINED" reklamu
   */
  function renderCombined(el, data, adInfoUrl) {
    data.ads.forEach(function(ad) {
      // Vytvoříme elementy
      var item = document.createElement("a");
      var item_inner = document.createElement("div");
      var image_wrapper = document.createElement("div");
      var image = document.createElement("img");
      var content = document.createElement("div");
      var longHeadline = document.createElement("h2");
      var visibleUrl = document.createElement("a");

      // Nastavíme atributy
      item.setAttribute("class", "ad-item");
      item.setAttribute("href", ad.clickUrl);
      item_inner.setAttribute("class", "ad-item__inner");
      image_wrapper.setAttribute("class", "inner_item__image");
      image.setAttribute("src", ad.adSquareImageUrl);
      content.setAttribute("class", "inner_item__content");

      // Naplníme daty
      longHeadline.innerText = ad.longHeadline;
      visibleUrl.innerText = ad.visibleUrl;

      // Sestavíme
      item.appendChild(item_inner);
      item_inner.appendChild(image_wrapper);
      image_wrapper.appendChild(image);
      item_inner.appendChild(content);
      content.appendChild(longHeadline);
      content.appendChild(visibleUrl);

      //Vykreslíme položku
      el.appendChild(item);
    });

    // Vykreslíme označení reklamy
    var label = adLabel(adInfoUrl);
    el.appendChild(label);
  }

  /**
   * Sestaví označení „Reklama“
   */
  function adLabel(adInfoUrl) {
    var div = document.createElement("div");
    var a = document.createElement("a");

    div.setAttribute("class","ad-label");
    a.setAttribute("href", adInfoUrl);
    a.setAttribute("target","top");

    a.innerText = "Reklama";
    div.appendChild(a);

    return div;
  }
})();

img {
    width: 100%;
    height: auto;
}

h2 {
    color: #CC0000;
    font-family: sans-serif;
    margin: 0 0 5px 0;
    font-size: 18px;
}

p, a {
    color: #333;
    text-decoration: none;
    font-family: sans-serif;
    margin: 0 0 5px 0;
}

a:hover {
    text-decoration: underline;
    cursor: pointer;
}

#ssp-zone-124852 {
    position: relative;
    display: grid;
    flex-direction: column;
}

.ad-item {
    display: flex;
    flex-direction: column;
    justify-content: center;
    position: relative;
}

.ad-item__inner {
    display: flex;
    padding: 0 15px;