無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

miibotのOAuth対応メモ

TwitterBasic認証が利用できなくなるらしいので連休を利用してmiibotのOAuth対応をしましたよ、ということで以下は対応手順のメモです。

はじめに

  • miibotはGoogle App Engine/Javaで動いています。
  • いわゆるbotさんです。OAuth対応といっても、ハードコードした固定のアカウントで認証してつぶやければOK

botでのOAuth認証

OAuth認証でのAPIアクセスの流れは、大雑把に以下のような感じになります。

  1. dev.twitter.comにアプリケーションを登録し、consumer key, consumer secretを取得
  2. consumer key, consumer secretを元に、Twitterのサイトよりrequest token, request secretを取得
  3. Twitterの認証サイトで認証。
  4. request tokenを元に、ユーザーのaccess token,access token secretを取得
  5. 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クライアントライブラリTwitter4JOAuth認証に対応しているのでそれを利用させて頂きました。

    • Twitter APIへののアクセスは、呼び出している機能が少ないこともあってjava.netを使って独自に行っていたのですが、この際なので全面的にTwitter4Jを使う方向で書き換えました。
    • 使っている機能が少ないのであれですが、とりあえず「つぶやきの登録」「言及の取得」機能ははGAE環境でも問題なく動いています! すごい!

以下は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;
    }
}