asamuzaK.jp

Twitterでのコメントをブログに表示したい

というわけで、ブログの記事の関連ツイートをTopsyのAPIを使ってPHPで書き出すようにしてみた。

手順としては、

  1. API(/trackbacks.json)に自分自身のURLを(URLエンコードして)渡してJSONオブジェクトを取得。
    • APIに渡せるオプションのパラメータとしては
      perpage
      ページあたりのツイート数。デフォルトは10、MAXは100
      sort_order
      ソート順。デフォルトは新しいツイートから。古いツイート順にするには"sort_order=-date"
      などがある。
  2. 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"]
      プロフィール画像
  3. 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&amp;sort_method=-date&amp;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&amp;sort_method=-date&amp;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

"Twitterでのコメントをブログに表示したい"へのコメント

コメントは寄せられていません。

コメント投稿フォーム

名前、メールアドレス、URIはいずれも任意です。 コメントは承認後に公開されます(承認されない場合もあります)。 なお、メールアドレスは公開されません。

情報の保存

"Twitterでのコメントをブログに表示したい"へのトラックバック

1 件のトラックバックが寄せられています。

当サイトのレスポンス [asamuzaK.jp]
ツイートを表示するようにしたら案の定レスポンスが激悪化orz

この記事にトラックバックするには、http://asamuzak.jp/cgi-bin/mt/mt-trackbacks-mmxii.cgi/362までpingを送信してください。 トラックバック送信元にこの記事への言及(リンク)がない場合は受け付けない設定にしています。