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
こんなスバラシイまとめがありました。多謝。