at posts/single.html

Twitter の RT (ReTweet) 時に元発言へのリンクを知りたい(未解決)

Twitter には RT (ReTweet) という文化がある。 ReTweet とは、面白いと思った他の人の発言を転載すること。

面白いんだけど、普通のリプライと違って元発言へのリンクが張られなくなってしまう。 これだと、1つのつぶやきで完結している場合はいいんだけど、前後のつぶやきを追いたいという場合にはちょっと不便。 なので、 RT 時も元発言へリンクしたいと思って調べてみた。

リプライ時の元発言へのリンク

普通に Twitter のページから他の人の発言にリプライすると、発言のすぐ下に以下のように表示される。

3分前 webで ○○宛

「○○宛」という文字がハイパーリンクになっていて、クリックすると元発言へ飛べるようになっている。 これで、話の流れを追うことができる。

Twitter APIの場合は、 update の in_reply_to_status_id オプションに元発言へ の ID を含めることで、元発言へリンクできる。

in_reply_to_status_id (オプション)
  返信(reply)対象のステータスIDを指定する。どのステータスに対する返信か明示するのに使用する
  存在しない、あるいはアクセス制限のかかっているステータスIDを指定した場合は無視される

Web の場合は、 POST データに in_reply_to_status_id が含まれている。

authenticity_token=xxxxxxxxxxxxxxxx&
status=xxxxxxxxxxx&
twttr=true&
return_rendered_status=true&
in_reply_to_status_id=12345678

Twitter クライアントを使う場合

RT で POST する場合に、 in_reply_to_status_id を送ってくれるクライアントを使えばいい。 でも、なぜか RT の時は in_reply_to_status_id を送らないクライアントが多いみたい。 たとえば、P3:PeraPeraPrvというクライアントは、途中で in_reply_to_status_id を送らないように仕様が変わっている。

2009/04/02 00:30

  • Ver.4.10
  • RT/via/RepostLinkに設定していたin_reply_to_status_idを廃止

なにか弊害があったのかもしれないけど、よく分からない。

Web から RT する場合

RT は Twitter の「機能」ではないので、標準では RT できない。 そこで僕は Twitter Enhancements: Retweet This という GreaseMonkey を入れている。 このスクリプトも RT の時に元発言へのリンクを張ってくれないので、 パラメータに in_reply_to_status_id を付与するように修正してみた。

--- 26500.user.js	2009-06-22 05:13:22.000000000 +0900
+++ twitter_enhancements_ret.user.js	2009-08-09 14:30:51.000000000 +0900
@@ -36,6 +36,12 @@
   return button;
 }
 
+function GetEntryStatusId(entry) {
+  var url = entry.getElementsByClassName('entry-date')[0].href;
+  var m = /^https?:¥/¥/twitter.com¥/.*?¥/status¥/(.*)$/.exec(url);
+  return m[1];
+}
+
 function GetEntryAuthor(entry) {
   var url = entry.getElementsByClassName('entry-date')[0].href;
   var m = /^https?:¥/¥/twitter.com¥/(.*?)¥/status¥/.*$/.exec(url);
@@ -61,6 +67,7 @@
   var entryAuthor = GetEntryAuthor(entry);
   var entryContent = getText(entry.getElementsByClassName('entry-content')[0]);
   var retweetStr = gblRetweetTemplate.replace(/%a/g, entryAuthor).replace(/%c/g, entryContent);
+  var entryStatusId = GetEntryStatusId(entry);
   
   var statusElem = document.getElementById('status');
   if (statusElem) {
@@ -68,7 +75,20 @@
     statusElem.focus();
   } else {
     var m = /^(https?:¥/¥/twitter.com¥/).*$/.exec(document.location.href);
-    window.open(m[1] + 'home?status=' + encodeURIComponent(retweetStr));
+    window.open(m[1] + 
+      'home?status=' + encodeURIComponent(retweetStr) +
+       '&in_reply_to_status_id=' + encodeURIComponent(entryStatusId) +
+       '&in_reply_to=' + encodeURIComponent(entryAuthor)
+     );
+  }
+
+  var statusIdElem = document.getElementById('in_reply_to_status_id');
+  if (statusIdElem) {
+    statusIdElem.value = entryStatusId;
+  }
+  var replyIdElem = document.getElementById('in_reply_to');
+  if (replyIdElem) {
+    replyIdElem.value = entryAuthor;
   }
   
   event.preventDefault();

修正内容はシンプル。個別ページからの RT の時は、 URL のクエリストリングに in_reply_to_status_id (元発言のステータスID) と in_reply_to (元発言のユーザID) を含めるようにしている。 一覧ページでは、入力フォームの in_reply_to_status_id と in_reply_to に同じ値を設定している。

これで動く…はずなんだけど、どうも動かない。 調べてみると、 Web から投稿する場合は、つぶやきの先頭が「@machu つぶやき」のように「@ユーザID」で始まっていないと、サーバに in_reply_to_status_id を送らない仕様になっているみたい。 たぶん、 Submit 時に JavaScript でチェックしているんだろう。

Twitter 本体の JavaScript は難読化されていて、解析するのは難しそう。 ううん…ここで断念か。

関連する日記