miibotのOAuth対応メモ
TwitterでBasic認証が利用できなくなるらしいので連休を利用してmiibotのOAuth対応をしましたよ、ということで以下は対応手順のメモです。
はじめに
- miibotはGoogle App Engine/Javaで動いています。
- いわゆるbotさんです。OAuth対応といっても、ハードコードした固定のアカウントで認証してつぶやければOK。
botでのOAuth認証
OAuth認証でのAPIアクセスの流れは、大雑把に以下のような感じになります。
- dev.twitter.comにアプリケーションを登録し、consumer key, consumer secretを取得
- consumer key, consumer secretを元に、Twitterのサイトよりrequest token, request secretを取得。
- Twitterの認証サイトで認証。
- request tokenを元に、ユーザーのaccess token,access token secretを取得
- access token,access token secret指定してAPIにアクセス。
ようは、APIにアクセスする場合、最終的にはaccess token,access token secretが必要になるわけです。で、このaccess token,access token secretですが、明示的に無効にしない限り有効(有効期限がない)なので、botではつぶやくアカウントで事前に作成したものをプログラムにハードコードして利用します。
作業メモ
ということで、具体的な作業内容は以下です。
1.dev.twitter.comへのアプリケーションの登録 && access token,access token secretの取得
dev.twitter.comへアプリケーションを登録してoauth token, oauth secretを取得します。さらにbotで使うaccess token,access token secretもdev.twitter.comで作成できるのであわせてGetしておきます。具体的な手順は
星光のつれづれ日記 - twitterのbotなどで OAuthを使う方法(PHPバージョン2)
の解説が分かりやすいのでそちらを参照。(といって逃げる。)
2.botのコード修正
Java向けのTwitterクライアントライブラリ「Twitter4J」がOAuth認証に対応しているのでそれを利用させて頂きました。
以下はTwitterアクセス部分のコードです。
package miibot.service; import java.io.IOException; import java.util.ArrayList; import java.util.List; import twitter4j.Paging; import twitter4j.ResponseList; import twitter4j.Status; import twitter4j.Twitter; import twitter4j.TwitterException; import twitter4j.TwitterFactory; import twitter4j.http.AccessToken; /** * {@link TwitterService} の実装。 */ public class TwitterServiceImpl implements TwitterService { static final String CONSUMER_KEY = "<アプリケーション登録時に作成されるconsumer key>"; static final String CONSUMER_SECRET = "<アプリケーション登録時に作成されるconsumer secret>"; static final String ACCESS_TOKEN = "<botアカウントで作成したaccess token>"; static final String ACCESS_TOKEN_SECRET = "<botアカウントで作成したaccess token secret>"; @Override public Mention[] mentions(String prevId) throws IOException { Twitter t = getTwitter(); try { ResponseList<Status> list = prevId != null ? t.getMentions( new Paging( Long.valueOf(prevId)) ) : t.getMentions(); List<Mention> tmp = new ArrayList<Mention>(list.size()); for ( Status status : list ) { tmp.add(new Mention( String.valueOf( status.getId() ), (String) status.getUser().getScreenName(), (String) status.getText() )); } return tmp.toArray( new Mention[0] ); } catch (TwitterException ex) { throw new IOException(ex); } } @Override public void update( final String msg) throws IOException { Twitter t = getTwitter(); try { t.updateStatus(msg); } catch (TwitterException ex) { throw new IOException(ex); } } private static final Twitter twitter = null; /** * Twitterインスタンスを取得する。 * @return Twitterインスタンス */ private synchronized Twitter getTwitter() { if ( twitter != null ) return twitter; Twitter twitter = new TwitterFactory().getOAuthAuthorizedInstance( CONSUMER_KEY, CONSUMER_SECRET, new AccessToken(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)); return twitter; } }