Twitterのお気に入りをTumblrへ投稿するプログラム書いたよ | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

2010.10.11 追記

下記のプログラムはTwitterのBasic認証を利用するプログラムで10年8月以降動作しません。

Twitterで登録したお気に入りを登録したい場合、もっと簡単に「Tumblrへ簡単にTwitterのお気に入りを取り込む 」の方法で対応ができます。

プログラムを書きたい場合は、エントリ最後に記載している関連記事の中のOAuth対応スクリプトを応用することで書くことができると思います。



Twitterのタイムラインで気に入ったツイートを見つけた場合、Twitterのお気に入りへ登録するようにしているんですが、このお気に入りを後で見返すのは結構面倒だったり、見づらかったりします。

個人的には、Tumblrはある一文を引用して保存しておきたいって時に便利なので、TwitterとTumblrって結構相性が良いのではと思ったりしてます。

と言うことで、Twitterで付けたお気に入りをTumblrへ投稿するプログラムを書いてみました。



Twitterのお気に入りを取得するPHPスクリプト


まとめてソースを解説すると長くなるので、まずはTwitterのお気に入りを取得するAPIを利用したプログラムの書き方から。

PEARのHTTP_Clientを使っています。


<?php

require_once "HTTP/Client.php";

$username = "your-twitterid";
$password = "your-password";

// TwitterAPI用のURL
$url  = "http://twitter.com/favorites.xml";

$basic = array('Authorization'=>'Basic '.base64_encode($username.':'.$password));

$client = new HTTP_Client(null, $basic);

// お気に入り取得のためのリクエスト送信
$client->get($url);
// お気に入りのレスポンス取得
$response = $client->currentResponse();

// お気に入りのXML情報を解析
if (isset($response['body'])) {
    $xml = new SimpleXMLElement($response['body']);

    for ($i = 0; $i < count($xml->status); $i++) {
        echo $xml->status[$i]->user->screen_name . " : " . date('Y/m/d H:i:s', strtotime($xml->status[$i]->created_at)) . "\n";
        echo "\t" . $xml->status[$i]->text . "\n";
    }
}


この辺の書き方は、「Twitterのタイムラインを取得するPHPスクリプト 」とほぼ同様になるので、そちらも合わせて参考にしてみてください。

基本的には、Basic認証をクリアさせてTwitterのお気に入り用のURLから情報を取得、返ってきたデータ(上記の場合はXML形式)を解析して表示、ってな感じです。



Tumblrへ投稿(QUOTE)するPHPスクリプト


次に、TumlbrへQUOTEを投稿するPHPスクリプトです。

Tumblrへ写真やブログ記事を投稿したい場合は、別の書き方が必要です。


参考: Tumblr APIの使い方を勝手に和訳したもの @ Coro-1729


<?php

require_once "HTTP/Client.php";

// Tumblrの書き込み用APIのURL
$url  = "http://www.tumblr.com/api/write";

// 引用する内容
$quote = "test";
// 引用元
$source = "http://ameblo.jp/itboy/";

$client = new HTTP_Client(null);

// Tumblrへ投稿するために必要なパラメータ
$request = array('email'    => 'your-Email',
                 'password' => 'your-password',
                 'type'     => 'quote',
                 'quote'    => $quote,
                 'source'   => $source);

// リクエスト送信(Tumblrへ投稿)
$client->post($url, $request);

// Tumblrからのレスポンスを取得
$response = $client->currentResponse();

// HTTPステータスコードの内容からエラーハンドリング
if ($response['code'] == 201) {
    echo "投稿完了";
} elseif ($response['code'] == 403) {
    echo "E-Mailまたはパスワードが違います";
} else {
    echo "リクエストが不正です";
}


こちらも、投稿するURLとリクエストのパラメータが異なるぐらいで、Twitterのプログラムとあまり大差なく書くことが出来ます。

Tumblrの場合は、認証用のパラメータ(E-Mailとパスワード)を同時に渡します。



Twitterのお気に入りを取得してTumblrへ投稿するPHPスクリプト


以上のロジックを踏まえて、実際にTwitterのお気に入りをTumblrへ投稿するスクリプトを書いてみます。

(そして完成したものがこちらに・・・)


<?php

require_once "HTTP/Client.php";

// 最後にTumblrへ投稿したIDを保存しておくファイル
$twitter_id_file = './twitter_last_favorite_id.txt';

$last_id = NULL;

// 前回Tumblrに投稿していた場合は、そのIDを取得
if (file_exists($twitter_id_file)) {
    $last_id = trim(file_get_contents($twitter_id_file));
}

$tumblr_post = array();
$num = 0;

while (1) {
// Twitterからお気に入りを取得
    $favs = getTwitterFavorites();
    if ($favs === FALSE) {
        break;
    } else {
        for ($i = 0; $i < count($favs); $i++) {
// 前回投稿したIDと同一だった場合はお気に入りの取得を終了
            if ($last_id !== NULL && $favs[$i]->id == $last_id) {
                break 2;
            } else {
// Tumblrのquoteに入れるテキスト
                  $tumblr_post[$num]['quote']      = $favs[$i]->text;
// Tumblrのsourceに入れるテキスト(Twitter / @(username) : (post-date)の形式)
                $tumblr_post[$num]['source']     = "<a href='http://twitter.com/" . $favs[$i]->user->screen_name . "/status/" . $favs[$i]->id . "'>";
                $tumblr_post[$num]['twitter_id'] = $favs[$i]->id;
                $num++;
            }
        }

// 最初の実行の場合は20件だけTumblrに登録する仕様
        if ($last_id === NULL) {
            break;
       }
    }
}

$post_flg = TRUE;

// Tumblrへ投稿していく
for ($i = 0; $i < count($tumblr_post); $i++) {
    if (postTumblr($tumblr_post[$i]) === FALSE) {
        echo "登録失敗\n";
        $post_flg = FALSE;
        break;
    }
}

// Tumblrへの投稿が失敗した場合は、直前のTwitterのIDをセット
if ($post_flg === FALSE) {
    if ($i !== 0) {
        $last_id = $tumblr_post[$i-1]['twitter_id'];
    }
} else {
// 全て正常に登録できた場合は、最新のTwitterのIDをセット
    $last_id = $tumblr_post[0]['twitter_id'];
}

// 最後のお気に入りのIDを保存
$fp = fopen($twitter_id_file, "w");
fwrite($fp, trim($last_id));
fclose($fp);


// Twitterからお気に入りを取得する
function getTwitterFavorites() {

    static $page = 1;

    $twitter_uname = "your-twitterid";
    $twitter_pwd   = "your-password";

// Twitterのお気に入り取得API用のURL
    $twitter_url  = "http://twitter.com/favorites.xml?page=" . $page;

    $basic = array('Authorization'=>'Basic '.base64_encode($twitter_uname.':'.$twitter_pwd));

    $client = new HTTP_Client(null, $basic);
    $client->get($twitter_url);
    $response = $client->currentResponse();

    if (isset($response['body'])) {
// 取得したTwitterにつけたお気に入りを解析
        $xml = new SimpleXMLElement($response['body']);
        $page++;
        $data = $xml->status;
        if (!isset($xml->status[0]->id)) {
            $data = FALSE;
        }
    } else {
        $data = FALSE;
    }

    return $data;
}

// Tumblrへ投稿する
function postTumblr($data) {

    $tumblr_email = "your-Email";
    $tumblr_pwd   = "your-password";

// Tumblrの書き込み用APIのURL
    $tumblr_url  = "http://www.tumblr.com/api/write";

    $client = new HTTP_Client(null);

    $request = array('email'    => $tumblr_email,
                     'password' => $tumblr_pwd,
                     'type'     => 'quote',
                     'quote'    => $data['quote'],
                     'source'   => $data['source']);

    $client->post($tumblr_url, $request);

    $response = $client->currentResponse();

    if ($response['code'] == 201) {
        $status = TRUE;
    } else {
        var_dump($response);
        $status = FALSE;
    }

    return $status;
}


細かいエラーチェックや例外処理は組み込んでいませんが、一通り動くと思います。

前回実行した際の最後のTwitterのエントリIDをファイルに保存しているので、次回実行時はその続きからTumblrへ投稿できます。

ただ、エントリIDを保存したファイルが無い場合は直近の20件だけ取り出してTumblrへ投稿する仕様にしてます。(過度にAPI消費や負荷をかけないようにするため)

cronに登録しておけば定期的に拾ってTumblrへ投稿してくれると思います。


出来た結果は、私のTumblr の方で確認を・・・。