Előzmény
Egy szép nyáron napon volt pár e-mail a Gmail fiókomban, amikkel csak 1 hét múlva kellett volna valamit kezdenem, és zavart, hogy ennek ellenére minden nap ott néznek rám. Egy kis guglizással rátaláltam erre:http://lifehacker.com/5825634/how-to-add-a-snooze-button-to-gmail-no-extensions-required
Már a cikk címe felkeltette a érdeklődésem, mert elképzelésem nem volt, hogy hogyan lehetséges ez bármiféle kiterjesztés vagy harmadik félnek történő jelszókiadás nélkül.
Lehetséges, és a varázslat része a dolognak a Google Scripts, ami lehetővé teszi számunkra, hogy minden nap megadott időben lefutó javascript nyelvű felhőben tárolt scripteket írjunk, amik nagyon kényelmes javascriptes api-n hozzáférhetnek Google szolgáltatásainkhoz, mint például a Gmailhez vagy a Docs-hoz.
Ennek a scriptnek a kódjáról nem fogok beszélni. Ha érdekel, akkor megtalálod az eredeti linken.
Kényszer
Aztán jött a kényszer, hogy valamire használnom kell ezt a Google Script-et a Gmail Snooze-on felül.. Itt jött az ötlet, hogy milyen király(?) lenne, ha láthatnám a banki egyenlegem alakulását egy grafikonon Google Docsban.Kérés
Az OTP biztosít egy a normál netbanktól független felületet, ahol a telekóddal és kártyaszámmal le lehet kérdezni az aktuális egyenleget. A telekód alapból a számlaszám utolsó 3 számjegye. Ez a felület az OTPdirekt belépés gomb alatt található jelenleg:Direkt link az OTP egyenleglekérdezés leírására
Itt a kártyaszám és a telekód megadása utána megkaphatjuk az aktuális egyenlegünk:
Hm… Ezt a lekérdezést szeretnénk valahogy automatizálni.
Nézzük meg az űrlapot, ami beküldünk:
(Chrome-ban dolgozom.)
Katt az “Elem megtekintésére”.
Ekkor a Chrome feldobja az Elements Panel-t:
A method=”post”-ból láthatjuk, hogy ez egy POST kérés lesz. A kérésben a következő mezők fognak utazni:
muvelet
azonosito
telekod
honlapAzonosito
azonositoxx
telekodxx
Ezekből mi csak kettőnek állítjuk az értékét, és értelemszerűen ezek az azonositoxx és telekodxx. A többit alapértéken hagyjuk.
Valójában ha jobban megnézzük, akkor tévedtem, mert az azonositoxx és a telekodxx az beküldéskor üres lesz az onsubmit eseménykezelő hatására, és a tartalmuk átíródik a rejtett azonosito es telekod mezőkbe. (Ezt azért csinálták, mert nem akarták, hogy a böngésző felajánlhassa a jelszó elmentését, valamint így a Vissza gomb megnyomása után a böngésző nem tudja visszaállítani a kitöltött állapotát az űrlapnak.)
Eddig feltételezésink helyességéről meggyőződhetünk, ha elkezdjük figyelni az oldal forgalmát a Network fülön, és beküldünk egy kérést.
Ehhez váltsunk át a Network fülre (Az Elements fültől 2-vel jobbra.), és aztán a szokványos módon küldjük be az űrlapot. Ezután kattintsuk rá a “bankkartyaEgyenlegLekerdezes” kérésre, és keressük a Form Data részt.
Úgy tűnik, hogy mindent helyesen láttunk.
Kipróbálhatjuk mondjuk wget-el (opcionális):
wget https://www.otpbankdirekt.hu/homebank/do/bankkartyaEgyenlegLekerdezes -O - --post-data "muvelet=login&azonosito=██████████&telekod=███&honlapAzonosito=Default.User&azonositoxx=&telekodxx="
(Ez a parancs egy sor.)
Ha minden jól sikerült, akkor a wget hatására láthatjuk a lekérdezés eredményét egy csomó html kód közt.
Megvan, hogy hogyan tudjuk lekérdezni. Akkor most ebből valahogy Google Script-et kéne csinálni.
Script
Hozzunk létre egy új Google Táblázatot, nyissuk meg, és az Eszközök menüből válasszuk ki a Script szerkesztőt. Ekkor kapunk egy nagyon segítőkész ablakot, amit csukjunk is be.Ekkor ezt kell látnunk:
A kis “Play” gombbal lefuttathatjuk a myFuncton-t, ami jelenleg nem csinál semmit. (Ekkor el kell mentenünk a Project-et. Mentsük tetszőleges néven.)
Csináljunk valami extravangásabbat:
Mikor ezt lefuttatjuk, akkor első pillantásra nem történik semmi, pedig valójában megjelent egy üzenetablak, de nem ott ahol vártuk, hanem az eredeti dokumentumban:
Az elérhető API-kat itt találod: https://developers.google.com/apps-script/defaultservices
Például megtalálhatjuk a UrlFetchApp.fetch metódust, ami jó szolgálatot fog nekünk tenni. Ezzel fogjuk lekérni az egyenlegünket.
A korábban összehozott lekérés és a dokumentáció alapján a következő kódot állítjuk elő:
Ez ugyanaz a lekérés, ami korábban kipróbáltunk. Próbáljuk ki itt is:
… és az eredmény:
A lekérés a title alapján működni látszik….. Már csak valahogy ki kéne nyerni belőle a lényeget. Html-ből infót kinyerni nem szép, de hasznos.
A következő buta, de működő megoldást választottam: Az első <span class="value"><strong> és </strong> közötti cucc érdekel minket:
var egyenleg = response.getContentText().split('<span class="value"><strong>')[1].split("</strong>")[0];
Valamint még a pontot is kéne kapni belőle, mert számot szeretnénk:
var egyenleg = response.getContentText().split('<span class="value"><strong>')[1].split("</strong>")[0].replace(".","");
Így a következő tesztelhető kódhoz jutunk:
… amit ha lefuttatunk, akkor most már ténylegesen az egyenlegünket kapjuk a dobozba:
Ez szép és jó, de mi grafikont szeretnénk.
A grafikonhoz először meg lennie az adatnak táblázatosan. Mondjuk így:
Ezután kijelöljük az A és B oszlopot egyszerre, és hozzáadunk a dokumentumhoz egy vonaldiagramot. Azon kicsit állítgatunk, és akkor valami ilyesmit kaphatunk:
Azért volt fontos az egész A és B oszlopot kijelölni, mert így ha egy új sorba beleírunk valamit, akkor így az is felkerül a diagramra, és így akkor most már tényleg csak az a magic kell, ami minden nap hozzáad egy új sort ehhez a táblázathoz a megfelelő értékekkel.
Az eddig elkészült függvényünket alakítsuk át egy segédfüggvénnyé, ami az egyenleggel tér vissza visszatérési értékként. Ehhez egyszerűen cseréljük le az msgBox-os sort erre:
return egyenleg;
Ezután írjuk meg a következő függvényt, ami hozzáadja a megfelelő értékekkel rendelkező új sort:
Láthatjuk, hogy ez felhasználja korábban megírt getOtpEgyenleg függvényünket.
Az “otp-egyenleg” a munkalap neve. Ez neked lehet, hogy más.
A dátumot azért ilyenre formázom, mert (többek közt?) ezt ismeri fel a Docs dátumnak.
Ha ezt a függvényt lefuttatjuk a kis Play gombbal, akkor láthatjuk, hogy hozzáadódik egy új sor a táblázathoz, és a diagram is frissül.
Egyetlen lépés van már csak hátra: Beállítani, hogy minden este automatikusan lekérje az aktuális egyenleget:
Resources menü → Current script’s triggers → és ott adjuk hozzá a következő sort:
Mentsük, és ezzel készen is vagyunk. Minden éjjel magától frissülni fog a táblázatunk. :)
Yéy!
A kód másolható formában
function getOtpEgyenleg() {
var url = "https://www.otpbankdirekt.hu/homebank/do/bankkartyaEgyenlegLekerdezes";
var payload =
{
"muvelet" : "login",
"azonosito" : "██████████",
"telekod" : "███",
"honlapAzonosito" : "Default.User",
"azonositoxx" : "",
"telekodxx" : ""
};
var options =
{
"method" : "post",
"payload" : payload
};
var response = UrlFetchApp.fetch(url, options);
var egyenleg = response.getContentText().split('<span class="value"><strong>')[1].split("</strong>")[0].replace(".","");
return egyenleg;
}
function updateSpreadSheetWithNewRow() {
var egyenleg = getOtpEgyenleg();
var date = Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd");
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("otp-egyenleg");
sheet.appendRow([date, egyenleg]);
}
Még egy kis kiegészítés (aktuális egyenleg)
Néha jó lenne rögtön itt látni az aktuális egyenleget (nem csak a tegnap estit).
Erre csináltam egy függvényt, ami beírja azt egy cellába, és létrehoztam egy trigger-t, ami a doksi megnyitásánál lefuttatja.
function updateSpreadWithCurrentBalance(){ var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss.getSheetByName("otp-egyenleg"); sheet.getRange("E2").setValue("Updating..."); SpreadsheetApp.flush(); var egyenleg = getOtpEgyenleg(); sheet.getRange("E2").setValue(egyenleg); }
…és a trigger: