Getting Flash and Twitter to play nice.
by Martin on 18/04/2008Attention!
This code was written by a far less awesome version of me and using it is strongly discouraged. You should go here and use that code instead. Do it. You’ll thank me.
I’m an avid user of Twitter. I’m also a Flash developer so it figures I had created a Twitter badge in Flash to display on my old blog. I even had a tutorial on how to do it. The thing is; Twitter all of a sudden decided to close off their feeds to Flash. By changing their crossdomain.xml 1 the pretty much messed up any Flash apps out there talking to Twitter. A tad frustrating, but oh well.
This just means we’ll have to be a bit more creative when we create Twitter stuff. To get the Actionscript and the clever solution for the cross domain issue, read on.
So. Firstly we’ll have to get around the cross domain issue. Well, luckily I stumbled over a solution. Yahoo Pipes is a pretty awesome mashup tool which allows you to mess around with the feeds from different sources. Specifically this ‘pipe’ is relevant to our problem. You’ll need your twitter ID which is the last string of numbers if you click on the RSS-icon at your twitter homepage. Plug it in at the pipe and snatch the URL for the feed.
We’re ready to write some Actionscript. Here goes nothing.
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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | package { import flash.display.Sprite; import flash.net.URLRequest; import flash.net.URLLoader; import flash.text.*; import flash.events.Event; public class TweetPipeLoad extends Sprite { var twitURL:URLRequest; var twitLoader:URLLoader; var tx:XML; var regExp:RegExp; var processed:Array; public function TweetPipeLoad (userId:String){ /*Long ass url to the yahoo pipe * processed twitter feed.*/ twitURL = new URLRequest("http://pipes.yahooapis.com/pipes/pipe.run?_id=4b85031723ba7785e277add01b0169c5&_render=rss&twitter="+userId); twitLoader = new URLLoader(twitURL); twitLoader.addEventListener(Event.COMPLETE, onComplete); /*Let's create an Array for the * tweets after they're loaded. */ processed = new Array(); /*Reg exp: Regular expressions. Black magic. * This particular one checks for URLs in the string * so we can make them clickable.*/ regExp = new RegExp( /(ftp|http|https)://(w+:{0,1}w*@)?(S+)(:[0-9]+)?(/|/([w#!:.?+=&%@!-/]))?/); } private function onComplete(e:Event) : void { /*This function is called when the Pipe URL is done loading * hence the name 'onComplete'. Lets check that it contains * valid data and store the information in a XML object. */ if(twitLoader.data){ tx = new XML(twitLoader.data); /*Next: Check for the occurrence of '@' in the tweet. If so * we'll assume the tweet is in response to someone else, * in which case we don't want it on our badge. I don't, anyway. * If the string doesn't contain any @s we push it to the array.*/ for (var i:int = 5; i<tx.children()[0].children().length(); i++){ var curTweet:String = tx.children()[0].children()[i].children()[2]; if (curTweet.indexOf("@") <= -1 && !regExp.test(curTweet)){ processed.push(curTweet); } else /*We also check for URLs using the RegExp from earlier. * If we find a url in the string we wrap it in <a> tags * to make it clickable. At the end we push the string to the array.*/ if(curTweet.indexOf("@") <= -1 && regExp.test(curTweet)){ var urlstr:Array = regExp.exec(curTweet); var justUrl:String = curTweet.substr(urlstr.index,urlstr.toString().length); var linkedUrl:String = "<a href='" + justUrl + "'>" + justUrl + "</a>"; var newTweet:String = curTweet.replace(justUrl,linkedUrl); curTweet = newTweet; processed.push(newTweet); } } } /*Dispatch an event to let listeners know * that the tweets have been loaded and processed.*/ this.dispatchEvent(new Event("TweetComplete",true,false)); } /*The getTweets() - method should be called only * after the "TweetComplete" event is dispatched. * It takes one optional argument. If you want the * tweets to appear without the leading "username: " * you can fill out your username and it will * automagically be removed from the string.*/ public function getTweets(userDecap:String = null) : Array { if(userDecap != null){ for (var i:int = 0; i< processed.length; i++){ processed[i] = processed[i].substring(userDecap.length + 2); } return processed; } else { return processed; } } } } |
This can almost certainly be improved upon, but it works quite well. Let’s have a look at the usage, which is fairly simple.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import net.parallaxdenigrate.TweetPipeLoad; var tpl:TweetPipeLoad; var processed:Array; /*set up a new instance and pass the Twitter user id*/ tpl = new TweetPipeLoad("200523"); /*Listen for the event dispatched when the Tweets are loaded*/ tpl.addEventListener("TweetComplete", onTweetComplete); function onTweetComplete(e:Event):void { /*Fire the getTweets() method and pass your username as an argument.*/ processed = tpl.getTweets("martinj"); for each (var item:String in processed){ trace(item) } } |
There. That’s all there is to it.
Example files here.
There are 20 comments in this article: