Saturday, May 19, 2012

Vala tutorial: Twitter Authentication

I'm just starting to learn Vala as it appears to be one of the most swiftly-growing languages for open-source development. It's fast like C/C++ but supposedly a lot more intuitive and generally less hateful. We'll see. Anyway, there doesn't seem to be a lot of great instructive material for it floating around the ether, so I decided I'd try to give back here and there with a brief tutorial.

Here goes:

1. Install librest

I'm using Ubuntu as my development platform, so my installation step was
sudo apt-get install librest-dev

2. Register Your App on Twitter

This step is fairly straight forward. Create a profile on Twitter's developer page and then start a new project. For this tutorial, you'll need to change the settings for you project such that it has read/write/direct privileges for tweets.

3. The code:

To see a nice copy with syntax highlighting, click here. Otherwise the code can be found at the bottom of the post, sans syntax-highlighting.

4. Compile:

someone@someone-UBook:~/workspace/vala/twitter$ valac --pkg rest-0.7 simpletweet.vala -o simpletweet

5. Execute:

someone@someone-UBook:~/workspace/vala/twitter$ ./simpletweet "Test 2"
Go to http://twitter.com/oauth/authorize?oauth_token=0RKxDFc5NFWoucwubsdGxfBMl37ZHWFhTnggbCVnZA then enter the PIN
6408330
Tweet succeeded!

Conclusion

As this is a simple demonstration, the user is forced to do the very tedious authentication step repeatedly. My guide is primarily an adaptation of Ross Burton's tutorial, in which he suggests storing the authentication credentials in GNOME's keyring; however, I don't know how to do that yet. If you have questions or comments, post 'em up.

simpletweet.vala :



using Rest;

public class SimpleTweet {
 private static const string CONSUMER_KEY = "#######################"; // this comes from your app's twitter account page
 private static const string CONSUMER_SECRET = "########################################"; // this comes from your app's twitter account 
 private static const string URL_FORMAT = "https://api.twitter.com";
 private static const string REQUEST_TOKEN_URL = "https://api.twitter.com/oauth/request_token";

 private static const string FUNCTION_ACCESS_TOKEN = "oauth/access_token";
 private static const string FUNCTION_STATUSES_UPDATE = "1/statuses/update.xml";

 private static const string PARAM_STATUS = "status";

 public static int main(string[] args) {
  // make sure there is a message to tweet
  if(args[1] == null || args[1] == "") {
   stdout.printf("No tweet message specified.\n");
   return 0;
  }

  /** Authenticating with Twitter */
  // initialize proxy
  var proxy = new OAuthProxy(CONSUMER_KEY, CONSUMER_SECRET, URL_FORMAT, false);

  // request token
  try {
   proxy.request_token("oauth/request_token", "oob");
  } catch (Error e) {
   stderr.printf("Couldn't get request token: %s\n", e.message);
   return 1;
  }

  // prompt user for pin
  stdout.printf("Go to http://twitter.com/oauth/authorize?oauth_token=%s then enter the PIN\n", proxy.get_token());
  string pin = stdin.read_line();

  // access token
  try { proxy.access_token(FUNCTION_ACCESS_TOKEN, pin); }
  catch (Error e) {
   stderr.printf("Couldn't get access token: %s\n", e.message);
   return 1;
  }

  /** sending the tweet */
  // setup call
  ProxyCall call = proxy.new_call();
  call.set_function(FUNCTION_STATUSES_UPDATE);
  call.set_method("POST");
  call.add_param(PARAM_STATUS, args[1]);
  try { call.sync(); } catch (Error e) {
   stderr.printf("Cannot make call: %s\n", e.message);
   return 1;
  }

  // print success
  stdout.printf("Tweet succeeded!\n");

  return 0;
 }
}

No comments:

Post a Comment