今回は、認証が必要な Twitter APIMathematica 8 から使う話。認証不要な API に関しては、前回記事を参照のこと。
認証が必要な Twitter API とは、例えば新たな発言をするとか自分のアカウント向けの発言を見るなどの、Twitter にログインしないとできない操作に対応するコマンドのこと。本稿執筆時点で Twitter API の認証には、OAuth という仕組みを使う必要がある。Mathematica 8 では、 J/Link を使って Java のライブラリを利用して実現するのが簡単そうだ。そこで、矢吹さんのブログ記事 http://blog.unfindable.net/?p=788 に載っていた Java コードを参考にして作ってみた(というか、単に J/Link に劣化ポートしてみた)、というのが今回の内容だ。元記事の著者の矢吹さんは、ブログを見る限りかなり凄腕の Mathematica プログラマーなので、僕が下手をかぶせる形になるのは恐れ多いのだが、こういうポート情報に興味のある人もきっといるはず、ということで。

認証を使うので当然だが、以下の内容を試すには、Twitter のアカウントが必要だ。また、将来 Twitter API の仕様が変わって動作しなくなる可能性があるのは前回同様。

準備として、http://dev.twitter.com/apps の「新しいアプリケーションを登録する」で登録作業を行ない、Consumer keyConsumer secret を取得する必要がある。アプリケーションの種類は「クライアントアプリケーション」、アクセスタイプは「Read&Write」にしておく。ここで言う「アプリケーション」は、Twitter API を利用するプログラムのことで、今回の場合は、Twitter API を利用する Mathematica プログラムを指す。スタンドアロンソフトを作るのでも公開予定があるわけでもないのにアプリ登録というのもなんだか変な感じだが、この手順は OAuth のためには必須。僕は今回は Moriyas test by Mathematica という名前で登録してみた。

まだ準備がある。 OAuth のための Java ライブラリだ。 Commons Codec のサイト http://commons.apache.org/codec/ からダウンロードできるファイルを展開した中にある commons-codec-1.4.jar と、oauth-signpost のサイト http://code.google.com/p/oauth-signpost/ からダウンロードできる signpost-core-1.2.1.1.jar を同じフォルダに置いておく(いずれも本記事執筆時点に確認したバージョン)。そして、この同じフォルダの中に、新しく Mathematica ノートブックファイルを作成/保存する。これでようやく準備完了だ。

OAuth では、アプリが作成した認証用のアドレスをウェブブラウザで開くことで得られる暗証番号を使って Access token と Secret key を生成し、この token と key を使って API コマンドを実行することになる。いちど生成した token と key は2回目以降も使えるのでファイルに保存しておき、このファイルがあるときには生成はせずにファイルから読み込むようなものを作ることにする。上で保存したノートブックを開き、下記のようなスクリプトを書いて評価実行すると、 token と key を取得することができる。赤字の部分は、準備で取得した Consumer key と Consumer secret に置き換える必要がある。

Needs["JLink`"];
tokenfile = "savedtoken";
SetDirectory[NotebookDirectory[]];
AddToClassPath[NotebookDirectory[]];
consumer = JavaNew["oauth.signpost.basic.DefaultOAuthConsumer",
  "*** consumer key ***", (* <- 取得した Consumer key *)
  "*** consumer secret ***"]; (* <- 取得した Consumer secret *)
genTokenFile[] := Module[{provider, pin, res},
  provider = JavaNew["oauth.signpost.basic.DefaultOAuthProvider",
   "https://api.twitter.com/oauth/request_token",
   "https://api.twitter.com/oauth/access_token",
   "https://api.twitter.com/oauth/authorize"];
  LoadJavaClass["oauth.signpost.OAuth"];
  SystemOpen[
   provider@retrieveRequestToken[consumer, OAuth`OUTUOFUBAND]];
  pin = InputString["ブラウザで表示された暗証番号を入力して下さい。"];
  If[$Canceled == pin || ! IntegerQ[ToExpression[pin]],
   Print["暗証番号の入力に問題があります。"]; Abort[]];
  provider@retrieveAccessToken[consumer, pin];
  Put[res = {consumer@getToken[], consumer@getTokenSecret[]},
   tokenfile];
  res]
{token, tknsecret} = If[MemberQ[FileNames[], tokenfile],
  Get[tokenfile], genTokenFile[]];
consumer@setTokenWithSecret[token , tknsecret];

実行すると、「アプリケーションが、あなたのアカウントへの接続を要求しています」と書かれたウェブページが開き、ここで「許可する」を選択すると暗証番号が表示される。この暗証番号をコピーして Mathematica に戻り、暗証番号入力用のダイアログ(小さな独立ウィンドウ。他のウィンドウの下に隠れてしまいやすいので注意)が開いているので入力して OK ボタンをクリック。何も出力されないが、何事もなく評価終了すれば OK。初回の実行で、token と key はファイルに書き出されるので、次回以降の実行時は、ブラウザを開いて許可を求める処理は行なわれない。

ようやく Twitter API を実行するところにたどり着いた。とりあえず、もっともポピュラーな「投稿する」を試してみることにしよう。投稿が成功したら、 HTTP レスポンスから情報を切り出して該当投稿を表示する URL を構築し、ウェブブラウザで開くようにしてみた。(プロキシ対応は未確認。追加する必要があるはず)

tweet = "Mathematicaから投稿してみるテスト。文字列操作関数と\
組み合わせてMathematica独自のものができるといいのだが、今回は単に投稿だけ。";
LoadJavaClass["java.net.URLEncoder"];
url = JavaNew["java.net.URL",
  "http://api.twitter.com/1/statuses/update.json?status=" <>
   StringReplace[URLEncoder`encode[tweet, "UTF-8"], "+" -> "%20"]];
connection = url@openConnection[];
connection@setRequestMethod["POST"];
consumer@sign[connection];
httpResponseCode = connection@getResponseCode[];
If[httpResponseCode === HttpURLConnection`HTTPUOK,
  br = JavaNew["java.io.BufferedReader",
   JavaNew["java.io.InputStreamReader", connection@getInputStream[]]];
  res = StringJoin[
   Most@NestWhileList[br@readLine[] &, "", # =!= Null &]];
  json = ImportString[res, "JSON"];
  SystemOpen[
   "http://twitter.com/" <> ("screen_name" /. ("user" /. json)) <>
    "/status/" <> ("id_str" /. json)];
 , "不具合が起きたようです。Status code: " <> ToString[httpResponseCode]]

これで、認証の必要不必要に関わらず、任意の Twitter API を Mathematica で使用できるようになった。
察しの良い読者はお気づきのように、ここまで来たら Mathematica を使ってかなり自由に Twitter-bot を作ることができる。例えば、長野の気温(WeatherData["Nagano", "Temperature"] で取得できる)を定期的に投稿するような bot や、自分のアカウント宛の mention 投稿に方程式が含まれていたらそれを解いた結果を投稿する bot など、いろいろ考えられそうだ。

...のだが、他の Twitter ユーザーが「サービス」としてその投稿を享受できるような使い方は、Mathematica の使用許諾に抵触してしまう可能性が高い。bot のような、自動で定期的に実行するような形での使用は、残念ながら避けた方が賢明だ。念のため、開発元 Wolfram Research 社にも確認してみたが、「Allowing people to access Mathematica functionality (like Plot[Sin[x], ...]) via Twitter (or any other means) is not allowed by the license agreement.(Twitter やその他の手段を介して、人々が Mathematica の機能を利用できるようにすることは、使用許諾で許されていません)」との回答だった(2011/02/10; TS 4455)。

言語の能力としては容易に実現できるのに、ライセンスの問題でやっちゃダメ(Amateur Edition でない webMathematica Professional Edition という高価な年間ライセンス製品を買えば可だが)だなんて。せっかくの Mathematica 言語の魅力をそいでしまっている思うのは、僕だけじゃあるまい。残念。

※この記事の内容は執筆者の個人的見解で、ヒューリンクスによる公式情報ではありません。[免責事項]

トラックバック

この記事へのトラックバックURL
http://blog.hulinks.co.jp/cgi/mt/mt-tb.cgi/461
内容に対しての関連性がみられないものは削除する場合があります

このたびの大震災で被災された方々を思うと、胸が苦しい。亡くなられた方々の冥福を祈... 続きを読む

コメントの投稿

Emailアドレスは表示されません。は必須項目です。
ヒューリンクス取り扱い製品の内容や購入に関するお問い合わせはヒューリンクスサイト連絡先へお願いいたします。投稿前にその他の注意事項もご覧ください。

HULINKS サイトの新着情報