Showing posts with label fun. Show all posts
Showing posts with label fun. Show all posts

Tuesday, June 19, 2012

The @FindMyPlane bot

A few days ago I wrote about the Genexus Challenge developer edition and my first Smart Devices app, Find my Plane. Once I get, what I think is, a good idea in my head I get around it a lot to improve it in every possible way. But this is not the case, sort of.

Right after I deployed the app to the Apple’s app store, I thought “how can I advertise it, without paying for advertising of course”, I needed people to find out about the app and download it, and a good word about it would be awesome too. So I thought about social networks… Facebook is for friends and I already told them to download it (did I mentioned it’s free?!) so twitter came to mind… but what can I do to promote my app from twitter, other than twitting about it of course.

So I thought of the @FindmyPlane bot and this post will tell you how I did it, not that it’s rocket science, but I found an interesting use of Windows Azure’s Worker Roles*. Wait, what?! you’re gonna tell people how to build a twitter spammer bot? No, let me get into that.

The @FindMyPlane twitter account works like this. You send a twit to @FindMyPlane with your flight number and find my plane will answer that tweet with useful info about it, the same kind of info you’d get in the Find My Plane app, but of course, only the info that fits in 140 characters.

So this is how it works. There’s a worker role (called Receiver) that every ten seconds access the twitter api looking for mentions for the @FindMyPlane account. Once it gets the list of tweets (if any of course) it saves them to a Table from Azure Storage and saves the latest tweet id in a Queue (also from Azure Storage) so the next time it just asks from that tweet on.

This is pretty much the code:

string lastTweet = "";
string previousMessageId = "";
foreach (CloudQueueMessage message in Queue.GetAllMessages(Constants.AZURE_STORAGE_ACCOUNT, Constants.AZURE_STORAGE_KEY, Constants.AZURE_QUEUE))
{
previousMessageId = message.Id;
lastTweet = message.AsString;
}

bool first = true;
foreach (Status status in Mentions.GetMentions(fmp, lastTweet))
{
try
{
Table.Insert(Constants.AZURE_STORAGE_ACCOUNT, Constants.AZURE_STORAGE_KEY, Constants.AZURE_TABLE, TweetEntity.FromStatus(status).ToString());
}
catch { }

if (first)
{
lastTweet = status.Id;
first = false;
}
}

if (!first)
{
Queue.DeleteMessage(Constants.AZURE_STORAGE_ACCOUNT, Constants.AZURE_STORAGE_KEY, Constants.AZURE_QUEUE, previousMessageId);
Queue.CreateMessage(Constants.AZURE_STORAGE_ACCOUNT, Constants.AZURE_STORAGE_KEY, Constants.AZURE_QUEUE, lastTweet);
}




And there’s a second Worker Role (called Replier) that every ten seconds queries the table where the tweets were saved for those that have not been replied yet and don’t have errors. For every tweet I try to get info of the flight number sent, if I do find info, I reply the tweet with that info and update the record on the table as replied. If I can’t find info, let’s say you tweeted “@FindMyPlane is awesome!” I update the record as ‘with errors’. This is just a way for me to know when I couldn’t reply because of an error on the system or because what I got was not a valid flight number.



Code here:



string query = "Replied eq 'False' and Error eq 'False'";
foreach (TableEntity entity in Table.Query(Constants.AZURE_STORAGE_ACCOUNT, Constants.AZURE_STORAGE_KEY, Constants.AZURE_TABLE, query))
{
string flightNumber = entity["Text"].ToUpper().Replace("@FINDMYPLANE ", "");
try
{
FlightInfo info = FlightStatus.GetFlightStatus(flightNumber);
string tweet = string.Format("@{0} {1}", entity["UserScreenname"], info);
Update.UpdateStatus(tweet, fmp, entity["Id"]);
entity["Replied"] = "True";

Table.UpdateEntity(Constants.AZURE_STORAGE_ACCOUNT, Constants.AZURE_STORAGE_KEY, Constants.AZURE_TABLE, entity);
}
catch
{
try
{
entity["Error"] = "True";
Table.UpdateEntity(Constants.AZURE_STORAGE_ACCOUNT, Constants.AZURE_STORAGE_KEY, Constants.AZURE_TABLE, entity);
}
catch
{
Table.DeleteEntity(Constants.AZURE_STORAGE_ACCOUNT, Constants.AZURE_STORAGE_KEY, Constants.AZURE_TABLE, entity.PartitionKey, entity.RowKey);
}
}
}



Cool uh?!



Here’s how all this works together



image



(*) for a good read on the Azure platform, Worker Roles and Storage (Table, Queues & Blobs) go to: http://bit.ly/SGAzure



You can download the ‘Find my Plane’ for Android and for iPhone.

Read Full Post

Wednesday, December 16, 2009

Windows Azure Web Storage Explorer

A few days ago I posted about my first useful Azure application, which is hosted on here http://storageexplorer.cloudapp.net http://azurestorage.azurewebsites.net. Today I just wanted to announce I just uploaded the code to a Google Code project called windowsazurewebstorageexplorer :)
It is a good (I think is good) example of both programming for the Windows Azure platform and programming against the Windows Azure Storage client API.
So feel free to download it and let me know what you think. (Make sure you download the Windows Azure tools for Visual Studio 2008 first)
As usual, this code is certified to apply every “works on my machine” standard :)
works-on-my-machine-starburst_3
Note: Too bad the December 2009 Windows Azure-Related Developer Challenges are for US only :(

Read Full Post

Wednesday, December 09, 2009

Great programming quotes!

I recently read on stackoverflow a ton of great programmers quotes I thought it’d be good to share.

Here are some of my favorites.

“Walking on water and developing software from a specification are easy if both are frozen.”

“Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.”

“Linux is only free if your time has no value”

“Debuggers don't remove bugs. They only show them in slow motion.”

Read the full list here.

Read Full Post