TwitterのStreaming APIをtwitter4j利用で試す＋α

# ゴール：StreamingAPIをちょっと触ってみる！

## 参考情報メモ

* StreamingAPIは3つある

>Public streams：twitterに流れる全てのtweets
User streams：ある単一ユーザーのtweets/timeline
Sites streams：複数のユーザーのtweets/timeline

* 今回は上記の中で「Public streams」を利用するが、この中にもエンドポイントが3種類がある

>statuses/filter：ふるいにかけたtweetsを取得できるAPI。（ただし日本語で検索するにはあまりうれしくなさそう。。「あり」と検索すると「ありがとう」とかひっかかって欲しいけれど、「あり」しかひっかからない模様。ハッシュタグやローマ字ならいけるらしい）
statuses/sample：firehose（すべて）の軽量版。1%程度らしい。1%+1%+…といくらやっても同じ1%なのでfirehoseには及ばない
statuses/firehose：全タイムラインをリアルタイムに取得できるAPI（ただし利用には契約が必要？一般人にはご縁がなさそうです）

* 公式文書はこちら： https://dev.twitter.com/docs/streaming-apis

## さっそく触る！

### 準備〜実行

* javaプロジェクトをつくる
* twitter4jをとってくる　ここから： http://twitter4j.org/ja/index.html
* zipを解凍した後のフォルダの「lib」の中のjarファイルたちを作ったjavaプロジェクトに持って行きパスをとおす
* twitterでdeveloper登録して、アプリを適当に登録（Consumer keyとかが4つ欲しいので）
* クラスをひとつ作る（内容は以下のソース）

```java:Streaming.java
package twitter;

import twitter4j.StallWarning;
import twitter4j.Status;
import twitter4j.StatusDeletionNotice;
import twitter4j.StatusListener;
import twitter4j.TwitterStream;
import twitter4j.TwitterStreamFactory;
import twitter4j.conf.Configuration;
import twitter4j.conf.ConfigurationBuilder;


public class Streaming {
    private static final String CONSUMER_KEY = "自分のアプリのもの";
    private static final String CONSUMER_SECRET = "自分のアプリのもの";
    private static final String ACCESS_TOKEN = "自分のアプリのもの";
    private static final String ACCESS_TOKEN_SECRET = "自分のアプリのもの";
	
    static class MyStatusListener implements StatusListener {

        public void onStatus(Status status) {
            System.out.println("Status: " + status.getText());
            //	System.out.println("@" + status.getUser().getScreenName() + " | " + status.getText() + " 【 https://twitter.com/" + status.getUser().getScreenName() + "/status/" + status.getId() + " 】");
            // こんな感じでstatusについている名前とかを色々表示させるとさらに欲しい情報にたどり着けると思います
        }

        public void onDeletionNotice(StatusDeletionNotice sdn) {
            System.out.println("onDeletionNotice.");
        }

        public void onTrackLimitationNotice(int i) {
            System.out.println("onTrackLimitationNotice.(" + i + ")");
        }

        public void onScrubGeo(long lat, long lng) {
            System.out.println("onScrubGeo.(" + lat + ", " + lng + ")");
        }

        public void onException(Exception excptn) {
            System.out.println("onException.");
        }

		@Override
		public void onStallWarning(StallWarning arg0) {
			// TODO Auto-generated method stub
			
		}
    }

    public static void main(String[] args) throws Exception {
        Configuration configuration = new ConfigurationBuilder().setOAuthConsumerKey(CONSUMER_KEY)
                .setOAuthConsumerSecret(CONSUMER_SECRET)
                .setOAuthAccessToken(ACCESS_TOKEN)
                .setOAuthAccessTokenSecret(ACCESS_TOKEN_SECRET)
                .build();
        
        TwitterStream twStream = new TwitterStreamFactory(configuration).getInstance();
        twStream.addListener(new MyStatusListener());

        twStream.sample();
    }
}
```

* あとはこれを実行するだけ！

### ハマったポイント１　〜proxyってどこに設定するの？〜

* twitter4j.properties というのをつくってそこに設定する。このファイルはプロジェクト直下においた
* 詳しくはここ：http://twitter4j.org/ja/configuration.html

``` twitter4j.properties 
http.proxyHost=proxy.なんとか
http.proxyPort=8080
http.proxyUser=ゆーざー
http.proxyPassword=ぱす
```

### ハマったポイント２　〜Error 401 Unauthorizedって言われる〜

* キーとかあってるはずなのにおこられる！！！

``` 
401:Authentication credentials (https://dev.twitter.com/pages/auth) were missing or incorrect. Ensure that you have set valid consumer key/secret, access token/secret, and the system clock is in sync.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Error 401 Unauthorized</title>
</head>
<body>
<h2>HTTP ERROR: 401</h2>
<p>Problem accessing '/1.1/statuses/sample.json?stall_warnings=true'. Reason:
<pre>    Unauthorized</pre>
```

* 開発環境とは別にEC2たててjarに固めたのをやったら動いた。。ので複数接続が出来ない罠にハマっていたかも。。ソースは合ってることもあるので怒られたら別環境で試してみるのもありですねφ(ﾟ0ﾟ*) ﾌﾑﾌﾑ…φ(｡_｡*)ﾒﾓﾒﾓ…