GAE/j上でtwitter4jを使ってtwitterAPIを利用する

はじめに

 今回は、Google App Engine for Java(以下GAE/j)からtwitterAPIを利用して、tweetの投稿を行おうと思う。ただし、偉大なる先人により、GAE/jからでもtwitterAPIを利用できるライブラリが公開されている為、
Twitter4J - A Java library for the Twitter API
 今回はこのライブラリを利用させて頂き、まずはそのサンプルコードをGAEjava上で実行してみる。
 尚、今回の内容を進める間に何度か、ローカルのテスト環境で503エラー(SERVICE_UNAVAILABLE)が発生した。これはプロジェクトの作り直しやPCの再起動などで解決してしまったので、原因不明で再現性無しという、なんとも気持ち悪い結果となってしまった。もしも同じ症状になった方がいましたら、僕に変わって原因を調べて下さい。……え?
 (10/18追記)この503エラーでは、そもそもGAE公式サンプルのゲストブックすら動かない、かなり不思議な状態になっていました。その辺りも含めて、原因の分かる方がいましたら、コメント欄などにご一報下さい(追記ここまで)

twitter APIとは

 APIとは、公式の文言*1を簡単にまとめると、外部アプリケーションからデータを利用できる様にする窓口の事だ。そして、twitterの場合にはそのプロトコルにHTTPを利用している。
 twitter APIの構成だが、これは大きく分けて三つからなる。それは、二つのRepresentational State Transfer(REST) APIとStreeming APIからできているそうだ*2。その違いについては、とりあえず保留しておく。

OAuth認証の準備

 twitter APIにおいて、ユーザの操作をプログラムで代行する場合、OAuthによる認証を行う必要がある。OAuth自体の説明は既に詳しいページが存在し*3、ここで扱うと本題から離れてしまう為、割愛する。
 さて、具体的なやり方であるが、まずはtwitter側にOAuth認証を利用するアプリケーションを登録する必要がある*4
 まずは持っているtwitterアカウントでログインし、設定画面を開く。その後、連携アプリを選択する。すると、許可した連携アプリの一覧が表示されるが、その右側に「連携アプリの追加と設定はこちらから変更できます。」という文章が小さく書かれている。ここのリンク先を開くと、「新しいアプリケーションを追加」というリンクがあるので、それをクリック。「アプリケーション登録申請」画面が開くので、最低限以下の項目を記入する。

  • アプリケーション名
    • 他と被らない名前でなければならない。「Twitter」という言葉を含む名前は付けられない
  • アプリケーションの説明
    • 開発中は適当でOK。最低限10文字以上
  • アプリケーションのウェブサイトURL
    • アプリケーション公開時には、GAEjavaの公開ページを指定する。今は適当に
  • アプリケーションの種類
    • GAEから利用する前提なので、「ブラウザアプリケーション」を選択
  • コールバックURL
    • OAuth認証完了後に戻るページ。開発中はやはり適当に
  • Default Access type
    • ここでは読み書きが出来るように「Read & Write」を選択
  • Twitterでログインする
    • 今回はこれを利用して、ユーザ認証まで行う

 全ての項目は後から編集できるので、あまり神経質にならなくて良い。とりあえずここまで書けたら、画像文字認証を正しく入力して「保存する」。
 成功すれば、「Application Details」が表示され、開発に必要な情報が参照できる。このページは先程の「連携アプリの追加と設定はこちらから変更できます。」からまたいつでも来れるので、必要になった時に見に来よう。

twitter4jの準備

 続いて、twitterを利用する為のライブラリ、twitter4jを利用できる様に設定する。まずはこちらから、twitter4jをダウンロードしよう。
Twitter4J - A Java library for the Twitter API
 ダウンロードしたzipを展開し、好きな場所に置こう。現段階では、このまま置いておけば良い。

サンプルプログラムの準備

 今回はtwitter4jのサンプルTwitter4J - コード例より、「8.Twitterアカウントによるサインイン」に示されている、sign-in-with-twitterをGAE上で動作させてみる。まずはサンプルコードを入手しよう。
 サンプルを入手したら、それらを扱う為のプロジェクトを作成する。使うのはもちろん、NetBeansである*5。ちなみに、現段階のNetBeansでは「新規のGAEプロジェクト」を生成する事ができない様だ(自分だけですか?)。とりあえず今回は、サンプルプログラム「Guestbook」を生成して、そのプロジェクト名を変更するという手法を取った。
 プロジェクトを作成したら、ここにサンプルコードを順次追加していく。netBeansのプロジェクトウィンドウに直接投げ込んでいけばOK。
 最終的には、次の構成になっていれば良い。

 Guestbookサンプルから関係するjspServletが削除され、twitter4jのサンプルプログラムからjsp, Servlet, tags, imagesが追加、そしてライブラリにはtwitter4j-coreを読み込む。ライブラリの読み込みは、プロジェクトウィンドウ上で「ライブラリ」を右クリック、「JAR/フォルダを追加...」から先程展開したtwitter4jのディレクトリからtwitter4j-core-x.y.z.jar(x.y.zはバージョン番号)を選択すれば良い。
 また、プロジェクト名やServletのパッケージ名は適当に決めた物なので、各自で自由につければ良いと思われる。

設定の変更

web.xmlの書き換え

 サンプルプログラムで使用するServletをURLに対応させる。web.xmlを開き、以下の変更を行う。この際、servlet-classにはパッケージ名まで含めた正確なクラス名を入力する。

<!-- 削除
    <servlet>
        <servlet-name>guestbook</servlet-name>
        <servlet-class>guestbook.GuestbookServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>guestbook</servlet-name>
        <url-pattern>/guestbook</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>sign</servlet-name>
        <servlet-class>guestbook.SignGuestbookServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>sign</servlet-name>
        <url-pattern>/sign</url-pattern>
    </servlet-mapping>
-->

<!-- 追加 -->
    <servlet>
        <servlet-name>signin</servlet-name>
        <servlet-class>twitter4JSample.SigninServlet
        </servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>signin</servlet-name>
        <url-pattern>/signin</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>logout</servlet-name>
        <servlet-class>twitter4JSample.LogoutServlet
        </servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>logout</servlet-name>
        <url-pattern>/logout</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>callback</servlet-name>
        <servlet-class>twitter4JSample.CallbackServlet
        </servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>callback</servlet-name>
        <url-pattern>/callback</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>post</servlet-name>
        <servlet-class>twitter4JSample.PostServlet
        </servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>post</servlet-name>
        <url-pattern>/post</url-pattern>
    </servlet-mapping>

<!-- 変更 -->
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
sessionの許可

 今回のサンプルでは、その動作にsessionを利用している。sessionとは、jspがページ間でデータを受け渡す為の機構である。これは、Cookieなどに一時的に保存され、ブラウザを閉じるなどすると破棄される*6
 これを利用する為には、appengine-web.xmlに以下の一文を追加する必要がある。

<sessions-enabled>true</sessions-enabled>
OAuthの設定

 twitter4jでは、OAuthの為にtiwtterから発行されたconsumerKey/Secretをtwitter4j.propertiesというファイルに記述して利用する、様に見える。しかし、GAEjava上で動作させる場合、これがうまくいかない。これを解決する方法が、こちらの記事*7に書かれていた。
 これもやはり、appengine-web.xmlを編集する。具体的には、以下の二文を追加すれば良い。

    <system-properties>
        <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
        <!-- 追加ここから -->
        <property name="oauth.consumerKey" value="{取得したconsumerKey}"/>
        <property name="oauth.consumerSecret" value="{取得したconsumerSecret}"/>
        <!-- 追加ここまで -->
    </system-properties>

動作テスト

 以上の設定が終了したら、NetBeansの実行ボタンを押そう。正しくファイルのコピー、設定ができていれば、twitterアカウントでログインし、そのアカウントにつぶやきを投稿できるはずである。
 一応、以下のページにGAEjava上にデプロイしたサンプルプログラムを公開しておく。
Sign in with Twitter example

まとめ

  • twitter4jを使う事で、twitter APIを用意に利用できる
  • GAE上で利用する場合、OAuthのKet/Secretを書く場所に注意が必要である
  • 503エラーがでたら、是非根本的解決策を見つけてください

次回

 ただサンプルを動かすだけで、予想以上に時間がかかってしまった。また、実際にこの通りに動かしてみれば分かるが、想定していただろう動作が実現できていない所がある。具体的には、ログイン後の画面でユーザIDがうまく表示できない。
 そこで次回はまず、サンプルプログラムを読解し、OAuthによってユーザ認証を行う正確な流れを把握したい。
 その後、ユーザ名の取得やユーザタイムラインの取得を行う改造を行ないたい。これは、次々回に行う。