AdWords skripty – univerzální úložiště proměnných

Jakmile si s AdWords skripty začnete trochu hrát, zjistíte, že by se hodilo znát hodnoty proměnných z předešlého běhu skriptu, nebo třeba výsledky skriptu zcela jiného. Dnes vám proto ukážeme snad nejjednodušší možný způsob, jak si udělat univerzální úložiště proměnných, se kterým se vám bude pohodlně pracovat.

 

1. Kdy se ukládání proměnných může hodit

Záleží jen na vaší kreativitě. Pro inspiraci uvádím typické situace, ve kterých ukládání proměnných využívají naše AdWords skripty.

Dopočítání hodinových metrik. Pokud si začnete hrát s optimalizací účtu na úrovni hodin, narazíte na určitá omezení. Denní data jsou málo; potřebujete hodinová. Chcete znát počet zobrazení nebo kliknutí za poslední hodinu? Nebo dopočítat průměrnou pozici nebo průměrnou cenu za poslední hodinu? A podle toho třeba měnit nabídky? Potřebujete znát stav před hodinou.

Zamezení opakovaného posílání emailů. Alarmy jsou tím nejdůležitějším typem skriptu, zejména pokud uvažujete o jakékoliv automatizaci účtu. Hlídají, jestli se něco “nevymklo” kontrole, a pokud ano, pošlou email. Jak ale zamezit tomu, aby se opakovaně neposílalo upozornění na stejný problém? Údaj o tom, že email byl již zaslán, si může skript uložit a při dalším běhu, pokud stejný alarm opět nastane, již email neposlat.

Sdílení výsledků mezi skripty. Používáme specializovaný skript, který v účtu nic nemění, ale běží každou hodinu a dopočítává hodinové metriky, naše vlastní metriky a různé statistiky přes celý účet. Tyto údaje pak používají ostatní skripty, které si je již nemusí počítat. Je to velmi robustní a snadno udržovatelné řešení, které navíc umožňuje opakované nasazení v nových klientských účtech.

Externí zadávání parametrů. Tak to je k nezaplacení. Chcete změnit email, na který posíláte upozornění nebo místo 14-ti denní historie pracovat s 30-ti denní historií? Kvůli tomu přeci nebudete měnit zdrojový kód skriptu. Jednoduše v externím úložišti změníte tyto hodnoty a skript si je již odtud načte a změní své chování.

Logování. Další pecka. Už jste někdy měli v účtu několik skriptů, které běží každou hodinu a pak se snažili dohledat nějaký údaj, který si neposíláte emailem, ale který logujete pomocí funkce Logger.log()? AdWords zatím neumožňuje filtrování skriptů ani prohledávání logů. Dohledávat potom nějakou událost v rozpětí několika dní znamená stovky kliknutí a klidně desítky minut. Klikáte jako šílení, otevíráte log za logem a… Neztrácejme čas, logujme externě, do vlastního archivu. V jednom úložišti pak máte všechny historické logy a během chvilky dohledáte, co se v minulosti událo.

… je toho ještě víc, ale nechám něco na vás :-).

 

2. Jak to celé funguje?

Ideově je to prosté. Stačí mít fyzicky místo, kam lze hodnoty proměnných zapsat a odkud je lze zase načíst. Jak prosté, Watsone. A od toho jsou přeci databáze…

Dobrá zpráva pro začátečníky a mírně pokročilé: dnes se vyhneme databázím, použijeme místo toho Google Sheety; to je takový ten “Google online Excel”.

Dobrá zpráva pro pokročilé a šampiony: pokud jste doufali v nějaké “advanced” ukázky využití služeb JDBC nebo Fusion Tables ve skriptech, nečtěte dál. A zkuste místo skriptů API, také jsme pro rozsáhlejší projekty přesedlali :-).

A proč tedy Sheety? Je to řešení jednoduché, přímočaré a vizuálně snadno kontrolovatelné. Navíc můžete pohodlně přes Sheet měnit parametry svého skriptu – je to tedy zároveň jakési jednoduché uživatelské rozhraní. Je třeba říkat více?

Tak snad už jen ideové schéma, ať víme, jak by to mělo fungovat…

Modrý váleček „SHEET S DATY“, to je naše externí úložiště proměnných a jejich hodnot. Vedle válečku je obdélník – to je náš skript. A ty šipky mezi válečkem a obdélníčkem říkají, že skript si může data z úložiště načíst, a taky je tam zapsat.

V reálu to pak vypadá tak, že ve skriptu ve funkci main() nejdříve zadáme funkci readVar(), která načte všechny proměnné z našeho datového úložiště. Všechny uložené proměnné tak máme k dispozici. Pomocí funkce existsVar(name) pak můžeme ověřit existneci konkrétní proměnné, pomocí funkce getVar(name) získáme její hodnotu a funkce setVar(name, value) buď aktualizuje hodnotu existující proměnné, nebo pokud proměnná neexistuje, vytvoří ji a uloží včetně její hodnoty. Na konci skriptu pak voláme funkci writeVar(), která všechny proměnné zapíše zpět do datového úložiště. Nezbývá tedy než začít programovat.

 

3. Realizace úložiště pomocí pěti funkcí

Nejdříve si vytvořte Google Spreadsheet (to je ten jakoby excelovský soubor) a v něm Sheet (to je list), který pojmenujete “var” tak, jak jest patrno na následujícím obrázku. Navíc zde již vidíte uložené dvě proměnné clicksLastRun a cliksThisHour, ke kterým se dostaneme v malé ukázce v další kapitole.

Nejdříve si ve skriptu vytvoříme globální proměnné. Globální = lze je číst/měnit v každé funkci včetně main(). Definují se mimo funkce, ideálně úplně na začátku skriptu. A my je pro lepší čitelnost kódu píšeme velkými písmeny. Takto:

01: //--> GLOBÁLNÍ PROMĚNNÉ
02: var URL = ""; //zadejte url svého Spreadsheetu
03: var SHEET, PROMENNE, HODNOTY;

A nyní do kódu vložíme 5 funkcí.

readVar() – tato funkce se použije úplně na začátku funkce main(); otevře Sheet (řádek 2) a z něj načte názvy proměnných (řádek 3) a jejich hodnoty (řádek 4). V následujícím cyklu (řádek 5 až 8) jsou již načtené hodnoty převedeny z typu pole na text, aby v nich mohlo být použito vyhledávání pomocí funkce indexOf().

01: function readVar() {
02:   SHEET = SpreadsheetApp.openByUrl(URL).getSheetByName("var"); 
03:   PROMENNE = SHEET.getRange("A1:A"+Math.max(1,SHEET.getLastRow())).getValues();
04:   HODNOTY = SHEET.getRange("B1:B"+Math.max(1,SHEET.getLastRow())).getValues(); 
05:   for (i=0;i<PROMENNE.length;i++) {
06:     PROMENNE[i] = PROMENNE[i].toString();
07:     HODNOTY[i] = HODNOTY[i].toString();
08:   }
09: }

writeVar() – tato funkce se volá na konci funkce main() a slouží k zapsání všech proměnných. Nejdříve jsou proměnné v poli změněny na pole polí (řádek 2 až 5) a následně jsou tyto zapsány do Sheetu (řádek 6 a 7).

01: function writeVar() {
02:   for (i=0;i<PROMENNE.length;i++) {
03:     PROMENNE[i] = [PROMENNE[i]];
04:     HODNOTY[i] = [HODNOTY[i]];
05:   }  
06:   SHEET.getRange("A1:A"+HODNOTY.length).setValues(PROMENNE);
07:   SHEET.getRange("B1:B"+HODNOTY.length).setValues(HODNOTY);
07: }

getVar(name) – umožňuje načíst proměnnou; pokud tato neexistuje, vrátí řetězec s textem “NULL”.
setVar(name,value) – uloží proměnnou s názvem name a hodnotou value; pokud proměnná v Sheetu existuje, pouze změní její hodnotou. Pokud taková proměnná neexistuje, vytvoří ji.
existsVar(name) – pokud proměnná se zadanou hodnotou v Sheetu existuje, vrátí hodnotu true, jinak vrací hodnotu false.

01: function getVar(name) { 
02:   if (existsVar(name)) return HODNOTY[PROMENNE.indexOf(name)];
03:   else return "NULL";
04: }
05: function setVar(name,value) { 
06:   if (existsVar(name))  HODNOTY[PROMENNE.indexOf(name)] = value;
07:   else  {
08:     PROMENNE.push(name);
09:     HODNOTY.push(value);
10:   }
11: }
12: function existsVar(name) {
13:   if (PROMENNE.indexOf(name)<0) return false;
14:   else return true;
15: }

 

4. Ukázka AdWords skriptu – počet kliknutí za poslední hodinu

A jak tedy vypadá elementární skript, který bude zjišťovat počet kliknutí v účtu za poslední hodinu? Například takto:

01: function main() {
02:   readVar();
03: 
04:   var clicksNow = AdWordsApp.currentAccount().getStatsFor("TODAY").getClicks();  
05: 
06:   var clicksLastRun;
07:   if (existsVar("clicksLastRun")) clicksLastRun = getVar("clicksLastRun");
08:   else clicksLastRun = clicksNow;
09: 
10:   var clicksThisHour;
11:   if (clicksNow < clicksLastRun) clicksThisHour = clicksNow;
12:   else clicksThisHour = clicksNow - clicksLastRun;
13: 
14:   setVar("clicksLastRun",clicksNow);
15:   setVar("clicksThisHour",clicksThisHour);
16: 
17:   writeVar();
18: }

Ve skriptu je určité zjednodušení spočívající v tom, že skript nedopočítává počet kliknutí mezi posledním spuštěním před půlnocí a půlnocí. V Sheetu pak uložené proměnné budou vypadat jako na prvním obrázku v tomto článku.

Berte prosím ukázku skriptu jako demonstraci použití výše popsaných funkcí, nikoliv jako hotové řešení, které zkopírujete a přímo někam vložíte. Příklad je sice funkční, takže necháte-li jej spustit každou hodinu, můžete se chodit dívat na počet nově nabytých kliknutí, nicméně zkuste číst ještě dál.

 

5. Některé návrhy na vylepšení

Předložené řešení je prakticky holoverze, ze které nelze skoro nic ubrat. Pokud se ale rozhodnete výpočet hodinových dat implementovat ve vlastním řešení, zvažte např. následující rozšíření.

Datum vytvoření proměnné a poslední změny hodnoty; stojí za zvážení přidat k proměnným ještě dva sloupce s datem vytvoření proměnné a datem poslední změny.

Symbol ‘ na začátku každé uložené hodnoty; máme neblahé zkušenosti s tím, že se Google Sheet někdy snaží rozpoznat typ proměnné a v dobré víře předělá číslo na datum nebo obráceně. Ani přetypování buněk nevede ke spolehlivému řešení. Pokud do buňky zapíšete místo 5.3 například řetězec ‘5.3, bude tento chápán jako text a překvapení s přetypováním by se mělo podařit zažehnat.

Kolize při více současných přístupech; pokud do jednoho Sheetu může zapisovat více skriptů, hrozí situace, kdy první skript data načte, a než skončí a zapíše nové hodnoty, načte a zapíše je skript druhý. Riziko podobného problému takřka eliminuje, pokud si vyhradíte konkrétní buňku k tomu, že jakmile skript potřebuje s daty pracovat, podívá se, jestli je ve vybrané buňce hodnota 0, a pokud ano, přepíše ji na 1 a pracuje dál. Až skončí, přepíše 1 zpět na 0. Pokud však skript po spuštění zjistí, že v buňce už je hodnota 1 (někdo s daty pracuje), počká např. 10 vteřin a pokusí se znovu o načtení. Tak to může zkoušet omezený počet krát, např. 60-krát (10 minut), a pokud je v buňce stále hodnota 1, skript pošle upozornění (emailem), že nemohl být spuštěn, a ukončí se.

A nebo zkuste zcela jiné řešení; cílem bylo ukázat princip, jak lze rozšířit funkcionalitu vašich skriptů. Způsob, kterým tuto možnost uchopíte, je zcela na vás.

 

6. Závěr

Na relativně malém prostoru jsme vám představili mechanismus, kterým můžete naprosto zásadně změnit celé pojetí automatizovaných řešení založených na AdWords skriptech. Pracovat na úrovni hodin místo dnů, na úrovni segmentovaných klíčových slov místo sestav, to je cesta, kterou se ubíráme nejen my a kde je prostor být opět nějaký ten krůček před konkurencí. Zkuste si takové řešení vytvořit sami nebo se obraťte na nás, budeme rádi, pokud ten krůček budeme moci udělat s vámi :-). Přejeme mnoho úspěchů.