Napojení webu na Adneto
Návod je psaný tak, aby podle něj web napojil AI programovací agent (nebo vývojář) bez další pomoci. Postupujte shora dolů.
Adneto doručuje reklamu z backendu. Váš server si stáhne malý manifest ve formátu JSON, uloží ho do cache a reklamu vypíše jako součást vlastního HTML. Prohlížeč návštěvníka se s Adneto nespojí: odkazy, obrázky i měření jdou přes vaši doménu. Žádný JavaScript třetí strany, žádné cookies, žádné identifikátory návštěvníků.
1. Co potřebujete
| Položka | Kde ji vzít |
|---|---|
| Token webu | Adneto → Weby → váš web. Zobrazí se jednou při založení webu; když ho ztratíte, vygenerujte nový. |
| Klíče ploch | Adneto → Weby → váš web → Plochy. Klíč vypadá jako sidebar. |
| Soubor klienta | https://adneto.com/download/client (uloží se jako adneto.php) |
| PHP 8.1+ | Bez povinných rozšíření. cURL se použije, když je k dispozici. |
| Zapisovatelný adresář | Pro cache. Nesmí být dostupný z webu. |
Token je tajemství: držte ho v proměnné prostředí nebo v konfiguračním souboru mimo veřejnou složku (například private/config.php, který vrací pole), nikdy ve veřejném repozitáři. Příklady níže ho čtou přes getenv('SLOTS_TOKEN'); použijte to, čím váš web tajemství už spravuje.
Volby nastavení
Adneto::configure([...]) přijímá:
| Volba | Výchozí | Význam |
|---|---|---|
token |
— | Token webu. Prázdný = klient nedělá nic. |
cache_dir |
— | Zapisovatelný adresář mimo veřejnou složku. |
endpoint |
/go.php |
Adresa na vašem webu, která volá Adneto::handle(). |
api |
https://adneto.com/api/v1 |
Základ API. Měňte jen při testování proti jiné instalaci Adneto. |
timeout |
3 |
Sekundy na jeden požadavek do Adneto. |
params |
['click' => 'r', 'view' => 'v', 'image' => 'm'] |
Názvy parametrů adresy pro prokliky. |
fallback_url |
/ |
Kam vede proklik, jehož reklama už v manifestu není. |
Adneto::refreshNow() stáhne manifest hned a při úspěchu vrátí true. Běžné stránky ji nepotřebují; hodí se pro testy a pro cron, pokud chcete obnovu plánovat.
2. Pravidla, která musí platit
- Neutrální názvy. Adresa, která obsluhuje prokliky, její parametry a třída nebo id každého obalového prvku, který přidáte, nesmí obsahovat slova
ad,ads,banner,sponsor,promoaniadneto(jako celé slovo nebo část oddělenou-či_, napříkladad-boxneboside_banner;paddingneboloadingnevadí). Blokovače reklam takové prvky skrývají. Použijte názvy jako/go.php,/l,tip-box. - Vrácené HTML neupravujte. Vypište ho tak, jak je. Neescapujte ho a neobalujte odkazem.
- Výstup adresy pro prokliky necachujte. Stránky s plochami cachovat můžete jako obvykle.
- Chyba nesmí rozbít stránku.
Adneto::render()při jakémkoli problému vrátí prázdný řetězec; nepřidávejte kolem něj kód, který vyhazuje výjimky.
3. Čisté PHP
Rozložení adresářů (veřejná složka je public/):
private/adneto.php ← klient, mimo veřejnou složku
private/cache/ ← zapisovatelná, mimo veřejnou složku
public/go.php ← adresa pro prokliky (libovolný neutrální název)
public/_slots.php ← společné nastavení, vkládá se tam, kde je potřeba
public/_slots.php:
<?php
require __DIR__.'/../private/adneto.php';
Adneto::configure([
'token' => getenv('SLOTS_TOKEN'), // token webu
'cache_dir' => __DIR__.'/../private/cache',
'endpoint' => '/go.php',
]);
public/go.php:
<?php
require __DIR__.'/_slots.php';
Adneto::handle();
V šabloně, kde má plocha být:
<?php
require_once __DIR__.'/_slots.php';
$tip = Adneto::render('sidebar');
?>
<?php if ($tip !== ''): ?>
<aside class="tip-box"><?= $tip ?></aside>
<?php endif; ?>
Obal se vypíše jen tehdy, když má plocha obsah, takže prázdná plocha nezanechá prázdný rámeček.
Když je _slots.php dostupný přes URL, jen nastaví klienta a nic nevypíše, takže to nevadí. Můžete ho dát i mimo veřejnou složku.
4. Laravel
- Klienta uložte jako
app/Support/adneto.php(nebo kamkoli mimopublic/). - Do
.envaconfig/services.phppřidejte:
SLOTS_TOKEN=token-vaseho-webu
'slots' => ['token' => env('SLOTS_TOKEN')],
- Klienta nastavte jednou, v
AppServiceProvider::boot():
require_once app_path('Support/adneto.php');
\Adneto::configure([
'token' => (string) config('services.slots.token'),
'cache_dir' => storage_path('app/slots'),
'endpoint' => '/l',
]);
- Do
routes/web.phppřidejte routu pro prokliky. Nesmí zakládat session ani nastavovat cookies, proto ji vyjměte ze skupiny middlewareweb:
Route::get('/l', function () {
\Adneto::handle();
exit;
})->withoutMiddleware('web');
- V šabloně Blade (pozor na neescapovaný výpis):
@php($tip = \Adneto::render('sidebar'))
@if ($tip !== '')
<aside class="tip-box">{!! $tip !!}</aside>
@endif
S prázdným tokenem klient nedělá nic, takže lokální vývoj a testy fungují bez nastavení.
5. Jak se to chová
- První požadavek: manifest ještě není, plocha je prázdná. Manifest se stáhne po odeslání odpovědi; plocha se objeví při dalším požadavku.
- Obnova: každých 5–15 minut ji spustí požadavek na stránku a proběhne až po dokončení výstupu stránky. Obnovuje vždy jen jeden požadavek. Pod PHP-FPM na ni návštěvník nečeká vůbec. Pod mod_php nebo vestavěným serverem se stránka odešle jako první, ale ten jeden požadavek zůstane otevřený, dokud obnova neskončí (běžně hluboko pod sekundu, při výpadku nejvýš asi 8 sekund); ostatních požadavků se to netýká.
- Výpadek: když je Adneto nedostupné, používá se poslední stažený manifest. Bez manifestu je plocha prázdná a stránka funguje.
- Prázdná plocha:
render()vrátí''. Pokud má váš obal okraj nebo odsazení, při prázdném výsledku ho skryjte. - Obrázky se stahují do cache a servírují z vaší domény přes adresu pro prokliky.
- Měření: klient počítá vykreslení na serveru, načtení měřicího bodu a prokliky do souboru v cache a při obnově posílá do Adneto hodinové součty. IP adresy ani cookies se neukládají.
- Roboti se nepočítají. Požadavky, jejichž user-agent vypadá jako robot nebo nástroj z příkazové řádky (včetně výchozího user-agenta
curlawgeta prázdného user-agenta), reklamu, obrázek i přesměrování dostanou, ale nezaznamenají se. Při zkoušení měření přes curl posílejte user-agent prohlížeče:curl -A "Mozilla/5.0 Firefox/130.0" …. - Proklik na reklamu, která už v manifestu není (například z nacachované stránky), přesměruje na
fallback_url, ve výchozím nastavení na úvodní stránku.
6. Kontrolní seznam
Proveďte tyto kontroly a u každé uveďte výsledek. U všech požadavků posílejte user-agent prohlížeče (viz „Roboti se nepočítají").
- Adresář cache obsahuje
manifest.jsonpo dvou načteních stránky pár sekund po sobě. - Zdrojový kód stránky obsahuje HTML plochy a každé
hrefasrcv něm míří na vaši doménu. - V HTML plochy a ve vašem obalu neobsahuje žádná hodnota
class,id,hrefanisrcslovaadneto,ads,banner,sponsornebopromoa žádná neobsahujeadjako slovo nebo část oddělenou-či_. Kontrolujte jen hodnoty atributů; text jakopaddingve stylech nebo hash obrázku se nepočítá. - Otevření odkazu z plochy přesměruje (HTTP 302) na adresu zadavatele.
- Odpověď adresy pro prokliky nemá hlavičku
Set-Cookie. - Zkouška výpadku: nastavte
'api' => 'https://invalid.invalid/api/v1', cache nechte a vynuťte obnovu jedním spuštěnímAdneto::refreshNow()z dočasného skriptu, který načte vaše nastavení. Musí vrátitfalse. Pak načtěte stránku: plocha se dál vykreslí z cache. Nastavení vraťte a skript smažte. - Zkouška prázdné cache: nasměrujte
cache_dirna prázdný adresář, nechte neplatnéapia načtěte stránku dvakrát. Stránka se načte, plocha je prázdná a v chybovém logu PHP (nebo v logu vašeho frameworku) nepřibyl žádný záznam. Obě nastavení vraťte. - Do 15 minut ukáže detail webu v Adneto „Naposledy připojen" a po několika zobrazeních s user-agentem prohlížeče i přijaté statistiky.
7. Jiné technologie: API
Když web není v PHP, naprogramujte stejné chování proti API. Základní adresa: https://adneto.com/api/v1. Každý požadavek autentizujte hlavičkou Authorization: Bearer <token webu>.
GET /manifest
Stahujte nejvýš jednou za 5 minut; řiďte se hodnotou ttl (sekundy). Posílejte If-None-Match s posledním ETag; 304 znamená beze změny. Při 401 je token špatně nebo je web pozastavený: nechte si poslední manifest a zkuste to později.
{
"v": 1,
"ttl": 600,
"slots": {
"sidebar": {
"schedule": [
{
"from": 1794351600,
"until": 1794610800,
"items": [
{
"id": 12,
"campaign": 5,
"html": "<span class=\"x1a2b3c4\"><a href=\"{{click}}\">…</a><img src=\"{{pixel}}\" alt=\"\"></span>",
"url": "https://zadavatel.example/stranka",
"images": { "<sha256>": "https://cdn.example/…/<sha256>.webp" }
}
]
}
]
}
}
}
Vykreslení plochy:
- Vyberte úsek rozvrhu, pro který platí
from <= teď < until(unixové sekundy). Bez úseku nebo bez položek je plocha prázdná. - Vyberte náhodně jednu položku.
- V
htmlnahraďte{{click}}adresou na vaší doméně, která přesměruje naurl,{{pixel}}adresou na vaší doméně, která vrátí GIF 1×1 sCache-Control: no-store, a každé{{img:<sha256>}}adresou na vaší doméně, která servíruje obrázek z cache. Vkládané adresy escapujte pro HTML. - Každý obrázek stáhněte jednou, ověřte, že SHA-256 obsahu odpovídá klíči, a servírujte ho s dlouhou dobou cache.
- Položku, jejíž
htmlobsahuje<script, atributon…=nebojavascript:, zahoďte. - Adresa prokliku musí určit plochu, kampaň a kreativu a
urldohledat v manifestu. Nikdy nepřesměrovávejte na adresu převzatou z požadavku.
POST /stats
Počty posílejte při obnově manifestu. Řádek je jedna plocha, kampaň, kreativa a hodina.
{
"batch": "32 malých hexadecimálních znaků, pro každou dávku jiných",
"rows": [
{ "hour": 1794391200, "slot": "sidebar", "campaign": 5, "creative": 12, "renders": 120, "views": 100, "clicks": 4 }
]
}
hourje unixový čas začátku hodiny (UTC).renders= vykreslení na serveru,views= načtení měřicího bodu,clicks= přesměrování.2xxznamená přijato; opakovanábatchse potvrdí a nezapočítá dvakrát, takže po chybě sítě pošlete stejnou dávku znovu.422znamená vadnou dávku: zahoďte ji.- Požadavky robotů nepočítejte. Neukládejte ani neposílejte nic, co identifikuje návštěvníka.