Twitter4jでつぶやく
ClojureでTwitterのbotを作ろうと思い、TWitterライブラリを探してみたら、Twitter4Jは扱いが簡単そうだったので試してみた。
Twitter4Jは最新の安定バージョンである2.1.0を使用した。
まずは、Twitter4Jのサンプルコードを参考に、つぶやくコードを書いてみた。
(ns twitter.hellobot (:import (twitter4j TwitterFactory Twitter))) (def user-id "******") (def password "******") (def twitter (. (TwitterFactory.) getInstance user-id password)) (. twitter updateStatus "Hello, world!")
実行すると、twitterインスタンスの取得でエラーとなる。
(def twitter (. (TwitterFactory.) getInstance user-id password)) ←◆ここでエラー
getInstanceメソッドが見えないようだ。
No matching method found: getInstance for class twitter4j.TwitterFactory [Thrown class java.lang.IllegalArgumentException] Restarts: 0: [ABORT] Return to SLIME's top level. Backtrace: 0: clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:85) 1: clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:28) 2: clojure.lang.Compiler$InstanceMethodExpr.eval(Compiler.java:1150) 3: clojure.lang.Compiler$DefExpr.eval(Compiler.java:298) 4: clojure.lang.Compiler.eval(Compiler.java:4537)
何が原因が良く分からないので、とりあえずclojureのバージョンを1.1.0に上げて試してみたら、以下のエラーとなった。
Can't call public method of non-public class: public java.lang.Object twitter4j.TwitterFactoryBase.getInstance(java.lang.String,java.lang.String) [Thrown class java.lang.IllegalArgumentException] Restarts: 0: [ABORT] Return to SLIME's top level. Backtrace: 0: clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:85) 1: clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:28) 2: clojure.lang.Compiler$InstanceMethodExpr.eval(Compiler.java:1206) 3: clojure.lang.Compiler$DefExpr.eval(Compiler.java:302) 4: clojure.lang.Compiler.eval(Compiler.java:4647) 5: clojure.core$eval__5236.invoke(core.clj:2017)
バージョン1.1.0ではエラーメッセージが親切になっている。
TwitterFactoryBaseクラスはTwitterFactoryクラスの親クラスであり、そのクラスがgetInstanceメソッドを実装している。エラーを見ると親クラスTwitterFactoryBaseも可視属性がpublicでないと駄目のようだ。
リフレクションの仕様?時間ができたら調べてみよう。
面倒になってきたので、twitter4jのソースを修正し、TwitterFactoryBaseクラスをpublicにしてみる。
twitter.hellobot> (def twitter (. (TwitterFactory.) getInstance user-id password)) #'twitter.hellobot/twitter twitter.hellobot>
正常にインスタンスを取得できたようだ。
一歩前進だが、いきあたりばったり方式でちょっと鬱。
twitterインスタンスが取得できたので、つぶやいてみる。
twitter.hellobot> (. twitter updateStatus "hello, world!") #<StatusJSONImpl StatusJSONImpl{createdAt=Sat Jan 30 21:32:43 JST 2010, id=8409854604, text='hello, world!', ...以下略... twitter.hellobot>
http://twitter.com/ で確認してみる。
書き込めた。\(^▽^)/
Twitter4Jは依存ライブラリが無いので、jarファイル一つで済むので、なかなか良いです。
オープンソースで公開して頂ける作者に感謝です。