Välihuudot?
Eduskunnassa on jo ammoisista ajoista ollut vallalla kulttuuri, jossa huudellaan keskustelun lomassa välihuutoja. Nämä välihuudot kirjautuvat eduskunnan täysistuntojen pöytäkirjoihin hakasulkeisiin, joten ne on suhteellisen helppo poimia koneellisesti talteen.

Olen seurannut politiikkaa niin kauan kuin muistan. Meillä oli jo lapsuudessa äidin kanssa tapana lukea hesari joka aamu ja käydä siitä keskustelua. Yksi intohimoistani on ollut euroopan integraatio. Ylä-asteella kahdeksannen luokan historian tutkielma-aiheet pyörivät usein joko antiikin Kreikan tai kolmannen valtakunnan tyyppisissä suosituissa aiheissa. Itse uin jo tuolloin vastavirtaan, sillä halusin tehdä tutkielman otsikolla “Euroopan Integraation Historia”. Sain naputella tutkielman äidin työhuoneella ihan tietokoneella ja parasta oli Jean Monnetin kuvan saaminen värikopiona mukaan. Niin lapset, 90-luvulla ei ollut joka kodissa tietokoneita, vaan niitä käyttääkseen piti hakeutua paikkoihin, joissa niitä oli, esmes “Internetkahvilaan” tahi juurikin jonkun sukulaisen työpaikalle. Kyseisen tutkielman teosta teki vielä vähän dramaattisempaa se, että olin 38 asteen kuumeessa jonkun syysflunssan kourissa. Eniveis, tästä muistelosta tulee varmaan selväksi ainakin se, että politiikka on ollut aina lähellä sydäntä, vaikka en vielä olekaan löytänyt puolueidentieettiäni yhdestäkään puolueesta.
Avoin data ja kansalaisjournalismi ovat mielestäni olleet yksi kulmakivi nykydemokratiallemme. Yksi tällaisista avoimuuden teoista, on se, että Eduskunta julkaisee kaikkien täysistuntojen pöytäkirjat avoimesti verkossa sekä näiden päivityksestä rss-feediä. Täysistunnot myös striimataan nettiin, joten ainakaan tiedon puutteesta ei voi syyttää, jos ei pysy kärryillä.
Harvalla meistä on kuitenkaan aikaa tai viitseliäisyyttä käydä kaivelemassa yksittäisiä pöytäkirjoja kaiken muun ruuhkavuosielämän timmellyksessä. Tämänkin takia poliittinen satiiri ja aktiiviset poliittiset twiittaajat ovat tärkeitä. Ajatus välihuutobotille syntyi työpaikkamme epävirallisessa virtuaalisessa politiikkakeskustelussa, jossa taivasteltiin Al-Holi -keskustelun tasoa (sakeaa) ja erityisesti välihuutoja. Tuostapa syntyikin ajatus, että mitäs jos niitä välihuutoja huudettaisiin Twitterissä myös twiittien väliin. Tarvittaisiin siis vain botti, joka hakee pöytäkirjan, kaivaa sieltä välihuudot ja twiittailee niitä sopivin väliajoin keskustelun sekaan. Atk-mielessä kyseessä ei ole kovin vaikea ongelma, vaikka uusimpia välihuutoja ei helposti valmiista apista saakaan haettua.
Eduskunnan sivuilla on myös haku, jonka kautta voi hakea vaikka äänestystuloksia. Kovin koherentisti en ole onnistunut saamaan tuosta hausta ulos vaikkapa “uusin äänestys”-tyyppisesti dataa. Valitsen tuosta dropdownista minkä tahansa vaihtoehdon, äänestystulokset ovat ja pysyvät samassa järjestyksessä:

Hienoa joka tapauksessa, että pöytäkirjat, mietinnöt ja äänestystuloksetkin ovat saatavilla, varmaan tuo hakukin tuosta vielä paranee aikojen saatossa.
TwitterBoteista
Twitter tarjoaa kehittäjille apin, jolla voi rest-rajapinnan kautta toimia twittertilinsä kanssa. Yksinkertaistettuna prosessi menee näin:
- Luo twittertili botillesi eli ihan twitter.com ja sieltä luot tilin.
- Hanki itsellesi developer-tili eli anot developer accounttia. Lomakkeella kysellään, mihin accounttia käytät jne. Huomioi, että hyväksynnässä saattaa mennä aikaa, itse jouduin muutamaan otteeseen perustelemaan, mitä tämä botti tekee. Twitterissä suhtaudutaan poliittiseen mainontaan nihkeästi, joten oli hieman vaikea selostaa, mitä nämä kansanedustajien välihuudot ovat ja miksi niiden twiittaaminen on vaan hauskaa viihdettä. Sitten kun hakemuksesi on hyväksytty, saat twitteriltä vastauksen, jossa kredentiaalit, joilla twiittaaminen onnistuu.
- Toteuta ohjelma, joka lähettää haluamasi sisältöä POST-kutsuna twitterin apiin käyttäen saamiasi kredentiaaleja.
Twitterbottien luomiseen löytyy useita tutoriaaleja. Tässä on melko hyvin selitetty seikkaperäisesti kuvineen vaiheet.
Kohta 2 on hieman tyhmä siinä mielessä, että kun olet kerran hankkinut developer accountin, voisi kuvitella, että voit sen jälkeen sillä accountilla luoda useita botteja, jotka tweettaavat eri tileiltä. Valitettavasti kuitenkin twitter tili ja developer kredentiaalit ovat sidottuja toisiinsa, joten tarvitset joka botille oman developer accountin. Pöhköä.
Clojure ja botin logiikka
Koodit ovat vapaasti käytettävissä ja löytyvät githubista.
Botin logiikka riippuu siitä, ollaanko täysistuntokaudella, jolloin käydään kurkkimassa, josko uusia pöytäkirjoja olisi ilmestynyt, vaiko istuntotauolla, jolloin twiitataan uusintana edellisen kauden huutoja.
Istuntokaudella logiikka toimii näin:
- Käy katsomassa, onko edelliseen pöytäkirjaan verrattuna löytynyt uudempia.
- Mikäli uusia pöytäkirjoja on löytynyt, hae pöytäkirja ja käy se läpi välihuutojen varalta.
- Twiittaa välihuudot tasaisin väliajoin jaoteltuna seuraavan 10h ajalle (eli jos vain kaksi huutoa, twiitataan ne viiden tunnin välein.
Koodina sama.
- Onko uudempia pöytäkirjoja ilmestynyt:
(defn get-from-rss-by-version
"Checks the state of tweets from db and if new memos exists, tweets from them"
[latest-versio year]
(let [feed (feedme/parse (:rss-url config))
memo-start (format "%s%s/%s%s" "PTK " (inc latest-versio) year " vp")
filtered-match (filter #(= (:title %) memo-start) (:entries feed))]
(if (not-empty filtered-match)
(let [huudettu (text-handling/get-huudettu-date (first filtered-match))
info {:huudettu huudettu :memo-version (str (inc latest-versio))}
valihuudot (text-handling/get-valihuudot (:title (first
filtered-match)))]
(do
(log/info "Found new huutos, tweeting them now.")
(tweeting/tweet (:valihuudot valihuudot)
(assoc info :memo-url (:memo-url valihuudot)))))
(log/info "No new tweets"))))
2. Tekstinkäsittelyyn eli pöytäkirjojen lataamiseen ja parsimiseen on oma namespacensa. Pöytäkirjat olisi saatavilla ihan html-sivuina, mutta koska ne sisältävät alasivuja määrän, jota ei kauhean helposti saa analysoitua, totesin, että helpointa on vaan ladata koko pöytäkirja pdf:nä ja hakea huudot siitä. Pdf-käsittelyyn on tietenkin olemassa oma kirjastonsa, jolla saa luettua pdf:n tekstin sisään.
Varsinaiset välihuudot saadaan kaivettua sitten hakasulkeiden seasta ja lopuksi poistetaan turhat huudot, kuten “Puhemies koputtaa”. Tämä siksi, että twitter-api ei anna twiitata samaa twiittiä useammin kuin kerran, joten twiitattavien välihuutojen on oltava uniikkeja:
(defn find-valihuudot [file]
(->> (text/extract file)
(re-seq #"\[.*?\]")
(map #(trim-text %))
(distinct)
(remove #(is-redunant? %))))
Tuo trim-text käytännössä vain poistaa hakasulkeet ja escapet tekstistä, mitä pdf:än tekstityksen jälkeen tuotokseen jää.
3. Varsinainen twiittaukseen keskittyvä namespace hyödyntää twitter-api -kirjastoa:
(twitter-api/statuses-update :oauth-creds creds :params {:status (str "Twiittaan välihuudot pöytäkirjasta: " (:memo-url info))})
Twitter developer portaalissa luodessasi uuden appsin, sait myös consumer-keyn, secretin ja tokenit. VälihuutoBot olettaa niiden tulevan ympäristömuuttujien kautta:
(defonce app-consumer-key (env :twitter-consumer-key))
(defonce app-consumer-secret (env :twitter-consumer-secret))
(defonce user-access-token (env :twitter-access-token))
(defonce user-access-token-secret (env :twitter-access-token-secret))
Mikäli tämä botti oltaisiin tehty jotenkin sofistikoituneemmin vaikka aws lambdalla, voisi nuo toki hakea jostain parameter storesta tai secrets managerista.
Mitä tekisin toisin?
Noh, periaatteessa tämmönen kerran päivässä pyörähtävä botti voisi olla ihan ihanteellinen lamdakeissi. Toisaalta, kun pyöritän tuota twiittaamista jopa kymmenelle tunnille jaettuna, niin välttämättä juuri tähän tapaukseen ei tuo lambda tulisi sen halvemmaksi. Homma oli hauska harjoitus tekstinkäsittelystä ja tähän mennessä botti on kerännyt jo yli 2000 seuraajaakin. Tällaiset hauskat pikkubotit tuovat ehkä näkyville kansalaisille sitä, mitä siellä eduskunnassa oikeastaan tapahtuu. Mietinkin, että ehkä puuhastelisin seuraavaksi semmoisen, joka hakisi eduskunnan äänestyksistä satunnaisesti äänestyksen ja tuloksista kansanedustajan ja miten hän äänesti. Tai sitten jotain ihan muuta.