PerlでTwitterアプリ開発の導入メモ - Net::Twitter

(※)最初に注意書き

この記事の記述は、Twitterのボットアプリ、つまりDesktop appの例で書いています。TwitterのWebアプリを作る場合はcallbackの実装などが必要のため別にまとめました、こちらをご参照ください。

はじめに

ものすごく今さらな話だけど、2012年10月11日よりTwitterAPIが結構大きく変更された。さらに2013年6月からは旧API(v1.0)が廃止され、v1.1しか使えなくなった。1.1への変更点としては……。

  • XML形式のサポートが無くなり、JSON形式のみのサポートとなった
  • rate limits(単位時間あたりのAPI利用回数制限)がキツくなった
  • 全てのエンドポイントでOAuth必須となった
  • APIのURLにバージョン番号が挟まれるようになった。具体的には、https://api.twitter.com/1.1/statuses/mentions_timeline.json のように。

その他詳細は、公式ページのhttps://dev.twitter.com/docs/api/1.1/overviewを参照。

私も以前、流行りに乗って(?)Twitterのボットを作っていたのだけど(http://homepage1.nifty.com/y-osumi/works/code/twitter_bot.htm)、Net::OAuthとXMLのパーサで自分でゴリゴリやる感じで書いていたので、気が付いたら10月11日から動かなくなっていた。

ということでPerlのNet::Twitterモジュールを使うことにして今さら直したのだけど、色々忘れてしまっていたので、PerlTwitterアプリを作る際のとっかかりメモを残しておく。という自分用メモがこの文章の目的。

APIを利用するまでの流れ

色々あちこちで書かれているので今さら私が書くまでも無いんだけど……TwitterAPIを利用してボットがTweetするには、以下の流れの感じで設定する必要がある。なお、ボットの場合はPIN-based authorizationを利用することになる。

  • まずTwitterの開発者向けページ(Twitter Developer Platform — Twitter Developers)に自分の普段のアカウントでログインし、"My applications" から自分のアプリを登録する。
  • 登録したアプリの設定ページで、アプリに払い出されたConsumer keyとConsumer secretを取得する(メモする)。
  • Consumer keyとConsumer secretを用いてAPIの/oauth/request_tokenを叩き、Request TokenとRequest Token Secretを取得する。
  • いま取得したRequest TokenとSecretを用いてAPIのoauth/authorize(https://dev.twitter.com/docs/api/1/get/oauth/authorize)のURL組み立て、ボットのアカウントでログインし、アプリに許可を与えてPINコードを取得する(メモする)。
  • いま取得したPINコードと、Request TokenとRequest Token Secretの3つをAPIの/oauth/access_token(https://dev.twitter.com/docs/api/1/post/oauth/access_token)に投げて、Access tokenとAccess Token Secretの2つを得る。
  • Consumer keyとConsumer secretとAccess tokenとAccess Token Secret、の4つセットを用いてAPITweetする。

色々と登場人物が多くてややこしいけど……最終的には、アプリのConsumer keyとConsumer secret、そしてアカウントのAccess TokenとAccess Token Secret、の4つだけあれば良い。そのため、Access TokenとそのSecretの発行までは最初の1回だけやれば良い。

どうしてこんなメンドいことになっているかと言うと。まず、アプリに直接Twitterアカウントとパスワードを入れるのは、アプリの制作者に悪意があった場合、パスワードを勝手にどこかへ送信するかもしれないので良くない。Access TokenとAccess Token Secretをアプリごと(Consumer keyごと)に発行するこの形式ならば、たとえAccess Tokenが盗まれても他のアプリでは使えないから意味ないし、Twitter自体のパスワードも盗まれないわけだ。

また、Access Tokenが盗まれたことが分かった時点でTwitterの設定ページにログインしてアプリへの許可を禁止すれば、盗んだ人が該当アプリ経由で何かすることもできなくなるので、結局のところ何もできず安全。ということになる。

Consumer Key とSecretの取得

Twitterの開発者ページ https://dev.twitter.com/ に自分のふだんのアカウントでログインし、右上のアカウントのところから My applications → Create a new application とする。

必須項目は"Name", "Description", "Website"の3つなので、実質何も無くても登録はできる。でもまぁ、それなりのWebとアイコンを用意してからやった方が気分も盛り上がって良いかも。

できたらConsumer keyとConsumer secretが発行されているので、これをメモっておく。

Access TokenとSecretの取得

では続けて、今作ったアプリに対する、ボットアカウントのAccess TokenとそのSecretを取得してみる。一つ一つ手でやると発狂しそうになるので、PerlのモジュールNet::Twitterを利用すると良い。

perldoc Net::Twitter::Role::OAuth するといろいろ例が載っているので、それを参考にしてこんな感じのを書いてみる。

#!/usr/bin/perl
use strict;
use Net::Twitter;

my $nt = Net::Twitter->new(
  traits => ['API::RESTv1_1'],
  consumer_key => "YOUR-CONSUMER-KEY",
  consumer_secret => "YOUR-CONSUMER-SECRET",
);

print "Login URL: ", $nt->get_authorization_url, "\n";
print "Enter the PIN#\n";
my $pin = <STDIN>;
chomp $pin;

my($access_token, $access_token_secret, $user_id, $screen_name) = $nt->request_access_token(verifier => $pin);
print "Access Token: $access_token\n";
print "Access Token Secret: $access_token_secret\n";

このスクリプトを実行すると、まず「Login URL: 」と表示されるので、そのURLにIEなりFirefoxなりWebブラウザでアクセスする。Twitterの認証画面となるので、ボットのアカウント(普段の自分のアカウントではない)でTwitterにログインする。

ログイン後に数字のPINコードが表示されるので、スクリプトに戻って、「input verifier PIN :」にこのPINコードを入力してEnterキーを押す。するとAccess TokenとAccess Token Secretが表示されるのでこれをメモしておく。

ここまでやれば、もうこのスクリプトは以後は必要無い。Consumer keyとConsumer secret、そしてアカウントのAccess TokenとAccess Token Secretの4つが揃ったので、あとはこの4つを使って色々操作できるようになった。

Tweetの一番簡単なサンプル

Access TokenとSecretが取れれば、後は簡単だ。Net::Twitterでツイートするサンプルを以下に載せる。

#!/usr/bin/perl

use strict;
use warnings;
use Net::Twitter;

my $consumer_key = 'xxxxxxxxxxxxxxx',
my $consumer_secret = 'yyyyyyyyyyyyyyyy',
my $token = 'zzzzzzzzzzzzzzzzzzzzzzzz';
my $token_secret = 'xyzxyzxyzxyzxyzxyz';

my $nt = Net::Twitter->new(
   traits => ['API::RESTv1_1'],
   consumer_key => $consumer_key,
   consumer_secret => $consumer_secret,
   access_token => $token,
   access_token_secret => $token_secret,
);

my $result = $nt->update('Hello, world!');

見ての通り、Net::Twiterオブジェクトを作ってupdateメソッドを使うだけで呟くことができる。ああ、なんと楽チンだ。

返事をするサンプル

ただつぶやくだけではつまらんので、せっかくだから話しかけられたら返事をする動きを実装してみよう。

話しかけられたつぶやき(自分への@付きのつぶやき)のことを、Twitterでは mention と呼んでいる。そのためこのmentionを取得して、応答すれば良い。

my $nt = Net::Twitter->new(
   traits => ['API::RESTv1_1'],
   consumer_key => $consumer_key,
   consumer_secret => $consumer_secret,
   access_token => $token,
   access_token_secret => $token_secret,
);

my $res = $nt->mentions();
print Dumper($res);

mentionを取得するmentionsメソッドにはsince_idなど引数が設定でき、上記の例のように省略すると最新20件を取得する。mentionsメソッドの戻り値(ここでは$res)は、mentionのハッシュリファレンスが最大20個の無名配列となって返ってくる。実際にDumperでprintしてみればすぐ見られるので、ここでは中身は載せない(長いし)。

mentionsメソッドの戻り値は、APIから返されるJSONをそのままPerlのデータ構造にしているだけなので、APIhttps://dev.twitter.com/docs/api/1.1/get/statuses/mentions_timelineを見ながらコーディングすれば良い。

mentionsを取得したら、一個一個取り出して処理する感じで返答できるだろう。

foreach my $mention (@$res) {
  my $mention_text = $mention->{text};
  my $screenname = $mention->{user}->{screen_name};
  my $userid = $mention->{user}->{id};

  (ここで、取り出したtextなどを用いて返答を$nt->update で行う)
}

とりあえずこんな感じ。