2014年11月21日

PHPのTwitterライブラリ「codebird.php」でログイン認証をしてツイートを投稿する話

倫理的な問題で連投機能が廃止された「鳩子ジェネレーター」ですが、それ以外の機能は稼働中です。どうぞ(なにがだw)

さてさて、そんな鳩子ジェネレーターに実装しようとした連投機能ですが、実装に際してライブラリを使用しました。
PHPで有名なTwitterライブラリは「twitteroauth.php」ですが、こいつはここ数年全く更新されてないので、使用するのはちょっと不安です。(ちなみに使ってみましたが14/11/20現在普通に動きましたし情報も多めなので完全に悪とは言いません)

というわけで今も活発に(?)開発されている「codebird.php」を使用してみました。
とはいえこいつ、とにかく日本語の情報が少ない。結構苦労しましたので、ここに日本語の情報を残しておいておこうと思います。

さて、まずは基本的なTwitterの認証の下準備について話しておこうと思います。
Twitterで実際にツイートを投稿するためには最低4つの鍵が必要となります。
それぞれを「ConsumerKey」「ConsumerSecret」「AccessToken」「AccessTokenSecret」と呼びます。まずこいつを手に入れましょう。

こいつを手に入れるには、TwitterDevelopperにアクセスして、アプリケーションを新規作成する必要があります。(いわゆるvia名取得ってやつです)

右上のメニューからTwitterのアカウントIDとPWを用いてログイン後、めちゃちっちゃくてわかりにくいんすけど、画像の通り右下の「Manage Your Apps」を選択してアプリケーションの新規作成画面に飛びます。
14_11_21_01.png

その後はCreate New Appを押して、適当にフォームを埋めて、アプリケーションを作成します(他のサイトに死ぬほどある情報なのでざっくり説明だけに留める)
14_11_21_02.png14_11_21_03.png

アプリ作成後、アプリアイコンをクリック、Settingsタブでアイコンを指定します(しなくても良いんだけどした方がかわいいよかわいいかわいいかわいい)
14_11_21_04.png14_11_21_05.png

続いてParmissionタブを選択し、利用したいものに応じてアクセスレベルを指定します。
・ツイートの取得だけが必要な場合はReadOnly
・ツイートの投稿も必要な場合はRead and Write
・ツイートの読み書きだけでなくダイレクトメッセージ(DM)も利用したい場合はRead, Write and Access direct messages

この辺りは状況によってまちまちなのでお任せします。今回は連投機能が欲しかったのでRead and Writeにしました。

最後に、Keys and Access Tokensタブを開き、「ConsumerKey」と「ConsumerSecret」をメモします。
冒頭で話した必要となる鍵のうちの2つです。英数字で書かれている暗号です。人に漏らしちゃいけません。扱いは慎重にしてください。
14_11_21_07.png

また、この「ConsumerKey」と「ConsumerSecret」の下の方に「AccessToken」と「AccessTokenSecret」も記載されています。TwitterBot等、このvia名を他の人が使う目的がなく、自分自身のみが使う、という場合はこいつも使って必要な鍵とします。この場合、鍵が4つ揃ってるので、これでおしまいですね。

そうではなく、Twitterクライアントの作成や、今回のような連投機能が欲しい場合には、アプリケーション製作者(がお)ではなく、アプリケーション利用者(どこかの誰か)自身が発言できるようにする必要が有るため、「AccessToken」と「AccessTokenSecret」は別の方法で取得します。(以下に表記)

(イメージとしては、ConsumerKey,Secretは"アプリケーション自体"に関連する情報を持つ鍵のID&PWで、AccessToken,Secretはアプリケーションを"利用する人"に関する情報をもつ鍵のID&PWみたいなもんです。厳密には違いますが。)




さて、すっかり前置きが長くなってしまいましたが、本題です。手に入れた「ConsumerKey」と「ConsumerSecret」を用いて、「codebird.php」のライブラリから「AccessToken」と「AccessTokenSecret」を取得します。

codebird.phpのインスタンスは以下のようにして作成します。ここはテンプレみたいに思ってください。

index.php(codebird.phpとは同一ディレクトリに置いてるとします)

require_once ('codebird.php');

define('CONSUMER_KEY', 'ここに先ほど手に入れたConsumerKeyを入力します');
define('CONSUMER_SECRET', 'ここに先ほど手に入れたConsumerSecretを入力します');

//名前空間利用しててキモいですがこれがConsumerKey&Secretを指定する静的メソッドです
\Codebird\Codebird::setConsumerKey(CONSUMER_KEY, CONSUMER_SECRET);

//↑でConsumerKey&Secretを指定したあと、こいつでインスタンスを生成します。
$cb = \Codebird\Codebird::getInstance();

/*以下にやりたいことを書きまくって行く感じです*/

こんな感じ。PHPの名前空間の記法のキモさを除けばそんなに難しい部分はないはずので問題無いですよね?


で、話を戻しますが、AccessTokenを手に入れるには、先にRequestTokenというものを手に入れなければなりません。
ConsumerKey&Secretを用いて、RequestTokenを取得後、RequestTokenを利用して、特定の認証ページにユーザを誘導、ユーザーが認証したら、その時初めてAccessTokenが得られるっていう流れです。
(よく見かけるような、以下の画像の画面が、特定の認証ページのことです)
14_11_21_08.png

話がややこしくなってきましたので再度言いますが、
・アプリ自体のID&PWがConsumerKey&Secret
・ユーザー情報のID&PWがAccessToken&Secret
・AccessToken&Secretを取得する際の認証に使うワンタイムID&PWがRequestToken&Secret
です。混同しないようにしましょう。

さて、では実際にRequestTokenを用いてAccessTokenを取得するコードを書きましょう。
(※index.php - getAccessToken.php間の情報の受け渡しにセッションを使います。セッションが何か分からない人はググってください。)


getAccessToken.php(codebird.phpとは同一ディレクトリに置いてるとします)

session_start();
require_once ('codebird.php');

// api 登録して取得した文字列を入れます
define('CONSUMER_KEY', 'ここに先ほど手に入れたConsumerKeyを入力します');
define('CONSUMER_SECRET', 'ここに先ほど手に入れたConsumerSecretを入力します');
//define('CALLBACK_URL', '認証後にリダイレクトして欲しいURLを指定します(今回はindex.phpです)');
define('CALLBACK_URL', 'http://www.hogehoge/index.php');

//テンプレ
\Codebird\Codebird::setConsumerKey(CONSUMER_KEY, CONSUMER_SECRET);
$cb = \Codebird\Codebird::getInstance();
//curlを使うと不具合が起こるという場合は以下を指定するとfile_get_contentsを用いて通信するようになります。
//$cb->setUseCurl(false);

//ConsumerKey&Secretの情報を元に、RequestTokenを取得します。
$reply = $cb->oauth_requestToken(array(
'oauth_callback' => CALLBACK_URL
));

//何らかの原因でRequestTokenが手に入らなかったら、しぬ。
if(!isset($reply->oauth_token) || !isset($reply->oauth_token_secret)){
echo "error: getAccessToken.php\n";
exit;
}

//得たRequestTokenは「$変数名->oauth_token」「$変数名->oauth_secret」に入っている
$cb->setToken($reply->oauth_token, $reply->oauth_token_secret);
$_SESSION['oauth_token'] = $reply->oauth_token;
$_SESSION['oauth_token_secret'] = $reply->oauth_token_secret;
$_SESSION['oauth_verify'] = 1;

//$cb->setToken()を用いてRequestTokenを設定したので、認証URLを作成し、リダイレクトする
$auth_url = $cb->oauth_authorize();
header('Location: ' . $auth_url);

index.php(codebird.phpとは同一ディレクトリに置いてるとします)

session_start();
include_once ('codebird.php');

define('CONSUMER_KEY', 'ここに先ほど手に入れたConsumerKeyを入力します');
define('CONSUMER_SECRET', 'ここに先ほど手に入れたConsumerSecretを入力します');

//getRequestToken.php でセットした oauth_token と一致するかチェック
if (!isset($_SESSION['oauth_token']) || !isset($_REQUEST['oauth_token']) || ($_SESSION['oauth_token'] !== $_REQUEST['oauth_token']) || !(isset($_GET['oauth_verifier']) && isset($_SESSION['oauth_verify']))) {
echo "認証していません\n";
unset($_SESSION);
}
else{
//おなじみのテンプレ
\Codebird\Codebird::setConsumerKey(CONSUMER_KEY, CONSUMER_SECRET);
$cb = \Codebird\Codebird::getInstance();
//$cb->setUseCurl(false);

//認証が通った RequestToken を用いてAccessTokenを取得します
$cb->setToken($_SESSION['oauth_token'], $_SESSION['oauth_token_secret']);
unset($_SESSION['oauth_verify']);
$reply = $cb->oauth_accessToken(array(
'oauth_verifier' => $_GET['oauth_verifier']
));

//AccessTokenが取得できなかったら、しぬ。
if(!isset($reply->oauth_token) || !isset($reply->oauth_token_secret)){
unset($_SESSION);
echo "AccessTokenが取得できませんでした。RequestTokenが期限切れの可能性があります\n";
}
else{
//手に入れたAccessTokenは今後ずっと使えるので大切にsessionに保管しておく
$_SESSION['access_token'] = $reply->oauth_token;
$_SESSION['access_token_secret'] = $reply->oauth_token_secret;

/*AccessTokenが無事手に入ったので、以下煮るなり焼くなり好きにしろ*/
}
}


というわけで、これでAccessTokenが手に入ったので、ツイート取得とかつぶやきとかし放題というわけですね。

ちなみに余談ですが、AccessTokenを取得するためには、必ずTwitterのRequestToken認証を挟みます。
この性質を利用すれば、Twitter側のログイン情報を元に、自分のサイトのログイン認証を行うことも出来ます。物は使いよう、こういうのは応用編っすね。(この話はまた今度するかもしれないししないかもしれません)


さてさて、話を戻して、得た4つの鍵「ConsumerKey」「ConsumerSecret」「AccessToken」「AccessTokenSecret」を用いて、codebirdで何かを呟くには以下のように記載します。

postTwitter.php(中核となる部分以外は全部省略してます)

session_start();
require_once ('codebird.php');

define('CONSUMER_KEY', 'ここに先ほど手に入れたConsumerKeyを入力します');
define('CONSUMER_SECRET', 'ここに先ほど手に入れたConsumerSecretを入力します');

//テンプレ
\Codebird\Codebird::setConsumerKey(CONSUMER_KEY, CONSUMER_SECRET);
$cb = \Codebird\Codebird::getInstance();
//(AccessToken,Secretは予めセッションに保管されてるものとする)
$cb->setToken($_SESSION['access_token'], $_SESSION['access_token_secret']);

$status = $cb->statuses_update(array(
'status' => 'つぶやきたい内容をここにキメろっ!!!'
));

こんだけです。この内、呟くために追加された行というのは

$status = $cb->statuses_update(array(
'status' => 'つぶやきたい内容をここにキメろっ!!!'
));

この行だけです。ね?簡単でしょ?
ちなみに連投する場合は

$message = array('連投したいもの','連投したいもの2',....,'連投したいものn');
$in_reply_to = '';
for($i=0;$i<count($message);++$i){
if($i===0 || $in_reply_to===''){
$status = $cb->statuses_update(array(
'status' => $message[$i]
));
}
else{
$status = $cb->statuses_update(array(
'status' => $message[$i],
'in_reply_to_status_id' => $in_reply_to
));
}
$in_reply_to = $status->id_str;
}

こんな感じに書けば、リプライツリーを作成しながら連投できます。お手軽お手軽っ


以上、TwitterAPI利用のためのアプリケーションを作成手順とcodebird.phpを用いてのログイン認証、簡単なつぶやき実装を記載しました。何らかの開発の助けになれば幸いです。
posted by がお at 17:52| Comment(0) | PHP | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

×

この広告は1年以上新しい記事の投稿がないブログに表示されております。