Saturday, September 18, 2010

Let Windows Azure update your Facebook status (part 1)

Wouldn’t it be cool to have a bot which automatically posts something to your Facebook profile for you? Imagine how much time you could save if you wouldn’t have to log on to your profile several times a day anymore to post something, but still get a steady stream of comments and responses from your friends!


For instance, the bot could automatically do the following types of Facebook postings for you:




  • “Hello world”: general statements like “Good morning everyone!”, or “Have a great weekend, everybody!”, based on current day / time. Could also mix with some feelings, such as “.. is tired .. looking forward to the weekend.”
  • News: post a link to a random news article, with a generic comment such as “This is interesting…” or “Wow!”. 
  • Humor: post a random link to a humor page (such as TheOnion.com, Dilbert.com), with a comment like “LOL” or “This is funny..”
  • Events: post a comment referring to a local event, e.g. “Is anyone planning to go to the Seattle Beer Festival on Sunday?”
  • Movies/TV: post a comment regarding a movie or TV show, like “Has anyone already seen ‘Twilight’? Is it really that good?!”
  • Countdown: counting down the hours or days until a specified event. Example: “5 hours left until my party starts - hope to see all of you guys tonight!”
Ok, seriously, probably that would be pretty useless. But I’ve been curious for a while now how hard it would be to implement at least a basic version of such a bot. Plus, I needed a reason to play with the set of new Microsoft technologies such as Windows Azure, SQL Azure, and the developer tools for Windows Phone 7 (RTM version has just been released yesterday) anyways.

So far, I see at least two key challenges:
  • Style and content of the automated posts need to vary.  Ideally, readers shouldn’t be able to distinguish bot-generated posts from human-written ones. A Facebook version of the Turing Test, so to say. ;-) This is probably a hard artificial intelligence (AI) / natural language processing (NLP) problem. For the V1 of the bot, a small set of patterns, repeated in a random fashion, would be sufficient.
  • The bot needs to be able to communicate with the Facebook APIs asynchronously, without requiring the user to be online. Authentication will be the biggest issue here. Therefore this is the problem I’d like to solve first.
So, since I’d like to use the Microsoft technology stack - what’s the best way to access the Facebook APIs in .NET? There is a Codeplex project Facebook Developer Toolkit which provides high-level wrapper classes (such as “User”, “Friends”) to access the Facebook API. However, after playing with it for a little while, it appeared rather buggy and unstable to me, which is consistent with the feedback from several other users (refer for instance to this stackoverflow discussion). Therefore, I’ll use Facebook’s C# SDK instead. It’s still only an alpha release and not much more than a lightweight wrapper around the REST API, but that’s good enough for now.

As a first proof of concept, I’d like to set up a simple ASP.NET web form, hosted in a Windows Azure web role, which takes a string as an input and immediately posts it to the user’s profile:



Only a few lines of code need to be added to the Page_Load method to immediately post the content of the text box to the user’s profile:

if (IsPostBack)
{
  Facebook.FacebookAPI api = new Facebook.FacebookAPI(token);
  Dictionary<string, string> postArgs = new Dictionary<string, string>();
  postArgs["message"] = TextBox1.Text;
  api.Post("/me/feed", postArgs);
}

That’s the easy part. However, note that the FacebookAPI class expects a “token” parameter, which is an access token string. If no such token is available from an earlier session, the page needs to redirect the user to a Facebook authentication form first.


Here's where we need to work around a quirk of Windows Azure: when redirecting to the Facebook authentication page, we need to pass in a redirect_uri parameter. It indicates the page the user needs to get redirected back after a successful login. Since want the user to be redirected to the current page after signing in, we'd usually want to use Request.Url.AbsoluteUri in ASP.NET for this purpose. In Windows Azure however, this will not return the URL of the original request (the one received by Azure's load balancer), but the one received by the actual web role VM handling the request. This "internal" URL contains a port number (:20000) only to be used between the load balancer and the VM.
This is a known issue and will be fixed in a future Azure release. Until then, we'll have to work around it by manually removing the port number :20000 from the URL:


string urlThisPage = Request.Url.AbsoluteUri.Replace(":20000",""); 

string urlRedirectAuthenticate = string.Format(




"https://graph.facebook.com/oauth/authorize?client_id={0}&redirect_uri={1}&scope=publish_stream",
_appId,
urlThisPage);

Page.Response.Redirect(string.urlRedirect);



Note the “scope=publish_stream” parameter: this is an extended permission the bot needs to be able to actually post to the user’s profile later.

Regarding the appId parameter: any connection to the Facebook API requires a (public) appID and a 128 bit private key, called the “App Secret”. Therefore, as a first step, it’s necessary to create an application in Facebook and point it to a valid URL: the page will be hosted in Windows Azure under http://maxifacebookbot.cloudapp.net, so Facebook needs to know about that.

After the user has signed in, Facebook does redirect the request to the original URL and adds a "code" parameter to it. The web server then needs to contact the Facebook API one more time to get it exchanged for the actual access token. Unfortunately, Facebook's C# SDK doesn't offer any help in doing this, but a HttpWebRequest to https://graph.facebook.com/oauth/access_token does the job. Note that this is where Facebook also requires the app secret to be passed in.





string urlExchangeCode = string.Format(
  "https://graph.facebook.com/oauth/access_token?client_id={0}&redirect_uri={1}&client_secret={2}&code={3}",
  _appId,
  urlThisPage, 
  _appSecret,
  Request.QueryString["code"]
);

HttpWebRequest request = WebRequest.Create(urlExchangeCode) as HttpWebRequest;
request.Method = "GET";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
  StreamReader reader = new StreamReader(response.GetResponseStream());
  response = reader.ReadToEnd(); // contains "access_token=..."
}




Ok, let’s try it out: publish the web role to Windows Azure …







After opening http://maxifacebookbot.cloudapp.net, the app indeed redirects to the Faceboot login page. After logging in, the user has to confirm the special permissions requested by the application:




After “allow”ing, the web form shows up, and indeed, it does what it’s expected to do – nice!




Facebook is giving away that the post has been created via an application and not by the user. L So one of the things I’ll investigate later is whether there’s a way to authenticate with a real user session instead of “as an application”.

Anyways, since it turns out to be possible to do immediate wall posts from a Windows Azure web role process, I’m curious to find out whether this can also be done in a delayed/scheduled fashion from a Windows Azure worker process. One issue will be to hand over the access token: the user will still need to authenticate through a web form. Azure then needs to persist that token somewhere, maybe in a SQL Azure database. Also, it needs to make sure the token doesn’t expire – maybe sending dummy requests every few minutes will prevent a timeout.

Until then, have fun updating your Facebook status with MaxiBot! J


Thursday, September 16, 2010

Stuttgart 21 - welche Argumente überwiegen denn nun?

Auf der Webseite des "Bahnprojekt Stuttgart-Ulm e.V" (www.das-neue-herz-europas.de) ist mir heute das folgende Logo aufgefallen:
"Die guten Argumente überwiegen" .. hmmmmmmm. Ist das nicht schon rein semantisch fragwürdig, sollte das nicht wenn überhaupt heißen "Die Argumente dafür überwiegen"? Man mag mich hier der Haarspalterei veruteilen, aber ob ein Argument nun gut oder schlecht ist hat doch nichts damit zu tun, ob es ein Pro- oder ein Contra-Argument ist, oder?

Hier z.B. ein Pro-Argument von obiger Webseite:
Wegen der neuen Schnellfahrstrecke fährt der Großteil der Fernzüge nicht mehr durch das Neckartal. Die neue Trasse führt künftig vom Hauptbahnhof durch den Fildertunnel auf die Filder. Durch den Ringverkehr fahren die Züge künftig unterirdisch durch die Stadt. Das heißt: Mehr Schienenverkehr, aber weniger Lärm, weil mehr als 30 Kilometer der Strecke in Tunnels verlaufen.
Das ist ein gutes Argument. Wenn der Tunnel erst einmal fertig ist und die Züge da durch fahren, ist das für sich gesehen eine tolle Sache - das Argument selbst ist nicht angreifbar, statt dessen müssen Gegenargumente (und zwar ebenfalls gute) vorgetragen werden.

Hier dagegen ein Pro-Argument von der Webseite www.stuttgart21-ja-bitte.de:
Würde man Stuttgart 21 jetzt noch abwürgen, wären nicht nur die Kosten hunderttausender Arbeitsstunden sondern auch der Kaufpreis von 459 Mio. Euro für die Grundstücke - die ja dann nicht nutzbar wären - in den Sand gesetzt.
...
Es wäre ja auch das komplette Chaos und der wirtschaftliche Ruin, wenn man rechtmäßig getroffene Entscheidungen noch nach so langer Zeit wieder kippen könnte. Langfristiges zukunftsorientiertes Handeln wäre gar nicht möglich. An einem gewissen Punkt müssen demokratische Entscheidungen auch respektiert werden.
Das halte ich für ein schlechtes Pro-Argument. Die bisher investierten "Arbeitsstunden" und "459 Mio. Euro" sind sunk costs. Und es sollte ja wohl bitte zu jedem Zeitpunkt möglich sein, Entscheidungen zu revidieren, die sich nach erneuter Überprüfung als falsch herausstellen. Im Gegenteil, gerade bei langfristigen Projekten düfte eine regelmäßige Kursüberprüfung sinnvoll sein - z.B. könnten sich die Rahmenbedingungen geändert haben, früher getroffene Annahmen könnten sich inzwischen als falsch herausgestellt haben, Prioritäten könnten sich verschoben haben usw. Es ist daher gar kein Gegenargument nötig, das Argument hält bereits in sich einer genaueren Überprüfung nicht stand.

Bei schlechten Argumenten ist nebenbei gelegentlich Skepsis angebracht. Möglicherweise wurden diese wiederum von der Gegenseite ins Spiel gebracht, um sämtliche Argumente - auch die guten - in ein schlechtes Licht zu rücken ("Poisoning the well" Strategie).

Ein besonderer Fall von schlechten Argumenten sind solche, die nicht auf logischen Widersprüchen, sondern auf Halbwahrheiten oder Unwahrheiten beruhen. Hier z.B. ein weiteres Zitat von der Webseite des Bahnprojekt Stuttgart-Ulm e.V. - unter der Überschrift 21 gute Gründe für Stuttgart 21 wird behauptet:
Mit dem Bahnknoten Stuttgart und der Neubaustrecke nach Ulm wird das Reisen quer durch Europa schneller und bequemer. Die Züge müssen an der Geislinger Steige, dem größten Engpass des europäischen Schienennetzes, nicht mehr herunterbremsen. Von Stuttgart nach München dauert eine Zugfahrt nur noch gut eineinhalb Stunden.
Dies ist ein schlechtes weil irreführendes Argument: die Geislinger Steige ist Teil der Neubaustrecke Wendlingen-Ulm und hat mit Stuttgart 21 nichts zu tun, d.h. unter der genannten Überschrift hat das Argument nichts verloren. Hier werden ganz bewusst zwei getrennte Themenbereiche miteinander verbunden.

Nun mal ein Blick auf die Argumente der Gegenseite. Eines der wesentlichen Contra-Argumente sind die enormen Kosten des Projekts, verbunden mit einer möglichen weiteren Kostenexplosion. So wird z.B. auf der Webseite www.kopfbahnhof-21.de argumentiert:

Seit Beginn der Planungen kam es zu enormen Kostensteigerungen, scheibchenweise kommt die wahre Dimension ans Licht. Die für Frühjahr 2010 zugesagten Ergebnisse der Wirtschaftlichkeitsüberprüfung der Neubaustrecke Wendlingen - Ulm - und damit aktuelle und realistischere Baukosten - liegen immer noch nicht vor. Statt 6,5 Milliarden Euro werden Stuttgart 21 und die Neubaustrecke Wendlingen - Ulm mindestens 10 Milliarden Euro kosten und zum weit überwiegenden Teil aus öffentlichen Kassen finanziert. Über die Finanzierung dieser Mehrkosten wurde kein Einvernehmen hergestellt.

Eindeutig ein gutes Argument - vorausgesetzt die genannten Zahlen stimmen, ist es kaum angreifbar. Oder würde jemand argumentieren wollen, es sei doch ganz gut, die Öffentlichkeit lieber ein wenig im Unklaren über die Kosten des Projekts zu lassen? Wohl kaum.

Aber, gleich das nächste Argument auf der gleichen Seite erscheint mir schon nicht mehr so stichhaltig:

Bund, Länder und Kommunen weisen Rekordverschuldungen auf, die Regierung hat einen harten Sparkurs ausgerufen. Bereits vorher war der Verkehrsetat drastisch unterfinanziert. Wichtige Verkehrsprojekte werden dem Rotstift zum Opfer fallen. Die knapper werdenden Gelder müssen Projekten mit einem hohen verkehrlichen Nutzen, den weder Stuttgart 21 noch die Neubaustrecke aufweisen, zufließen. Jetzt gilt erst recht: Stuttgart 21 ist nicht zeitgemäß.

Naja. Sparkurs war immer, ist immer, wird immer sein. Aber wenn man den Befürwortern glauben schenkt, ist das Projekt ja eine Investition, das langfristig eine entsprechende Rendite abwirft - so behauptet z.B. die Stadt Stuttgart, langfristig mehr Steuern einzunehmen, als ihr Finanzierungsanteil kosten wird. Genausogut könnte man nun daher nun die ganze Argumentation auf den Kopf stellen und sagen, dass wir doch gerade in Zeiten knapper Haushalte unternehmerisch denken und öffentliche Mittel in Projekte mit entsprechender Rendite investieren müssten ... daher ist dies, meiner Ansicht nach, ein schlechtes Argument. Dieses Mal eins der Contra-Seite.

Wenn wir uns nun darauf einigen, grundsätzlich nur die guten Argumente zu betrachten - sowohl Pro- als auch Contra - welche "überwiegen" denn nun?

Meine Gedanken hierzu sind die folgenden:
  • Wirtschaftlich: ich weiß unterm Strich nicht, ob Stuttgart 21 eine gute Investition wäre oder nicht. D.h. ob die hieraus entstehenden Mehreinnahmen langfristig höher wären als die Kosten. Mangels Kristallkugel kann dies im Endeffekt niemand wissen, sondern nur auf der Basis von zahlreichen Annahmen schätzen.
    Das Problem ist, das es kaum noch möglich ist, den Verantwortlichen hier noch ein Wort zu glauben. Über die tatsächlichen Kosten und Risiken herrscht Unklarheit, fast täglich kommen neue Unstimmigkeiten ans Licht. Das Projekt ist offensichtlich politisch gewollt und wird schöngerechnet.
    Also? Es könnte trotzdem sein, dass Stuttgart 21 tatsächlich wirtschaftlich rentabel ist, aber ich halte es für unwahrscheinlich und glaub's jetzt daher einfach mal nicht.

  • Ökologisch: Über 200 Bäume im Stuttgarter Schlossgarten zu fällen .. das tut schon weh. Ansonsten, angeblich keine Gefahr für Mineralquellen und Grundwasser - aber wie gesagt, Thema Glaubwürdigkeit..

  • Bauzeit: seien wir realistisch, das ganze wird 10-15 Jahre dauern, bis es fertig ist. Ehrlich gesagt, wenn das wirklich durchgezogen wird, bin ich ganz froh gerade nicht mehr in Stuttgart zu wohnen.

  • Nutzen: also jenseits der Wirtschaftlichkeit aus Sicht des Steuerzahlers, was hätten wir davon als Besucher in Stuttgart und als Bahnkunde? Sicher, es wäre ganz nett, am Flughafen Stuttgart zu landen und gleich in den ICE zu steigen wie in Frankfurt. Aber im Gegenzug entsteht mit dem unterirdischen Hauptbahnhof doch ein neuer Flaschenhals - mit gerade einmal 8 Gleisen. Reicht das wirklich aus, langfristig? Klingt für mich eher nach mehr Gedränge, weniger Komfort, und keinerlei Möglichkeit, die Kapazität später zu erhöhen.

Gut, ich hab mir meine Meinung jetzt gebildet: ich bin für die Bahnstrecke Wendlingen-Ulm, aber gegen Stuttgart 21. Und jetzt kann ich auch ruhigen Gewissens der Facebook-Gruppe "KEIN Stuttgart 21" beitreten.

Und gegen die CDU war ich sowieso schon immer. :-)