Twitterでのコメントをブログに表示したい
というわけで、ブログの記事の関連ツイートをTopsyのAPIを使ってPHPで書き出すようにしてみた。
手順としては、
- API(/trackbacks.json)に自分自身のURLを(URLエンコードして)渡してJSONオブジェクトを取得。
- APIに渡せるオプションのパラメータとしては
- perpage
- ページあたりのツイート数。デフォルトは10、MAXは100
- sort_order
- ソート順。デフォルトは新しいツイートから。古いツイート順にするには"sort_order=-date"
- APIに渡せるオプションのパラメータとしては
-
PHPで扱えるようにJSONオブジェクトを(連想配列として)デコード。
- 主に使いそうなところでいうと
- ["response"]["total"]
- ツイート数
- ["response"]["topsy_trackback_url"]
- Topsy上のリンクページ
- ["response"]["list"][n]
- 各ツイートの配列オブジェクト。nは0からスタート
- ["response"]["list"][n]["permalink_url"]
- ツイートのpermalink
- ["response"]["list"][n]["date"]
- 時間(UNIXタイム)
- ["response"]["list"][n]["content"]
- ツイート内容
- ["response"]["list"][n]["author"]["nick"]
- ツイッター上のニックネーム(ユーザー名)。["name"]で名前
- ["response"]["list"][n]["author"]["url"]
- ツイッター上のプロフィールへのリンク
- ["response"]["list"][n]["author"]["photo_url"]
- プロフィール画像
- 主に使いそうなところでいうと
- for文で回しながら、配列の中身から使いたい部分を抽出しつつHTMLに整形して出力。
…と、ざっと、こんな流れ。
1つ注意点としては、Topsyのバグだと思うが、公式RTが、リツイートされた人の発言としてではなく、リツイートした人の発言として扱われてしまう。 とりあえず報告しておいたけど…。Issue 13 - otterapi - trackbacks.json handles Retweeted tweet as a Retweeting person's tweet, not Retweeted(original) person's - Topsy's Otter API - Google Project Hosting。 ディスカッションでも話題に上ってた。Question about retweets - Otter API to Topsy | Google グループ
Question about retweets - Otter API to Topsy | Google グループにつけられた回答によれば、
For a specific tweet, you can call trackbacks with the specific tweet URL to get retweets:
とあって、どうやら逐一そのツイート自身についてあらためてAPIを通じてデータを取ればリツイートかどうかについてもわかる模様。 ということで、リツイートだとわかるように対処してみた。 再帰処理がさらに必要になったので益々重くなったがorz
そして、自分がツイートしたものは(他のツイートへの返信などでない限り)意味はないので除外するなど(除外するのをやめてすべて表示することにしたw)、あれこれゴニョゴニョして最終的にできあがったソースはこんな感じ。
<?php
/*
PHP to include tweets about your blog post.
http://asamuzak.jp
API using otterapi - Topsy's Otter API - Google Project Hosting <http://code.google.com/p/otterapi/>
*/
$sQuery = 'URL'; // URLエンコードしたもの
try {
$twJson = json_decode(file_get_contents('http://otter.topsy.com/trackbacks.json?perpage=100&sort_method=-date&url='.$sQuery), true);
if(!$twJson) {
throw new Exception('データを取得できませんでした。');
}
}
catch(Exception $e) {
echo '<p>'.$e->getMessage().'<a href="http://topsy.com/link?url='.$sQuery.'" rel="nofollow">Topsyで確認する</a></p>'."\n";
}
if(isset($twJson)) {
$twCount = $l = $twJson["response"]["total"];
$rtArr = array();
for($i = 0; $i < $l; $i++) {
$twURL = urlencode($twJson["response"]["list"][$i]["permalink_url"]);
try {
$rtJson = json_decode(file_get_contents('http://otter.topsy.com/trackbacks.json?perpage=100&sort_method=-date&url='.$twURL), true);
}
catch(Exception $e) {
// とりあえず何もしないw
}
if(isset($rtJson)) {
for($j = 0, $k = $rtJson["response"]["trackback_total"]; $j < $k; $j++) {
$rtArr[count($rtArr)] = array("rt_origin" => $twJson["response"]["list"][$i]["author"]["nick"], "origin_url" => $twJson["response"]["list"][$i]["permalink_url"], "rt_url" => $rtJson["response"]["list"][$j]["permalink_url"]);
}
}
}
$twArr = array();
for($i = 0; $i < $l; $i++) {
$twNick = $twJson["response"]["list"][$i]["author"]["nick"];
$twContent = $twJson["response"]["list"][$i]["content"];
$twURL = $twJson["response"]["list"][$i]["permalink_url"];
$twDate = date('F j, Y H:i:s', $twJson["response"]["list"][$i]["date"]);
for($int = -1, $j = 0, $k = count($rtArr); $j < $k; $j++) {
if($twURL == $rtArr[$j]["rt_url"]) {
$int = $j;
break 1;
}
}
if($int >= 0) {
$twArr[count($twArr)] = array("nick" => $twNick, "content" => $twContent, "date" => $twDate, "url" => $twURL, "rt_origin" => $rtArr[$int]["rt_origin"], "origin_url" => $rtArr[$int]["origin_url"]);
}
else {
$twArr[count($twArr)] = array("nick" => $twNick, "content" => $twContent, "date" => $twDate, "url" => $twURL);
}
}
if($l > $twJson["response"]["perpage"]) {
echo '<p>'.$twCount.'件のツイートがあります。<a href="'.$twJson["response"]["topsy_trackback_url"].'" title="Topsy上のページに遷移します">全てのTwitterコメントを見る</a></p>'."\n";
}
elseif($twCount > 0) {
echo '<p>'.$twCount.'件のツイートがあります。</p>'."\n";
}
else {
echo '<p>ツイートは見つかっていません。</p>'."\n";
}
for($i = 0, $l = count($twArr); $i < $l; $i++) {
echo '<p>'.$twArr[$i]["content"].'</p>'."\n";
echo '<ul class="comment-footer">'."\n";
echo '<li class="comment-date">'.$twArr[$i]["date"].'</li>'."\n";
echo '<li class="comment-author">'."\n";
if($twArr[$i]["rt_origin"] != null) {
echo 'RT <a href="'.$twArr[$i]["origin_url"].'" rel="nofollow">'.$twArr[$i]["rt_origin"].'</a> by <a href="'.$twArr[$i]["url"].'" rel="nofollow">'.$twArr[$i]["nick"].'</a>'."\n";
}
else {
echo '<a href="'.$twArr[$i]["url"].'" rel="nofollow">'.$twArr[$i]["nick"].'</a>'."\n";
}
echo '</li>'."\n";
echo '</ul>'."\n";
}
}
?>
コメントの中身について、例えば短縮URLを元に戻してアンカーにするとか、コメント内に出てくる@ユーザーへのリンクを生成するとか、…は、あえて何もせずそのまま表示することにした。
実際につけてみての感想は、Topsyからのレスポンスが遅い時が結構ある。
ので、記事の表示に時間がかかる。
せっかくgz圧縮するなど少しでも表示を早くしようと小細工してるのに…orz
上記のコードをこのまま使うと、サイトのレスポンスが激しく悪化します。
当サイトのレスポンス、当サイトのレスポンス、その2
しかしながら、キャッシュ化の詳細については、サーバーの設定やブログの設定、セキュリティが絡む話なので公開を見合わせています。
もし関心がある方がいれば、コメント欄などでお問い合わせを。
ま、実のところ、出し惜しみするほどの記事じゃないんですけどねw
"Twitterでのコメントをブログに表示したい"へのTwitter上でのコメントやRT
4件のツイートがあります。Topsyで確認する
asamuzaK.jp : Twitterでのコメントをブログに表示したい http://t.co/AwGB7BwV
さっそくテストw RT @asamuzakjp asamuzaK.jp : Twitterでのコメントをブログに表示したい http://t.co/8K0B9O9I
どうだ、ちゃんと表示されるだろうが! まいったか(何がw RT @excel_tiger: さっそくテストw RT @asamuzakjp asamuzaK.jp : Twitterでのコメントをブログに表示したい http://t.co/AwGB7BwV
リツイートはリツイートだとわかるように改訂してみた。 asamuzaK.jp : Twitterでのコメントをブログに表示したい http://t.co/AwGB7BwV via @asamuzakjp