FlashでTwitterのUserStreamsを受信してみる - さわっても熱くない花火の続き
前振り
なんかUserStreams APIに対応したActionScriptライブラリがあった…
as3twitterlib
git clone http://code.google.com/p/as3twitterlib/
ただ、私の使い方が良くなかったのだろうけど、うまく使えなかったので、自分で書きました。
Streaming APIを受信するサンプルを弄って実装
Streaming APIにBasic認証で繋いで利用するサンプルがありました。それをOAuth化してUserStreams APIを受信したいと思います。
Twitter Streaming APIを使って関連TLをテレビにオーバーレイ表示するAIRアプリを作ってみた - Tosshi Note
ホント参考になりました。感謝感謝!
ソースコード
ほとんど弄って無いので、ソースはっつけて良いのか些か疑問です…問題ならば指摘していただければ幸いです。
TwitterStreamLoader.as
package { import com.adobe.serialization.json.JSON; import flash.events.EventDispatcher; import flash.events.HTTPStatusEvent; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.net.URLRequest; import flash.net.URLRequestHeader; import flash.net.URLRequestMethod; import flash.net.URLStream; import flash.net.URLVariables; import mx.utils.Base64Encoder; import org.iotashan.oauth.*; import org.iotashan.utils.*; import org.httpclient.*; import com.hurlant.crypto.Crypto; import org.flaircode.oauth.*; import org.httpclient.http.*; import org.httpclient.events.*; import flash.net.*; import flash.events.*; import com.adobe.net.URI; [Event(name = "tweetReceived",type = "TwitterStreamEvent")] public class TwitterStreamLoader extends EventDispatcher { private static const ROOT_URL:String = "https://userstream.twitter.com/2/"; private var _authHeader:URLRequestHeader; private var _stream:URLStream; private var _streamBuffer:String = ""; private var consumerKey = "こんしゅーまーきー"; private var consumerSecret = "こんしゅーまーしーくれっと"; public var accessToken:OAuthToken; private var consumer:OAuthConsumer; //myAccessTokenにはアクセストークンな文字列を指定。 public function TwitterStreamLoader(myAccessToken) { super(); accessToken = OAuthUtil.getTokenFromResponse(myAccessToken); consumer = new OAuthConsumer(consumerKey,consumerSecret); } public function loadFilterStream():void { var oauthReq:OAuthRequest = new OAuthRequest("POST",ROOT_URL + "user.json",{oauth_version:"1.0",replies:"all"},consumer,accessToken); var auth:String = oauthReq.buildRequest(new OAuthSignatureMethod_HMAC_SHA1 ,OAuthRequest.RESULT_TYPE_POST); auth = auth.split("&").join("\","); auth = auth.split("=").join("=\""); auth = auth.replace(/,replies=.*/,""); var authHeader:URLRequestHeader = new URLRequestHeader("Authorization","OAuth " + auth); var variables:URLVariables = new URLVariables(); variables["replies"]="all"; var request:URLRequest = new URLRequest(ROOT_URL + "user.json"); request.requestHeaders = [authHeader]; request.method = "POST"; request.data = variables; _stream = new URLStream(); _stream.addEventListener(IOErrorEvent.IO_ERROR, onIoError); _stream.addEventListener(ProgressEvent.PROGRESS, onProgress); _stream.addEventListener(flash.events.HTTPStatusEvent.HTTP_STATUS,function(e:flash.events.HTTPStatusEvent):void{ trace(e.status); }); _stream.load(request); } public function close():void { _stream.removeEventListener(IOErrorEvent.IO_ERROR, onIoError); _stream.removeEventListener(ProgressEvent.PROGRESS, onProgress); _stream.close(); _stream = null; } private function onProgress(event:ProgressEvent):void { dispatchEvent(event.clone()); var buffer:String = _stream.readUTFBytes(_stream.bytesAvailable); _streamBuffer += buffer; var twstr:String; var splitpos:int = _streamBuffer.indexOf("\r\n"); while (splitpos > -1) { twstr = _streamBuffer.substr(0,splitpos); if (twstr.length > 0) { receivedTweet(twstr); } _streamBuffer = _streamBuffer.substr(splitpos + 2); splitpos = _streamBuffer.indexOf("\r\n"); } } private function receivedTweet(str:String):void { var tweet:Object = JSON.decode(str); dispatchEvent(new TwitterStreamEvent(TwitterStreamEvent.TWEET_RECEIVED, tweet)); } private function onIoError(event:IOErrorEvent):void { trace(event.text); trace("IO Error."); } } }
TwitterStreamEvent.as 名前空間以外は参考サイトのソースコードから変更点無し
package { import flash.events.Event; /** * Twitter Stream イベント */ public class TwitterStreamEvent extends Event { /** * イベントタイプ : ツイート受信 */ public static const TWEET_RECEIVED:String = "tweetReceived"; private var _tweet:Object; /** * @return ツイート */ public function get tweet():Object { return _tweet; } /** * コンストラクタ * * @param type イベントタイプ * @param tweet ツイート */ public function TwitterStreamEvent(type:String, tweet:Object = null) { super(type, false, false); _tweet = tweet; } } }
使い方
とりあえず、DMだけを表示できるようにしてみました。
var streamLoader:TwitterStreamLoader = new TwitterStreamLoader("oauth_token=544281054-HLasyE6sqXJNHKOeoQD273Cb14WxBFNmiqaUpNU&oauth_token_secret=LHJ4NiGxcUcnZq09icSLMIzPKDE1tQg9TRm79t22E&user_id=544281054&screen_name=kwsnara"); streamLoader.addEventListener(TwitterStreamEvent.TWEET_RECEIVED, function(event:TwitterStreamEvent):void { if(event.tweet["direct_message"]!=null) { trace(event.tweet["direct_message"]["text"]); } }); streamLoader.loadFilterStream();
余談
UserStreams APIを叩くときは、repliesステータスを指定した方が良さそうです。
ずっと401エラーで悩まされていたのですが、repliesステータスを指定することでなぜかエラーが出なくなりました。
UserStreams APIの戻り値達
Twitter の User Streams で流れてくるやつ — Gist
こんなスバラシイまとめがありました。多謝。