Twitter botが作りたい。

普通は始めに覚えるんだろうけど、TwitterAPI(Twitter4j-2.1.8)を使ってのサンプル。

ツイートするとか、する前に、どーするか

 クラスパスのルートに、twitter4j.propertiesを作って入れてあげる。ぼくのツイッターIDはarcanum_jpなので、こうなる。

id=arcanum_jp
oauth.consumerKey=XXXXXXXXXXXXXXXXXXX
oauth.consumerSecret=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


追記:2010/12/17
 上のidを書いてしまうとBASIC/xAuth認証をしようとするので、書かないほうがいいね!

 Twitterクラスのインスタンスを取得する。new Twitter(...)は非推奨らしいので、ファクトリクラスを使用する。ファクトリクラスには例のAccess tokenを入れてあげる。

TwitterFactory tf = new TwitterFactory();
AccessToken at = new AccessToken("**取得したACCESS_TOKEN**", "**取得したACCESS_TOKEN_SECRET**");
Twitter tw = tf.getOAuthAuthorizedInstance(at);

...
// つい〜と
tw.updateStatus("今日も元気だお酒がうまい");
// ダイレクトメッセージ
tw.sendDirectMessage("arcanum_jp", "こんにちは、あいかわらず変ですね。www");
// フォローする
tw.createFriendship("arcanum_jp");
// フォロー解除する
tw.destroyFriendship("arcanum_jp");

追記:2010/12/17
プロパティファイルでヤル必要がないんであれば。プログラム上から入れてしまうのもアリらしい

ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
  .setOAuthConsumerKey(取得したCONSUMER_KEY)
  .setOAuthConsumerSecret(取得したCONSUMER_SECRET)
  .setOAuthAccessToken(取得したACCESS_TOKEN)
  .setOAuthAccessTokenSecret(取得したACCESS_TOKEN_SECRET).setDebugEnabled(true);
TwitterFactory tf = new TwitterFactory(cb.build());

Twitter tw = tf.getInstance();

Twitter botが作りたい。

 Twitter botが作りたくて調べています。botにツイートされたら構文解析してツイートし返すという簡単なものです。いつものツイッターIDでbotを作ってしまうとbot向けにツイートされたものでタイムラインが埋まってしまいますので、いつも使っているツイッターIDと、bot用のIDは分ける必要があるようです。


 Javaの場合はtwitter4jというライブラリがあるらしく、TwitterAPIを生で使うなんてそんな・・・と言うヘタレな僕はこのライブラリを神と崇め使っていきたいと思います。


 Twitterアプリケーションを作る場合はそのアプリケーションをTwitterに登録申請する必要があります。bot用のIDでログインした後、次のURLでTwitterアプリケーションを登録します。

ようこそ開発者のみなさん! Twitterアプリケーションプラットフォーム・ベータ版へ。
連携アプリケーションはまだ始まったばかりですが、開発を手助けするいくつかの機能
を公開しています。今すぐにユーザの皆様をTwitterの世界につなげましょう!

http://twitter.com/oauth_clients/new
  • アプリケーションのアイコン
    • 画像は700KB以下でなくてはいけません。
    • 対応フォーマットはGIF、JPEGPNGです。
    • デフォルトのアイコンは72px x 72pxみたいです。
  • アプリケーション名
    • アプリケーション名を入力する。
    • 「熱いィートbot」とか
  • アプリケーションの説明
    • 説明を入力します。
    • 「フォロワーに熱いメッセージを送り応援するbot」とか
  • アプリケーションのウェブサイトURL
    • Webサイト系のTwitterアプリなんかは、この部分にTopページを入力する
  • 所属会社/団体
    • 個人とか
  • サイト
    • 自分のサイト、ブログとか。
  • アプリケーションの種類
    • クライアントアプリケーション
    • ブラウザアプリケーション
  • コールバックURL
    • アプリケーションの種類が、ブラウザアプリケーションの場合必須
  • 標準のアクセスタイプ
    • Read & Write
    • Read-only
  • Twitterでログインする
    • ユーザーにログインさせて使わせるアプリの場合必要
    • botの場合は不要?

登録に成功すると、次のようなデータが表示されます。

# Consumer key
XXXXXXXXXXXXXXXXXXXXXX
# Consumer secret
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# フォローをリクエストしました。
http://twitter.com/oauth/request_token
# Access token URL
http://twitter.com/oauth/access_token
# Authorize URL
http://twitter.com/oauth/authorize

このConsumer key と Consumer secretがTwitterアプリケーション側で必要になるのでメモしておきます。尚、この画面は、「設定」⇒「コネクション」⇒「連携アプリの追加と設定はこちらから変更できます。」の「こちら」のリンクで見ることができます。


 このConsumer keyとConsumer secretのほかにAccess tokenとAccess token secretが必要です。これは、OpenIDのログインのように、botのIDの認証が必要になり、その後、発行されます。


 Access tokenの取得には、twitter4jのサイトにはサンプルがあります。Eclipseなんかで実行すると、標準出力にURLが出力されますので、このURLをブラウザーに貼り付けて、botのIDで認証を行います。すると、PIN番号が表示されますので、またEclipseなどの実行したところに戻ってこの番号を入力します。

最初はユーザアカウントへのアクセス権がありません。以下のように authorization URLに
ユーザを誘導し、AccessToken を取得する必要があります。

http://twitter4j.org/ja/code-examples.html#oauth


 このサンプルを使う注意点として、最期にTwitter#updateStatus()を使っていますので、先ほどのアプリケーションの登録で入力した「標準のアクセスタイプ」の項目は「Read & Write」である必要があります。あとTwitter#updateStatus()を使用する際の引数がこのサンプルクラスへの実行引数になっているので、面倒な場合はこの引数部分を任意の文字列に変更します。実行したあと、Eclipseなどの実行した標準出力と、bot用のタイムラインにTwitter#updateStatus()で指定された引数が出力されます。



 他にもAccess tokenの取得には以下のページでも公開されています。

以下の TwitterOAuthAccessTokenGetter クラスを利用して、
認可キー(TokenとTokenSecret)を取得する。

http://www.nilab.info/zurazure2/001125.html

以下は、上記のサイトのものをコピペして20行目をちょっと変更しただけです。NI-Labさん、ありがとうございます。こちらの方が「標準のアクセスタイプ」の項目は「Read & Write」である必要はなく分かりやすいようですね。

import java.io.*;
import twitter4j.*;
import twitter4j.http.*;
 
public class TwitterOAuthAccessTokenGetter {
  
  public static void main(String[] args) throws Exception {
    
    // http://twitter.com/oauth_clients/new にてアプリケーションを登録した際の
    // Consumer key と Consumer secret を使用
    String consumerKey = ""; // Consumer key をセット
    String consumerSecret = ""; // Consumer secret をセット
    
    // 認証用URLを取得
    TwitterFactory factory = new TwitterFactory();
    Twitter twitter = factory.getOAuthAuthorizedInstance(consumerKey, consumerSecret);
    RequestToken requestToken = twitter.getOAuthRequestToken();
    String authorizationURL = requestToken.getAuthorizationURL();
    
    System.out.println(authorizationURL);
    System.out.println("認証を許可したらウェブブラウザにPINコードが表示されます。");
    System.out.println("PINコードを入力して[Enter]キーを押してください。");
    
    // 入力待ち
    BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
    String pin = r.readLine();
    
    // AccessTokenオブジェクトを生成 
    AccessToken accessToken;
    if(pin.length() > 0){
      accessToken = twitter.getOAuthAccessToken(requestToken, pin);
    }else{
      accessToken = twitter.getOAuthAccessToken();
    }
 
    // 認証情報を表示
    int userId = twitter.verifyCredentials().getId();
    String token = accessToken.getToken();
    String tokenSecret = accessToken.getTokenSecret();
    System.out.println("UserId=" + userId);
    System.out.println("Token=" + token);
    System.out.println("TokenSecret=" + tokenSecret);
  }
}

 これでAccess tokenとAccess token secretが取得できました。ちなみに先ほど登録したアプリケーションは、「設定」⇒「コネクション」に表示されるようになります。設定を変更したければ、再度、「連携アプリの追加と設定はこちらから変更できます。」の「こちら」のリンクをたどっていきます。


 このAccess tokenを取得する行為ですが、何度もすると当然Access tokenはそのたびに異なります。しかし一度取得したAccess tokenは有効期限がないらしいので、自分のIDにTwitterアプリケーションとしてbotを登録するのであれば1回取得したAccess tokenを未来永劫使い回しでいいのでしょうか。

ご指摘の通り、現在の所 Twitter では Access Token の有効期限を設けていません。
ユーザーがアクセス許可を手動で取り消す可能性がありますので、それに対する対応と同じです。
有効期限向け固有の実装は恐らく必要ありません。
メソッドコール時に例外が発生(恐らく TwitterException.getStatusCode()== 401)したら
Access Token が無効になったという処理にしておけば良いと思います。

http://d.hatena.ne.jp/kenji_jp/20100308/1268064528

※ 改行はnigredoにて行った

 Webアプリ系は、上記のコメントのように401が帰ってきたら再度access tokenを取得する処理へ画面を移行させるのでしょう。botのように未来永劫リッスンし続けるようなアプリの場合はどうすんのかなぁ・・・と思ってしまった。多分何もしなくとも良いんだろうけど。まぁ、それは後で考えるとして・・・

2010/12/14追記:
 たまにAccess Tokenが無効になる。多分Twitter自身が再起動なんかして、無効になるのかな?

 自分ツイートのフッキングはUserStreamListenerの実装クラスであるUserStreamAdapterクラスを継承したものを作ればよいようです。このリスナーインターフェースの説明については、以下に詳しい説明があります。

UserStreamListenerインターフェイスはStatusListenerインターフェイス
サブインターフェイスでUserStreamのデータを受信するために使用します。
StatusListenerで受信出来るデータに加え、デスクトップアプリケーションの
表示の更新をする際に必要な全てのデータを受信出来ます。

http://sites.google.com/site/elekmole/twitter4jtop/streaming-api-method/userstreamlistener


 次に、このアプリケーションをコネクションに追加したユーザーのツイートをツイートされたイベントをフッキングする処理を書く。以下はblog.mtzw.jp/?p=78で公開されているコードのコピペしてちょっと変更。mtzwさんありがとう。

TwitterのStreamingAPIがとても楽しいので、簡単なサンプルコードをのっけてみる。
※twiter4jは2.1.5以上が必要です。

http://blog.mtzw.jp/?p=78


 以下は上記のサイトからコピペしたコードに、自分用のメモとしていくつか追加したものです。

import twitter4j.Status;
import twitter4j.TwitterStream;
import twitter4j.TwitterStreamFactory;
import twitter4j.UserStreamAdapter;
import twitter4j.conf.Configuration;
import twitter4j.conf.ConfigurationBuilder;
import twitter4j.util.TimeSpanUtil;

public class StreamingSample extends UserStreamAdapter {

    static TwitterStream twitterStream;
    static {
        ConfigurationBuilder builder = new ConfigurationBuilder();
        builder.setUseSSL(true);
        // -- 以下は http://twitter.com/apps/new からもらってくる
	builder.setOAuthConsumerKey("ConsumerKey");
        builder.setOAuthConsumerSecret("ConsumerSecret");
        // -- 以下は ConsumerKeyとConsumerSecretを基に取得したもの
        builder.setOAuthAccessToken("AccessToken");
        builder.setOAuthAccessTokenSecret("AccessTokenSecret");
        // -----
        Configuration conf = builder.build();

        twitterStream = new TwitterStreamFactory(conf).getInstance();
    }

    public void start() {
        //ts.setStatusListener(this);	// deprecated
        ts.addListener(this);
        twitterStream.user();
    }

    public void onStatus(Status status) {
        System.out.println(new StringBuilder()
                .append("- ")
                .append(status.getUser().getScreenName())
                .append(": ")
                .append(status.getText())
                .append(" [")
                .append(TimeSpanUtil.toTimeSpanString(status.getCreatedAt()))
                .append("]"));
    }

    public void onException(Exception e) {
        e.printStackTrace();
    }

    void onFollow(User source, User target){
        // source <-- 誰が
        // target <-- 誰をフォローした
        
    }

    void onUnfollow(User source, User target){
        // source <-- 誰が
        // target <-- 誰をフォロー解除した
    }

    public static void main(String[] args) {
        new StreamingSample().start();
    }

} 

 これでこのコードを実行するとストリームが開き、待ち状態になるので、bot用のIDやこのbot用IDフォローしたIDでツイッターでツイートしてみる。そうすると標準出力に出力されます。

 onStatus()でツイートを解析してリツイートやり何なりしてやればよいようです。フォローしていないとこのメソッドは当然ですが呼び出されないので、onFollow()でbotの対象ユーザーをフォローしてやる、onUnfollow()でbotの対象ユーザをフォローの解除をしてあげればよいようです。


 上記のコード、Eclipseで実行すると、ストリームが開きっぱなしになります。何度も実行するとプロセスが複数残ったままになるので、実際のTwiterアプリでは、ストリームを閉じる処理をどっかに記載する必要があるようです。TwitterStream#shutdown()がそれにあたるんだと思います。<-- これウソ

ごにょごにょ玉

こちらの方から、
http://d.hatena.ne.jp/happy_ryo/20101208

キミはもう、ごにょごにょしたか!
のっぴきならない「ごにょごにょ」を、おひゃらかそう!!

http://gonyo-gonyo.appspot.com/

 すばらしい!!現代の「王様はロバの耳」だね。やっぱり同じこと考えていても発想の良い人ってのは面白くするんだよね。ちなみに是非、なにも書かずに「この玉を出す」を押してみてください。大笑いしますよ。

「スティーブ・ジョブズvsビル・ゲイツ (PHPビジネス新書)」を読んだ

スティーブ・ジョブズvsビル・ゲイツ (PHPビジネス新書)

スティーブ・ジョブズvsビル・ゲイツ (PHPビジネス新書)

内容とか

 Macスティーブ・ジョブズと、Windowsビル・ゲイツ、どっちが凄いだろうかという単純な本。それをいくつかの視点(経営力、人物力、突破力、仕事力)に分けて、両者の違いを紹介し、ドッチが凄いかを最期にコメントする本。最期には2人が起業できる環境はと言うものに言及し、では日本では・・・と言う話で結ぶ。どちらかと言うと、ジョブズに軍配が上がるような文章構成・・・僕もあやうくジョブズファンになりそうになった。でも最終的な勝敗はどうだろうか・・・興味のある方は読んでみてください。

感想とか

 「MSXって何の略だ?」「(M)マイクロ (S)ソフト (X)エックスの略らしいよ・・・」とうわさし合った(青)少年の頃から僕らは(名前だけは)知っていたマイクロソフトに親近感を持っていた。そのMSXにもマウスとかGUIがどーたら言われた頃に、マッキントッシュってあるんだってよ・・・マウスでアイコンってのをクリックするとプログラムが起動するらしいってMSXマガジンに載ってたよ。え?アイコンでプログラムが起動・・・どういうこった?なんか未来的だな。そんな(青)少年だったころ、2人は既に起業してバトルを繰り広げていたわけだ。その頃の記憶も相まって2人の生い立ち、起業の様子などは面白く読むことができた。


 読み物としては抜群に面白い。特に第2章の人物力については、2人のハチャメチャ振りに思わず電車の中で笑いそうになってしまった。いやぁ、こんな上司なら付き合いたくないし、付いていきたくないなぁ。うちのボスがかわいいぐらいに見える。それより僕はこの著者の語録にも笑いそうになった。

P93

だが、歳と共に薄くなった髪の毛では、ゲイツに軍配が上がるというと叱られるだろうか。

 おいおい、生い立ちバトルにコレ関係ないし・・・


 あと、2人の特徴をとらえたフレーズがうまい。

P126

 記憶に残るのはジョブズで、記録に残るのはゲイツとも言える

 この人の文章、結構読みやすく僕は好感が持てた。いくつか読んでみたいと思う。

「トロン」を見た


トロン [DVD]

トロン [DVD]

12/17の公開を前に、前作を見た。これは何度か見ているので話の筋は知っている・・・ハズだったが・・・もうすっかり忘れている。前に見たのはかれこれ10年ぐらい前か・・・トロンについての詳細は前にも書いたけど、下記の方にまかせます。すごいです。

先週ゼーガペインの話をしましたが、その際にちょこっとトロンについて触れました。これは82年に公開された映画です。今年の年末に念願の続編、「トロン レガシー」が公開予定ですが、実はその前に一度PCゲームとしてトロンの続編はリリースされています。そのゲームの話はまだいずれ話すとして、今回は初代トロンの映画について書こうと思います。古い映画なので今の若い世代では知らない人も多いかと。

電子世界の幕開け: 我々はCHENJESU。〜W.C.A.Blog〜


 僕らはこのトロンに夢中になったもんだ。今となってはチャチイCGも当時は「なんてすばらしい、広がりがあってカッコいい」って思っていたものです。そのころ小学生だった僕は話の筋なんてサッパリわからずCGだけに夢中になったものです。うちの子供がゴセイジャー!って言っている割には話の筋がサッパリ分かっていないというのと似ています。

 もうすぐ公開・・・見てみたいけど・・・行けるかな?

「東北デベロッパーズコミュニティ忘年会」に行ってきた。

TDC : 東北デベロッパーズコミュニティ忘年会のお知らせ

だんだんと寒くなって参りましたが、みなさまいかがお過ごしでしょうか。
厳しくなる寒さを吹き飛ばすため、東北デベロッパーズコミュニティでは今年も忘年会を行います!

東北デベロッパーズコミュニティ忘年会のお知らせ - TDC - ニュース - 東北デベロッパーズコミュニティ(TDC)

僕の発表

 行ってきました。初LTもしてきました。いろいろ話したいことはあるけど、今回は行動分析学について。使った資料の半分ぐらいしかいえなかった。興味のある人勉強会しませんか!とか言いたかったけど5分間は頭の中が真っ白でした。参考に貼っておきます。


行動分析学
〜モチベーションを科学する〜
nigredo_LT.ppt 直


 あと、脳裏に残った人達(多分、本名も含め、公にしていいと思われる方)。

id:masa_m_0074

 先日行ったドラッカー勉強会について。

半谷 充生さん

 例の社内が英語になったという会社の方。アジャイルについてやってみた感想。

柿沼 清孝さん


 id:kiyolime さん。はてなブログアメブロで、「マンガ共有コミュ【COMEE】管理人のブログ」をやっています。

http://d.hatena.ne.jp/kiyolime/
http://ameblo.jp/kiyolime/

 ツイッターは、 http://twitter.com/kiyotakahive

COMEEについて

 http://comee.jp/

 COMEEとは何ぞや?Webで漫画を投稿するサイト。グリーで働いていて、辞めていまのCOMEEまでのすべて。

・制度の目的
「富県宮城」の実現に向けた取組を加速するため、(財)みやぎ産業振興機構(以下、「振興機構」という。)では、宮城県仙台市・(財)仙台市産業振興事業団(以下、「市事業団」という。)と連携し、地域資源等の活用による創業・新事業展開、産学連携による新製品・新技術開発、高付加価値サービスの創出を支援するため、これらの事業計画を広く募集し、優れた案件と認められるものに対して事業経費の助成を行います。

みやぎ中小企業チャレンジ応援基金事業 | (公財)みやぎ産業振興機構 (公財)みやぎ産業振興機構

id:lemur314

 上司を嫌う前にやる何項目か・・・ネコが・・・

ツイッターID leecomさん

 オトナの特撮もの。あいかわらず話し方がうますぎ。

その他の人(本名言っちゃまずいかなとか、ID知らずな方)

数学ガール」から。

 デザインパターンで有名な結城 浩さんの数学本から。本人の名前の方もゆ(う)きさんときている。

催眠術について

 弊社から一緒に出た人のLT。なるほど人を操ると言う術。おもしろい。


    • 感想

 自分的には柿沼さんのグリー辞めて自分の会社を興すと言うLTはすごかった。2次回でもっとお話したかったが・・・その2次会でもっと凄いことが起こった。「数学ガール」のLTをしたところ、数十分後に、結城さんからツイッターリツイートされた。2次会大盛り上がり。神降臨みたいな。ツイッターってこういうところがすごいんだな。先日読んだ本での「ソーシャルストリーム」がこれにあたるんだろう。


 今回のLTは引かれると思ったがそうでもないみたいだった。次はもっと引かれるものを・・・ウソです。


 あと、名前思い出せず。そのうち書く。

「「激安」のからくり (中公新書ラクレ)」を読んだ

「激安」のからくり (中公新書ラクレ)

「激安」のからくり (中公新書ラクレ)

内容とか感想とか

 激安ジーンズの仕組みから入り、流通業がどうやって激安を実現しているか調査した内容を書く。それは流通業が一貫して製造から販売を行う垂直統合であったり、まず売る価格ありきでその範囲内で利益が取れるように調整する消費者希望価格方式(需給分析方式)であったりします。


 垂直統合があれば、その逆の垂直分裂もあります。工程や機能ごとに複数の企業によって担当される場合です。この垂直分裂は、部品の標準化のたまものなのですが、その反面、企業にとっては独自性を出しづらくなり利益を出す方法として高付加価値化を揚げ、デザイン、BTO方式(注文を受けてから作る)、サービス貿易と発展します。


 その上で、日本の品質ありきの立ち居地が世界のなかではどう写るか、どのようにしなくてはいけないかなどが書かれます。実際には発展途上国において安いものを求めるエントリーユーザーの市場、これを制覇しつつ、そのなかから国が成熟するにつれ、高品質志向製品を出していくという「あれもこれも」の世界です。


 途中にあるコラムも秀逸ですp28〜29にある「大手チェーンを凌駕する「パパママ・ストア」」は僕にとっては転地がひっくり返るような驚きでした。街中にあるどう見てもその価格で経営が成り立っているのか?って感じるようなパパママストア。その成り立つからくり、スーパーの経営システムからはみ出した部分を頂戴する仕組みを紹介します。

感想とか

 先日、ドラッカーでの勉強会や、以前読んだ本でも言っていたように、消費者が求める品質を供給者が勝手に考える考えるのではなく、消費者が考えるということでしょう。いくら品質、品質と言っても、消費者が求めていなければ(市場が成熟していなければ)単に安いほうが勝者ですし、それが市場価格になります。


 本書のH&MやFOREVER21の例にあるように、いくら品質が良くて5年とか長く着る事ができる服を投入したとしても、その買う人達は1年着れればいいやと考えているのであれば、あとの4年の品質にかけるコストは単なる無駄になります。だったらその4年分を安くできるんじゃないかと。


 そこで「最期は品質だよ」と言うのは、供給側の傲慢ってもんでしょう。消費者が求めているものが何か考え(マーケティング)市場の成熟にあわせ品質なりを投入していくというのが大事なんでしょう。激安って今まで悪いイメージを持っていたけど、最近の読んだ本と、あわせて、非常にいい勉強になったなと。