Introducing TwitterAspirin: an AS3 Twitter API painkiller

 

A couple months ago, I started working on a Twitter component for my current project at Adobe. I went into this knowing I’d have to finally face the beast… OAuth. Just about every well-known Twitter client out there uses Basic Auth—and for a reason. It’s easy, what the user expects, and gives your app more credibility—there’s no requirement to leave to authenticate through the browser like with OAuth.

About five or six months ago, Twitter decided to enforce the transition. From then on, any application that uses the API must use OAuth in order to see “via [your app]” on tweets published with it—otherwise, it would display “via API.” Since “via” is where apps get probably 90% of their referrals, this was a big deal. Luckily for me, DestroyTwitter existed before that time and Twitter decided not to push the change on the veteran apps. Recently, however, the bad news spread that Basic Auth would be deprecated in June. This means every Twitter app must transition to the pain that is OAuth.

After developing the MAX Companion this past fall and now the more generalized version, I found myself rewriting the Twitter component each time. After a while, the Twitter API code I wrote for DestroyTwitter began to merge with the actual implementation, so it was no longer a standalone library that could easily be used by other projects. These past few months, I’ve been learning a great deal about framework architecture and design patterns. It has led me to realize I need to start fresh.

With all that being said, I’d like introduce a library I started working on two days ago. I call it TwitterAspirin. It’s an AS3 Twitter API library that eases the pain, providing developers with a very powerful tool for communicating with Twitter. Though it’s still a newborn at the moment, I see potential already. The library is built on RobotLegs and uses AS3 Signals instead of events. It’s hosted on GitHub, so the source code will always be available to the public. And, after last night’s commit, its OAuth functionality is complete. Here’s how to use it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package {
	import com.destroytoday.twitteraspirin.Twitter;
 
	import flash.display.Sprite;
 
	public class Test extends Sprite {
		// set application consumer key and secret
		public var twitter:Twitter = new Twitter(consumerKey, consumerSecret);
 
		public function Test() {
			// add signal listeners
			twitter.oauth.requestTokenSignal.add(requestTokenHandler);
			twitter.oauth.accessTokenSignal.add(accessTokenHandler);
			twitter.oauth.verifyAccessTokenSignal.add(verifyAccessTokenHandler);
		}
 
		// click the 'Authorize' button to get the request token
		protected function authorizeClickHandler():void {
			twitter.oauth.getRequestToken();
		}
 
		// upon receiving the request token, open Twitter in the browser to authorize
		protected function requestTokenHandler(oauth:OAuth, token:OAuthToken):void {
			navigateToURL(new URLRequest(oauth.getAuthorizeURL()));
		}
 
		// return with the provided pin and click the 'Activate' button to get the access token
		protected function activateClickHandler():void {
			twitter.oauth.getAccessToken(pin);
		}
 
		// upon receiving the access token, verify it
		protected function accessTokenHandler(oauth:OAuth, token:OAuthToken):void {
			oauth.verifyAccessToken(token);
		}
 
		// done
		protected function verifyAccessTokenHandler(oauth:OAuth, token:OAuthToken):void {
		}
	}
}

As you can see, it’s extremely easy to use. Not only that, it provides great flexibility. Many libraries are simple to implement, but don’t allow the developer access to certain aspects of the process. With TwitterAspirin, each method returns the loader involved with the operation, giving developers the ability to listen for errors, cancel the operation, or attain the raw API data. The library also uses loader pools to recycle instances, so you can submit a tweet and, while it’s loading, submit another—you don’t have to wait for the first operation to finish. Then, once the operation is complete, the loader is disposed and returned to the pool, which optimizes performance and memory usage.

I’m really excited to see where TwitterAspirin goes and I have nothing but great expectations. Be sure to follow along with development and fork whenever you like.

14 replies

  1. That can’t be it, surely – Where’s all the pain gone?

    Seriously cool looking class!

  2. I will test it, looks very good, Thanks for share it with the comunity.

  3. This is actually my first time looking at any Twitter API but I see that it is similar in many ways to the Facebook API. When that was getting built there was a lot of discussion around the practice of compiling your “secret” into your .swf as it could be decompiled and used by the forces of evil. Do you have any plans to work around that?

    This does get me thinking about using signals with the Facebook API. I’m just starting to catch the signals fire and I really like the way it makes your API look.

    Good luck with this beast! And good job already, I like the API.

  4. @Jason — To be honest, I didn’t think about the vulnerability of the secret. I’m not sure what harm can be done though, since the user would still need to authenticate with their credentials to retrieve an access token before doing anything. Maybe it’s more a vulnerability for the developer, but even then, all they could manage is to falsely display “via [your app]“. If there’s something I’m missing, fill me in.

  5. Yea, the vulnerability would be for the developer; authentication would still need to happen so not a big worry there. With Facebook the power to abuse the trust of a popular app is potentially quite dangerous but I suppose with a Twitter client the damage really isn’t that great. I suppose there isn’t much to worry about; I just saw the similarity and thought I would bring it up.

  6. @Jason — I appreciate it.

  7. Nicely done. Thanks for sharing.

  8. What’s the next step to use it? I’ve only used PHP to post messages to twitter.

  9. @Steve — I’ll slowly roll out other methods in the API over the next few weeks. I finished the getUser method earlier, so that might give you an idea. Once authenticated, you’d just need to call twitter.users.getUser(id, screenName). It’s an either or thing, so if you only have the ID, use that and leave screenName blank. If you only have the screen name, set id to NaN. Then listen to the twitter.users.getUserSignal.

  10. Something you can experiment with is returning the Signal instance from your service method. Then you can chain this together:

    twitter.oauth.getRequestToken().add(requestTokenHandler);

    Now your consuming code doesn’t have to know the name of the signal for the service method.

  11. @Robert — I did consider that, but it would prevent the ability to listen to the error and cancel signals. It does look nice as one line though. It could work if I dispatch both success and fail with the same signal and use a boolean value to indicate which.

  12. Funny you should mention that. That’s what I had been doing for quite a while with my “commands”; one “callback” which could switch on “success” and error properties. The code was really short and looked nice but having two distinct methods for handling sits much better with me. http://pbking.com/blog/?p=211 <- a post about that very think I wrote a short bit ago.

  13. nice work Jonnie, is this an AIR only project? getting some error on manageCookies if I try it in a web app.

  14. @Peter — The GeneralLoader class from DestroyFramework uses some AIR-only properties. You can certainly modify it and re-compile the swc and replace the current one in TwitterAspirin’s lib folder.

Reply