Anfang des Jahres wurde ich von der österreichischen Perl-Zeitung gefragt, ob ich auf Grundlage der in diesem Blog veröffentlichen Posts ein kurzen zusammenfassenden Beitrag über Twitter mit Perl schreiben könne, was ich gerne gemacht habe (Details siehe mein Blogpost vom 3. März 2012). Wie versprochen poste ich den Beitrag nun auch hier:
Twitter-API Programmierung mit Perl (März 2012, Perl-Zeitung.at)
Vor gut zwei Jahren hat Twitter den Zugang über Basic Authentication abgestellt und lässt seither nur noch API-Zugriffe mittels OAuth zu. Eigentlich eine gute Idee, denn OAuth ist ein praktisches Protokoll, das sich inzwischen als Quasi-Standard für offene Social-Media-APIs etabliert hat (ebenso etwa bei Google+ und Facebook). Die Erstellung kleiner Scripte wird jedoch dadurch etwas komplizierter, aber mit Hilfe des frei verfügbaren Net::OAuth Moduls ist das auch nicht allzu kompliziert.
Im Folgenden soll kurz erklärt werden, wie eine einfache „Single-User-Lösung“ mit Perl realisiert werden kann. In meinem Beispiel soll durch ein Script Tweets im Namen eines bestimmten Twitter-Account verschickt werden. Das ist deshalb eine „Single-User-Lösung“, da auf die Authentifizierung verzichtet wird und das Script eben nur im Namen dieses einen Twitter-Accounts die API nutzen kann. Möchte man eine komplexere Multi-User-Lösung empfiehlt es sich, fertige Twitter-Module für Perl, z. B. Net::Twitter zu verwenden und nicht wie hier nur eine Minimallösung zu realisieren. Aber für einfache Aufgaben, etwa um mit einem crontab gesteuertem Script automatisch News aus irgendwelchen Quellen auszulesen und in Tweets zu verwandeln, um einen Retweet-Bot oder eine Twitter-Wall zu bauen ist folgende „Single-User-Lösung“ bestens geeignet.
Als erstes muss die eigene „Application“ bei Twitter registriert werden:
- Dafür ruft man die Developer-Seite von Twitter auf: http://dev.twitter.com
- Als nächstes meldet man sich mit dem Twitter-Account an, mit dem später auch das Script ausgeführt werden sollen.
- Jetzt wählt man „Create App“ und denkt sich einen schönen Namen sowie eine Beschreibung für seine App aus (diese können Nutzer u. U. zu Gesicht bekommen, je nach Client wird diese Info unter den Tweets angezeigt).
- Auch eine URL ist anzugeben (z. B. die Homepage der Firma oder des Entwicklers), die Callback-URL muss leer gelassen werden.
- Jetzt ist die App erstellt. Unter „Setting“ muss man nur noch „Read&Write“ auswählen, sonst hat man nur Lesezugriff auf Twitter und kann keine Tweets versenden.
- Auf der Seite „Details“ findet man nun den OAuth-Consumer-Key und -Secret. Diese werden später benötigt (es sind die Zugangsschlüssel für die Anwendung, die sich nicht ändern würden, wenn man einen anderen Benutzer das Script ausführen lassen wollte).
- Unter „Details“ klickt man auf „Create my access token“. Darauf erhält man das OAuth-Access-Token und -Secret für den aktuell eingeloggten Twitter-User. Achtung: Möchte man, dass nicht nur ein User, sondern unterschiedliche das Script nutzen, braucht man eine „Multi-User-Lösung“. Dafür müsste dann die OAuth-Authentifizierung komplett implementieren, was nicht Inhalt dieses Tutorials ist (vgl. oben).
Bevor die Programmierarbeit beginnen kann muss ggf. nur Net::OAuth installiert werden – zu finden auf CPAN, deshalb einfach in die Shell perl –MCPAN –e ‚install NET::OAuth‘ tippen.
Und so sieht der Programmcode aus:
#!/usr/bin/perl use strict; use LWP::UserAgent; use Encode; use Net::OAuth; $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A; # OAuth: Tokens für den Twitter-User my $accesstoken = "???"; my $accesssecret = "???"; # OAuth: Keys für die App my $consumerkey ="???"; my $consumerkeysecret="???"; # Allgemeines my $APIurl = 'http://api.twitter.com/1/statuses/update.xml'; my $reqmethod = 'POST'; # Name des UserAgent - eigentlich egal my $UAname="myTwitterScript"; # achtstellige Zufallszahl für nonce my $zufallszahl = int(rand(90000000))+ 10000000; # Text des Tweets: my $nachricht="Danke an \@Simon_A_Frank für dieses Tutorial!"; # OAuth request vorbereiten my $request = Net::OAuth->request("protected resource")->new( consumer_key => $consumerkey, consumer_secret => $consumerkeysecret, request_url => $APIurl, request_method => $reqmethod, signature_method => 'HMAC-SHA1', timestamp => time, nonce => $zufallszahl, token => $accesstoken, token_secret => $accesssecret, extra_params => { status => decode_utf8($nachricht) } ); # OAuth signieren $request->sign; # hilfreiche LWP Settings my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; # http-Request vorbereiten und senden my $httpheader = HTTP::Headers->new('User-Agent' => $UAname); my $httprequest = HTTP::Request->new($reqmethod, $APIurl, $httpheader, $request->to_post_body); my $httpresponse = $ua->request($httprequest); # Erfolg? if ($httpresponse->is_success) { #Hat geklappt! print "Tweet erfolgreich verschickt!\n\n"; print "\nContent (XML): " . $httpresponse->content . "\n"; } else { #ging nicht ... print "Nicht erfolgreich, Fehler: " . $httpresponse->status_line; }
Noch ein paar Tipps:
Für das Versenden von Tweets gibt es noch etliche weitere Parameter, die in der ausführlichen offiziellen Doku zu finden sind – auch andere Rückgabeformate (statt XML) sind möglich, z. B. JSON. Details siehe: https://dev.twitter.com/docs/api/1/post/statuses/update
Natürlich kann man mit der Twitter REST-API nicht nur Tweets versenden sondern vieles mehr: z. B. Tweets auslesen, direct messages versenden, Followers hinzufügen usw., Details siehe:
https://dev.twitter.com/docs/api
Bei der Registrierung der App ist die Standardeinstellung inzwischen „Read“. Dies muss man vor der Erstellung der Access Token umstellen (vgl. oben). Hat man dies vergessen muss man nach der Änderung der Zugriffseinstellungen auf „Recreate my acccess token“ klicken.
Fehler bei der Übertragung können auch daran liegen, dass die $nachricht nicht richtig codiert ist und deshalb der gesamte Request nicht korrekt signiert wird. Statt status => decode_utf8($nachricht) kann man es für erste Tests einfach auch mal ohne ein „decode“ probieren status => $nachricht wenn man darauf achtet, dass die $nachricht keine Umlaute, Satz-, Sonder- und Leerzeichen enthält.
Beim Testen sollte man daran denken, dass Twitter zwei gleichlautende Tweets hintereinander ablehnt, deshalb empfiehlt es sich, bei jedem Testlauf eine andere $nachricht zu versenden. Außerdem ist auf das API-Limit zu achten – derzeit erlaubt Twitter maximal 350 API-Calls pro Stunde.
Möchte man seine Follower mit Test-Tweets nicht verärgern empfiehlt es sich, den Test mit direct message statt mit Tweets durchzuführen. Folgendes ist dafür zu ändern (unter „User“ gibt man den Empfänger der direct message an):
extra_params => { text => decode_utf8($nachricht), user => "Simon_A_Frank" }
Update im Februar 2014: Eine neue Version dieses Tutorials ist hier zu finden!
P.S.
Probleme? Fragen? Anregungen? Ich helfe jederzeit und gerne – einfach einen Kommentar oder Mail schreiben, die Antwort kommt schnellstmöglich. Unternehmen, die Unterstützung, Beratung oder Schulung bei der API- oder Webprogrammierung, der Social-Media-Entwicklung oder dem Social-Media-Management benötigen finden zudem entsprechende Angebote meiner Firma auf der Website www.Frank-IT-Beratung.de
Im Februar 2014 habe ich eine neue Version dieses Tutorials veröffentlicht:
http://frank-it-beratung.com/blog/2014/02/28/tutorial-twitter-api-programmierung-mit-perl-neue-version/
Mitte Juni 2013 wurde die API v. deaktiviert. Deshalb heißt es jetzt statt
my $APIurl = ‚http://api.twitter.com/1/statuses/update.xml‘;
neu
my $APIurl = ‚http://api.twitter.com/1.1/statuses/update.json‘;
Dazu kommen einige andere Probleme, so dass das oben genannte Script teilweise nicht mehr funktioniert (Fehlercode 215, „Bad Authentication data“). Ein Update ist in Vorbereitung, Details siehe http://frank-it-beratung.com/blog/2013/06/30/twitter-rest-api-v1-deaktiviert-json-statt-xml/
Das ist eine Super-Anleitung! Mein Problem: Mein Provider stellt das Modul Net::OAuth nicht zur Verfügung und will auch keine weiteren Module installieren. Was tun?
Hallo Emil, das Modul “OAuth” kannst Du wahrscheinlich auch “manuell” einrichten. Lade das Paket hier down:
http://search.cpan.org/dist/Net-OAuth/lib/Net/OAuth.pm
Wechsle in den Ordner “lib” und kopiere den Ordner “Net” samt Inhalt in den Ordner, in dem Dein Script liegt. Ich hoffe, das funktioniert?
vielen Dank 🙂
OK Funktioniert jetzt, nachdem ich die Tokens neu generiert habe. Super Anleitung! Weiter so.
Leider funktioniert der obige Code bei mir nicht richtig.
Ich bekomme immer ein: „401 Unauthorized“.
Tokens/Schlüssel sind richtig eingegeben und auch die Zugriffsrechte stimmen. Hat sich vielleicht schon wieder etwas an der twitter-API geändert?
Wäre dankbar für eine Antwort.