Zwitscher dir was (Linux-Magazin, Oktober 2009)

Der oft belächelte Twitter-Service taugt nicht nur zur eitlen Selbstdarstellung, sondern lässt sich mit Hilfe der angebotenen API programmatisch bedienen und zweckentfremden.

``Wozu bitte braucht man Twitter?'' -- sicher keine ganz einfach zu beantwortende Frage. Warum in aller Welt sollte man der Welt per Handy mitteilen, dass man mit Freunden beim Pizzaessen weilt, im Fitnessstudio ochst oder mit dem Flugzeug gerade in einem fernen Kontinent gelandet ist?

Abbildung 1: Wozu bitte braucht man Twitter?

Die von Twitter oder in der freien Variante auch von identi.ca angebotene Plattform zum ``Microblogging'' hat aber ganz erstaunliche Nebeneffekte. Möchte man herausfinden, was die Menschheit gerade im Augenblick bewegt, hilft weder Googles Suchmaschine noch Wikipedia weiter, sondern ein Blick auf die Startseite des Twitter-Service. Dort zwitschern Leute, die vor Ort politische Unruhen, Naturphänomene, den neuesten Kinofilm, oder Sportereignisse erleben -- noch bevor die Redaktionen der Tageszeitungen und Fernsehsender die Nachrichten überhaupt erfassen können.

Dass Twitter überhaupt funktioniert, grenzt an ein Wunder. Der Service bietet nur minimale Funktionen und seine Infrastruktur ist so wackelig, dass Ausfälle zur Tagesordnung gehören. Und trotzdem füttern 6 Millionen Nutzer das zerbrechliche Geschöpf unermüdlich mit Nachrichten, lassen es mit brandaktuellen Informationen pulsieren und halten es seit 2006 am Leben. Das Twitter-Team fügt nur sehr zögerlich neue Funktionen hinzu, und meist erst dann, wenn die treuen Twitter-Fanatiker dem simplen Riesen über abenteuerlich kreative Umwege neue Funktionen abgeluchst haben.

Abbildung 2: Typisches Twitter-Geplapper von Dauerblogger Robert Scoble.

Twitter kann sehr wenig: Nutzer mit einem Account dürfen 140 Zeichen lange Kurznachrichten an den Service schicken, die dieser dann veröffentlicht. Sie erscheinen sowohl in einer ``Public Time Line'' als auch unter dem Account des Users. In Kombination mit mobilen Telefonen über SMS oder Web entsteht so eine zwar oberflächliche, aber brandaktuelle Kommunikation. Wen interessiert, was ein User so von sich gibt, trägt sich als ``Follower'' (Verfolger) des Users ein, erhebt diesen damit zum ``Freund'' und bekommt dessen Nachrichtenstrom in den eigenen eingespielt. Typischerweise folgt jeder User einigen anderen Leuten und wird umgekehrt von anderen verfolgt. Ein unausgeglichenes Verhältnis deutet auf ein Problem hin: So verfolgen Spammer sehr viele Nutzer, werden aber ihrerseits von niemandem angehimmelt oder gelesen.

Abbildung 3: Der freie Twitter-Klon identi.ca

Twitter kostet nichts, wird aber wohl irgendwann die Daumenschrauben ansetzen, um Geld zu verdienen. Der freie Klon identica.org kommt optisch leicht unterschiedlich daher, bietet aber exakt die gleichen Funktionen, bis ins Detail und im URL-Layout. Das bedeutet zum Beispiel, dass das Perl-Modul Net::Twitter mittels eines einzigen Parameters von Twitter auf identi.ca umstellt, einfach, indem es http://twitter.com durch http://identi.ca ersetzt.

Zögerlich mit neuen Features

Twitter zögert mit neuen Features und lässt die User die 140 verfügbaren Zeichen pro Nachricht als eine Art Programmiersprache zweckentfremden, um neue Funktionen auszutesten. ``Retweets'', also zitierwürdige Nachrichten, die Verfolger eines Twitterers wiederum an ihre Verfolger weiterleiten, sind so ein Beispiel. Da eine derartige Funktion im ursprünglichen Twitter nicht existierte, brachten findige User die Buchstabenfolge ``RT @username'' in der Nachricht unter, solange, bis sich Twitter erbarmte und den ``Standard'' anerkannte.

Twitter bietet eben nur grobe Bauklötzchen, und dies spiegelt sich auch bei der der schlanken API wieder. Um so erstaunlicher ist es daher, dass der O'Reilly-Verlag gar ein knapp 400 Seiten starkes Buch zum Thema ([2]) herausgab, das nicht nur die Programmierschnittstelle erklärt, sondern auch ein knappes Tutorial zur Web-Programmierung und eine ganze Reihe erfolgreicher Twitter-Applikationen von Drittanbietern vorstellt.

Alles ausradiert

Wozu nun die API? Klarerweise könnte man damit recht einfach einen weiteren Client mit graphischer oder textbasierter GUI schreiben, doch auch zur Behebung von Twitterfehlern ist sie nützlich. Beim Anlegen des Test-Accounts 'perlsnapshot' muss ich wohl die falsche Taste erwischt haben, denn auf einmal tauchten dort sage und schreibe 20 Freunde auf, von denen ich noch nie im Leben gehört hatte. Diese einzeln zu löschen wäre im Browser eine Tortur gewesen, aber zum Glück ratterte das in fünf Minuten zusammengeklopfte Skript in Listing unfollow-all durch die Liste der falschen Freunde und warf sie samt und sonders wieder aus meinem Leben.

Listing 1: unfollow-all

    01 #!/usr/bin/perl -w
    02 use strict;
    03 use Net::Twitter;
    04 
    05 my $nt = Net::Twitter->new(
    06         traits   => [qw/API::REST/],
    07         ssl      => 1,
    08         username => "perlsnapshot",
    09         password => "*******",
    10 );
    11 
    12 my $friends = $nt->following();
    13 
    14 for my $friend (@$friends) {
    15     print "$friend->{screen_name}\n";
    16     $nt->destroy_friend( $friend );
    17 }

Passwort weg, Holland in Not

Wer Wert auf Sicherheit legt, dem fällt sicher das im Programmcode stehende Passwort auf, mit dem das Skript sich gegenüber dem Twitter-Service authentifiziert. Wegen der gesetzten Option ``ssl'' geht das Passwort allerdings nicht im Klartext über die Leitung, da das verwendete Perl-Modul Net::Twitter in diesem Fall mit Twitters https://-URLs kommuniziert. Doch bei wie Pilzen aus dem Boden schießenden Applikationen stellt sich die Frage, wie man es vermeidet, jedem Drittanbieter sein Passwort mitzuteilen. Befindet sich in der Kette auch nur ein Schlamper, der das Passwort vertandelt, ist Holland in Not.

Zur Behebung dieses Problems eignet sich das von Twitter neuerdings angebotene OAuth. Es räumt verschiedenen Applikationen Rechte an einem Benutzerkonto ein. Statt den Nutzernamen mitsamt Passwort an verschiedenste Anbieter weiterzuleiten und zu hoffen, dass kein einziger Schindluder damit treibt, erhält jeder Anbieter einen einzigartigen Token, den der Nutzer aber auch jederzeit widerrufen kann, ohne andere Anbieter zu beeinträchtigen, die separate Token verwenden. Das Perlmodul Net::Twitter unterstützt OAuth, allerdings besteht Twitter darauf, die Applikation unter [4] zu registrieren, bevor es die notwendigen Token ``Consumer Key'' und ``Consumer Secret'' herausrückt. Das heißt: Falls der Service gerade funktioniert, was zum Zeitpunkt der Entstehung dieses Artikels mal wieder nicht der Fall war.

Twitter als Logdatei

Eine weitere Anwendung der Twitter-API zeigt Listing TwitSend.pm, ein Perl-Modul, das sich in andere Perlprozesse einbinden lässt, um mit der von ihm bereitgestellten Funktion twit() Nachrichten an Twitter senden. In typischer Perl-Manier akzeptiert die Funktion entweder eine Nachricht als String oder eine Referenz auf einen Hash, der ein Feld namens 'message' mit sich führt. Ein zweiter Parameter 'home' deutet für den Fall, dass der gerade laufende Prozess vom root-User ausgeführt wird (wie zum Beispiel ein Backup-Programm), auf das Home-Verzeichnis des Users, in dem eine YAML-Datei mit dem Password des Twitter-Accounts liegt.

Listing 2: TwitSend.pm

    01 use strict;
    02 use Net::Twitter;
    03 use YAML qw(LoadFile);
    04 use base qw(Exporter);
    05 our @EXPORT_OK = qw(twit);
    06 
    07 ###########################################
    08 sub twit {
    09 ###########################################
    10   my($message) = @_;
    11 
    12   my $opts = {};
    13 
    14   if(ref($message) eq "HASH") {
    15       $opts    = $message;
    16       $message = $opts->{message};
    17   }
    18 
    19   if(! defined $message) {
    20     die "No message given!";
    21   }
    22 
    23   if(length $message > 140) {
    24     die "Message needs to be < 140 chars";
    25   }
    26 
    27   my $home = $opts->{home};
    28 
    29   ($home) = glob "~" unless defined $home;
    30 
    31   my $yaml = LoadFile( "$home/.twitsend" );
    32 
    33   my $nt = Net::Twitter->new(
    34         traits   => [qw/API::REST/],
    35         ssl      => 1,
    36         # identica => 1,
    37         username => "perlsnapshot",
    38         password => $yaml->{password},
    39   );
    40 
    41   $nt->update( $message );
    42 }
    43 
    44 1;

Wozu das Ganze? Die in [5] vorgestellte Bewässerungsanlage für meine Balkonpflanzen tut auch nach mehr als zwei Jahren noch klaglos ihren Dienst, aber hin und wieder würde ich im Urlaub gerne einen Blick auf ihre Aktivitäten werfen. Was liegt also näher, als die Pumpenaktivität auf Twitter zu melden, von wo sie dann aus dem Internetcafe aus einsehbar ist oder auf dem Mobiltelefon landet?

Abbildung 4: Twitter als Logdatei zur Serverüberwachung.

Das Modul TwitSend.pm in das damals beschriebene Skript water zur Pflanzenbewässerung einzubinden und die Funktion twit() mit einer Nachricht und dem Pfad zu einer .yaml-Datei mit dem Account-Passwort für 'perlsnapshot' aufzurufen war in 5 Minuten erledigt.

Die Implementierung sieht aus wie im Beispielskript twitsend, das Ergebnis auf Twitter wie in Abbildung 4 dargestellt. Die morgentliche Bewässerungdauer der Pflanzen an einem warmen Augusttag betrug demnach 60 Sekunden, und die Datensicherung auf meinem Entwicklungsrechner war um 11:49 beendet. Das Verfahren funktioniert ähnlich wie der von Kolumnenkollege Charly Künast in [3] kürzlich vorgestellte ttytter-Client. Das Skript benötigt nur noch die YAML-Datei .twitsend im Home-Verzeichnis /home/mike sollte mit den Rechten 0500 angelegt werden, damit sie nur für den Accountbesitzer selbst les- und schreibbar ist. Sie enthält nur eine Zeile password: ****, die das Passwort setzt (Abbildung 5).

Die im Modul TwitSend.pm in Zeile 36 auskommentierte 'identica'-Direktive nordet Skripts übrigens statt auf Twitter auf freien Klon identi.ca ein.

Listing 3: twitsend

    1 #!/usr/bin/perl -w
    2 use strict;
    3 use MyTwitSend qw(twit);
    4 
    5 twit({ 
    6   message => "This is yet another test message.",
    7   home    => "/home/mike",
    8 });

Abbildung 5: Die Konfigurationsdatei für TwitSend.pm, die das User-Passwort des verwendeten Twitter-Accounts setzt.

Zu beachten ist noch, dass Twitter identische Nachrichten schweigend ignoriert. Ein Cronjob, der täglich einmal ``Backup fertig'' aussendet, wird also nicht das gewünschte Ergebnis erzielen, aber mit einem Datumsstempel versehen wird ein Schuh daraus.

Es wäre denkbar, verschiedene Prozesse unter mehreren Twitter-Accounts zwitschern zu lassen und diese dann von einem persönlichen Account aus wahlweise über Twitters ``Follow''-Funktion zu verfolgen. Aus dem Urlaub zurückgekehrt, führt dann ein ``Unfollow'' auf der Twitter-Webseite wieder zur Entkopplung der Logs vom Nachrichtenstrom persönlicher Freunde.

Die über Net::Twitter ansprechbare API erlaubt es außerdem, Tweets zu löschen, administrative Funktionen wie follow/unfollow oder block auszuführen, private Nachrichten zu senden, den öffentlichen Nachrichtenstrom anzuzapfen und vieles mehr. Twitter beschränkt die Anzahl der Zugriffe auf 100 pro Stunde und verfolgt die Aktivität sowohl per IP als auch per Account.

Installation

Leider sind Net::Twitter und der Rattenschwanz notwendiger Zusatzmodule vom CPAN nicht als Ubuntu-Packages erhältlich. Aber eine mit 'perl -MCPAN -eshell' aufgerufene CPAN-Shell installiert mit dem Kommando 'installl Net::Twitter' alle notwendigen abhängigen Module. Weil Net::Twitter auch noch Moose herbeizieht und OAuth unterstützt, kann sich der Prozess in die Länge ziehen und eine Kaffepause ist anzuraten.

Infos

[1]

Listings zu diesem Artikel: ftp://www.linux-magazin.de/pub/listings/magazin/2009/10/Perl

[2]

``Twitter API, Up and Running'', Kevin Makice, O'Reilly 2009

[3]

``Zwitschermaschine'', Charly Kühnast, Linux-Magazin 2009/07

[4]

Twitter OAuth Application Registration, http://twitter.com/oauth_clients

[5]

``Der Mörder ist nimmer der Gärtner'', Michael Schilli, 2007/03, http://www.linux-magazin.de/heft_abo/ausgaben/2007/03/der_moerder_ist_nimmer_der_gaertner

Michael Schilli

arbeitet als Software-Engineer bei Yahoo! in Sunnyvale, Kalifornien. Er hat "Goto Perl 5" (deutsch) und "Perl Power" (englisch) für Addison-Wesley geschrieben und ist unter mschilli@perlmeister.com zu erreichen. Seine Homepage: http://perlmeister.com.