S-JIS[2010-09-08/2010-09-12] 変更履歴

Twitter4J

Twitter4Jは、Twitterへアクセスする為のJavaのライブラリー。

Twitterへアクセスする為の公式なTwitter APIHTTPで呼び出すので、それを理解していればHTTPクライアントを作るだけでアクセスできるようだが、その部分をTwitter4Jがライブラリー化してくれている。
したがって、Twitter4Jのクラス・メソッドを使用してTwitterにアクセスできる。


インストール

  1. Twitter4Jのページの「ダウンロード」からzipファイル名をクリックして、ダウンロードする。(2010-09-08時点でtwitter4j-2.1.3.zip)
  2. 適当な場所に展開する。(1つのディレクトリーにまとまっていないので、デスクトップ上に展開すると10個くらいのファイル・ディレクトリーが出来るので注意)
  3. EclipseでTwitter用のプロジェクトを新設する。
  4. 展開したファイル類をそこにコピー(あるいは移動)する。まぁ別にワークスペース内に在る必要は無いけど。
    例として、「C:\workspace\twitter\twitter4j-2.1.3」に置いたことにする。
  5. twitter4j-core-2.1.3.jarをビルドパスに追加する。(ソースの添付は「/twitter/twitter4j-2.1.3/twitter4j-core/src」)

ちなみに、twitter4j-examples-2.1.3.jarはTwitter4Jのサンプルプログラム。ソースは「C:\workspace\twitter\twitter4j-2.1.3\twitter4j-examples\src\main\java」。


サンプルプログラム:タイムラインの取得

twitter4j-examplesのGetTimelinesクラスを参考に、タイムライン(TL)を取得して表示してみる。

import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;

import java.util.List;
public final class GetTimelines {

	public static void main(String[] args) {
		System.out.println("■factory.");
		Twitter twitter = new TwitterFactory().getInstance();	//認証なしで接続

		System.out.println("■Showing public timeline.");
		try {
			List<Status> statuses = twitter.getPublicTimeline(); //パブリックタイムラインの取得
			for (Status status : statuses) {
				System.out.println(status.getUser().getName() + ":" + status.getText());
			}
		} catch (TwitterException e) {
			System.err.println(e.getMessage());
			e.printStackTrace();
		}
	}
}

TwitterFactory#getInstance()を呼ぶと、コンソールにログが出力される。
Twitter#getPublicTimeline()を呼ぶと、パブリックタイムラインのツイートが取得される。

■factory.
[Wed Sep 08 02:37:15 JST 2010]Will use class twitter4j.internal.logging.StdOutLoggerFactory as logging factory.
[Wed Sep 08 02:37:16 JST 2010]Will use twitter4j.internal.http.HttpClientImpl as HttpClient implementation.
■Showing public timeline.
〜

Twitter#getUserTimeline()で、特定ユーザーのツイートが取得できる。

			List<Status> statuses = twitter.getUserTimeline("hishidama");

Twitter#showStatus()で、特定のツイート(ステータス)が取得できる。

			Status status = twitter.showStatus(81642112L);

Basic認証

twitter4j-examplesのGetTimelinesクラスには、ユーザーID・パスワードを指定してタイムラインを取得するサンプルも入っている。

		Twitter twitter = new TwitterFactory().getInstance(userId, password);

しかしこれはBasic認証を使用する方法であり、Basic認証は現在廃止になっているので、実行するとエラーになる。

Failed to get timeline: 401:Authentication credentials were missing or incorrect.
{"errors":[{"code":53,"message":"Basic authentication is not supported"}]}

OAuth認証(クライアントアプリケーション)

クライアントアプリケーションでOAuth認証を使ってみる。[2010-09-11]
(OAuth認証を使う為には、事前に自分のアプリケーション専用の認証情報をTwitterから発行してもらう必要がある)

参考: Twitter4JのコードサンプルのOAuth認可

import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.http.AccessToken;
import twitter4j.http.RequestToken;

import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;

import javax.swing.JOptionPane;
	private static final String CONSUMER_KEY    = "Twitter登録時に表示されたConsumer key";
	private static final String CONSUMER_SECRET = "Twitter登録時に表示されたConsumer secret";
	public Twitter loginOAuth() throws TwitterException {

		Twitter twitter = new TwitterFactory().getOAuthAuthorizedInstance(CONSUMER_KEY, CONSUMER_SECRET);

		getOAuthAccessToken(twitter);

		return twitter;
	}
	AccessToken getOAuthAccessToken(Twitter twitter) throws TwitterException {

		//■リクエストトークンの作成
		RequestToken requestToken = twitter.getOAuthRequestToken();
		String url = requestToken.getAuthorizationURL();
//		System.out.println("AuthorizationURL\t" + url);

		//■ブラウザーでTwitterの認証画面を表示する(ここでTwitterにログインすることにより、暗証番号が表示される)
		Desktop desktop = Desktop.getDesktop();
		try {
			desktop.browse(URI.create(url));
		} catch (IOException e) {
			throw new TwitterException(e);
		}

		//■暗証番号の入力を求めるダイアログ
		String pin = JOptionPane.showInputDialog("暗証番号を入力して下さい");
		if (pin == null) {
			throw new TwitterException("暗証番号の入力がキャンセルされました");
		}
		pin = pin.trim();

		//■アクセストークンの作成(認証)
		try {
			AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, pin);
//			System.out.println("AccessToken\t" + accessToken);
			return accessToken;

		} catch (TwitterException e) {
//			System.out.println(e.getStatusCode()); //拒否されると401
			throw e;
		}
	}

Consumer key/secretは、自分のアプリケーション固有の値。
OAuthの登録を行った時に表示された英数字の羅列をコピペする。

  1. OAuthの認証の為に、まず、リクエストトークンを作成する。
  2. ここで生成されたURLブラウザーでユーザーにアクセスしてもらうと、認証を求める画面が表示される。
    (ちなみにURLは「https://twitter.com/oauth/authorize?oauth_token=hogehogeufufu」といった感じ 。「oauth_token=」以降は毎回変わる)
  3. そしてユーザーがログインしてアクセス許可すると、暗証番号が画面上に表示される
  4. その暗証番号を自分のアプリケーションに入力してもらう。
  5. その暗証番号を元にアクセストークンを作成する。(ここでTwitterに接続して認証している模様)
    アクセストークンの作成に成功すれば、以降、Twitterにアクセスできる。

過去に表示された暗証番号は再使用できないようだ。アクセストークン作成時にエラーになる。


アクセストークンの保持

一度認証されたアクセストークンは、保持しておけば何度でも使える。[2010-09-12]
(いちいち暗証番号を確認したり入力したりする必要が無くなる)

以下、シリアライズを使ってアクセストークンをファイルに保存しておく例。

	public Twitter loginOAuth(String name) throws TwitterException {
		Twitter twitter;

		AccessToken accessToken = loadAccessToken(name);
		if (accessToken != null) {
			// 保存されていたアクセストークンを使う
			twitter = new TwitterFactory().getOAuthAuthorizedInstance(CONSUMER_KEY, CONSUMER_SECRET, accessToken);
		} else {
			// 認証して暗証番号を入力してもらい、アクセストークンを保存する
			twitter = new TwitterFactory().getOAuthAuthorizedInstance(CONSUMER_KEY, CONSUMER_SECRET);
			accessToken = getOAuthAccessToken(twitter);
			storeAccessToken(name, accessToken);
		}

		return twitter;
	}
	// アクセストークンをファイルから読み込む
	AccessToken loadAccessToken(String name) {
		File f = createAccessTokenFileName(name);

		ObjectInputStream is = null;
		try {
			is = new ObjectInputStream(new FileInputStream(f));
			AccessToken accessToken = (AccessToken) is.readObject();
			return accessToken;

		} catch (IOException e) {
			return null; //ファイルが読めない(存在しない)場合はnullを返す

		} catch (Exception e) {
			e.printStackTrace();
			return null;

		} finally {
			if (is != null) {
				try { is.close(); } catch (IOException e) { e.printStackTrace(); }
			}
		}
	}
	// アクセストークンをファイルに保存する
	void storeAccessToken(String name, AccessToken accessToken) {
		File f = createAccessTokenFileName(name);
		File d = f.getParentFile();
		if (!d.exists()) {
			d.mkdirs();
		}

		ObjectOutputStream os = null;
		try {
			os = new ObjectOutputStream(new FileOutputStream(f));
			os.writeObject(accessToken);

		} catch (IOException e) {
			e.printStackTrace();

		} finally {
			if (os != null) {
				try { os.close(); } catch (IOException e) { e.printStackTrace(); }
			}
		}
	}
	// アクセストークンを保存するファイル名を生成する
	File createAccessTokenFileName(String name) {
		String s = System.getProperty("user.home") + "/.twitter/client/sample/accessToken_" + name + ".dat";
		return new File(s);
	}

ツイートするサンプル

OAuth認証を使ってツイート(つぶやきを投稿)する例。[2010-09-11]

	void tweet() {
		try {
			Twitter twitter = loginOAuth();           	//毎回暗証番号を入力
//			Twitter twitter = loginOAuth("hishidama");	//初回だけ暗証番号を入力[2010-09-12]

			twitter.updateStatus("Twitter4Jで投稿する実験");
//			twitter.updateStatus("リツィートする実験 RT @hishidama 実験", ステータスID);

		} catch (TwitterException e) {
			System.err.println(e.getMessage());
			e.printStackTrace();
		}
	}

参考: 18.updateStatus() - 陽昇れども地の底に光届かず


ちなみに、アプリをOAuthに登録した際に「Read-only(読取専用)」にしていると、例外が発生して投稿できない。

401:Authentication credentials were missing or incorrect.
{"request":"/1/statuses/update.json","error":"Read-only application cannot POST"}

TwitterException{exceptionCode=[15bb6564-00e304a2], statusCode=401, retryAfter=0, rateLimitStatus=null, version=2.1.3}
	at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:307)
	at twitter4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:72)
	at twitter4j.internal.http.HttpClientWrapper.post(HttpClientWrapper.java:103)
	at twitter4j.Twitter.updateStatus(Twitter.java:496)
	at jp.hishidama.twitter.sample.GetTimelines.tweet(Sample.java:201)
	at jp.hishidama.twitter.sample.GetTimelines.main(Sample.java:60)

Twitter目次へ戻る / Javaへ戻る / 技術メモへ戻る
メールの送信先:ひしだま