ActionScriptからTwitterAPIを使いたい時にGoogle App Engineをプロキシにすれば簡単
ActionScriptからTwitterAPI使う時は、クロスドメイン対応の為に、phpでプロキシ作ったりするらしいけど、
BlazeDSとTwitter4jでプロキシ作るのも良いんじゃないかな。
S3BlazeDS使えばGoogle App Engineでも動くし、
BlazeDS使えばRemote呼び出しできるのでTwitter4jの使いやすさをActionScriptでも実現できる。
んで、テキトーに作った。
とりあえずTL取得だけですが、
ポップアップ等つかってOAuth認証してもらえば何でもできるんじゃないかと
こいつをBlazeDに登録して使います。
TwitterAPI.java
public class TwitterAPI { //TL取得 public List<Status> getUserTimeline(String screenName) throws TwitterException { Twitter twitter = new TwitterFactory().getInstance(); List<Status> rs = twitter.getUserTimeline(screenName); return rs; } }
Twitter4jのクラスを変換できるように変換クラスを作成します。
(デフォルトコンストラクタが無いクラスは作る必要あり)
とりあえずめんどくさいのでStatusのtextプロパティのみ対応。他のプロパティやクラスも同じ要領で作ればOK。
StatusProxy.java
public class StatusProxy extends BeanProxy { private static final long serialVersionUID = 1L; @Override public Object createInstance(String className) { return new StatusStub(); } @Override public Object getValue(Object instance, String propertyName) { Status i = (Status) instance; if (propertyName.equals("text")) { return i.getText(); } throw new IllegalArgumentException("Illegal propertyName. " + propertyName); } @Override public void setValue(Object instance, String propertyName, Object value) { StatusStub s = (StatusStub) instance; if (propertyName.equals("text")) { s.text = (String) value; } else { throw new IllegalArgumentException("Illegal propertyName. " + propertyName); } } @Override public Object instanceComplete(Object instance) { return instance; } @Override public List<String> getPropertyNames(Object instance) { return Arrays.asList("text"); } class StatusStub implements Status { /** * */ private static final long serialVersionUID = 1L; String text; @Override public String getText() { return text; } @Override public RateLimitStatus getRateLimitStatus() { // TODO Auto-generated method stub return null; } @Override public Annotations getAnnotations() { // TODO Auto-generated method stub return null; } @Override public String[] getContributors() { // TODO Auto-generated method stub return null; } @Override public Date getCreatedAt() { // TODO Auto-generated method stub return null; } @Override public GeoLocation getGeoLocation() { // TODO Auto-generated method stub return null; } @Override public HashtagEntity[] getHashtagEntities() { // TODO Auto-generated method stub return null; } @Override public String[] getHashtags() { // TODO Auto-generated method stub return null; } @Override public long getId() { // TODO Auto-generated method stub return 0; } @Override public String getInReplyToScreenName() { // TODO Auto-generated method stub return null; } @Override public long getInReplyToStatusId() { // TODO Auto-generated method stub return 0; } @Override public int getInReplyToUserId() { // TODO Auto-generated method stub return 0; } @Override public Place getPlace() { // TODO Auto-generated method stub return null; } @Override public long getRetweetCount() { // TODO Auto-generated method stub return 0; } @Override public Status getRetweetedStatus() { // TODO Auto-generated method stub return null; } @Override public String getSource() { // TODO Auto-generated method stub return null; } @Override public URLEntity[] getURLEntities() { // TODO Auto-generated method stub return null; } @Override public URL[] getURLs() { // TODO Auto-generated method stub return null; } @Override public User getUser() { // TODO Auto-generated method stub return null; } @Override public UserMentionEntity[] getUserMentionEntities() { // TODO Auto-generated method stub return null; } @Override public User[] getUserMentions() { // TODO Auto-generated method stub return null; } @Override public boolean isFavorited() { // TODO Auto-generated method stub return false; } @Override public boolean isRetweet() { // TODO Auto-generated method stub return false; } @Override public boolean isRetweetedByMe() { // TODO Auto-generated method stub return false; } @Override public boolean isTruncated() { // TODO Auto-generated method stub return false; } @Override public int compareTo(Status o) { // TODO Auto-generated method stub return 0; } } }
変換クラスを登録するBootStrapサービス
service-config.xmlで設定する。
SerializerBootstrapService.java
public class SerializerBootstrapService extends AbstractBootstrapService { @Override public void initialize(String id, ConfigMap properties) { } @Override public void start() { PropertyProxyRegistry.getRegistry().register(Status.class, new StatusProxy()); } @Override public void stop() { PropertyProxyRegistry.getRegistry().clear(); } }
Flex側
TL取得のサンプル
<fx:Declarations> <s:RemoteObject id="twitteAPI" showBusyCursor="true" destination="TwitterAPIService"/> <s:ArrayCollection id="tweets"> </s:ArrayCollection> </fx:Declarations> <fx:Script> <![CDATA[ import mx.collections.ArrayCollection; import mx.collections.ArrayList; import mx.controls.Alert; import mx.rpc.AsyncResponder; import mx.rpc.AsyncToken; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; private function getUserTimeline(userName:String):void{ var token:AsyncToken = twitteAPI.getUserTimeline(userName); token.addResponder( new AsyncResponder( function(re:ResultEvent, obj:Object=null):void{ tweets = re.result as ArrayCollection; tweets.addAll(tweets); }, function(ee:FaultEvent, obj:Object=null):void{ Alert.show(ee.message.body.toString()); trace(ee); } ) ); } ]]> </fx:Script> <s:TextInput id="f_userName" text="kissrobber"/> <s:Button label="get" click="getUserTimeline(f_userName.text)"/> <s:List dataProvider="{tweets}" labelField="text"> </s:List>
Statusクラス
package as_twitterapi_proxy.io { [RemoteClass(alias="twitter4j.StatusJSONImpl")] public class Status { public var createdAt:Date; public var id:Number; public var text:String; public var source:String; public var truncated:Boolean: public var inReplyToStatusId:Number; public var inReplyToUserId:int; public var inReplyToScreenName:String; public var getLocation:Object; public var favorited:Boolean; public var user:Object; public var retweet:Boolean; public var retweetedStatus;Status; public function Status() { } } }