Trackback Ping を送信する
なにかのイベントや、事件などについての Blog 記事を書くとき、同じ内容について書かれている Blog エントリ同士がリンクでつながっていると、ブラウズやディスカッションの際に非常に便利です。Trackback は、こうしたエントリ間のつながりを、簡単な URL 呼び出しで実現するための Blog API です。今回は、この Trackback Ping の API について簡単に解説し、Trackback Ping を実際に送信するコードを記述してみます。 Trackback は MovableType の Ben & Mena 夫妻によって考案され(*1)、Movable Type ではじめて実装された、Blog 間の言及通知のフレームワークです。 Trackback は、送信側が受信側に対して、HTTP によるメッセージを送信することによって行われます。 まず送信側は、通知したい Blog エントリやカテゴリ毎に固有の Trackback URL に対して、HTTP POST で| パラメータ | 意味 |
|---|---|
| url | URL |
| blog_name | Blog 名 |
| title | タイトル |
| excerpt | 概要 |
Content-Type: text/xml <?xml encoding="utf-8"?> <response> <error>0</error> <message>Ping saved successfully.</message> </response>もしエラーが起こった場合には、
Content-Type: text/xml <?xml encoding="utf-8"?> <response> <error>1</error> <message>Something Bad happened.</message> </response>のように
error に 1 をセットします。
Trackback の API はたったこれだけです。MovableType では、各記事やカテゴリごとに Trackback の固有ID が用意されており、http://example.com/mt/mt-tb.cgi/1234 のような URL が Trackback URL (送信先)となります(*2)。その記事やカテゴリにリンク、言及した Blog がこの Trackback URL に対し、上述のような HTTP POST リクエストを送信します。
ここで紹介したように、Trackback の主な利用目的は、「リンクしたよ」とか、「同じイベントにいった感想を書いたよ」という通知といえますが、他にも
- 複数の Blog サイトの特定カテゴリのエントリを集約する
- PhotoFriday や FridayFive のような、アンケートなどの結果集積所
サンプルコード
Trackback を送信するための簡易フォームつき CGI スクリプトを記述すると、List 1 のようになります。use CGI; use HTTP::Request::Common; use LWP::UserAgent;使用するモジュールを use します。CGI スクリプトとして起動するため、CGI.pm を使用しています。
my $query = CGI->new();
$query->charset('utf-8');
CGI オブジェクトを new し、charset メソッドで文字コードを UTF-8 としています。Trackback の文字コードについては、実際の Trackback規格仕様書では対応方法が記述されておらず、日本語のように複数の文字エンコーディングを持つ言語での対応が若干混乱しています。執筆時点では、
- 送る文字コードは UTF-8 推奨
- 送信する際に
charsetパラメータでエンコーディングを指定 - 受け取り側は
charsetからデコード。ない場合は自動判定を試みる
my $mode = $query->param('mode');
if ($mode && $mode eq 'form') {
show_ping_form($query);
CGI の mode パラメータを受けとり、form であれば、送信するためのフォームを表示する show_ping_form を呼び出します。
} else {
my $v = $query->Vars();
if ($v->{ping_url} && $v->{title} && $v->{url}) {
my $message = send_ping($v);
show_ping_form($query, $message);
} else {
show_ping_form($query, "invalid parameters");
}
}
mode がない場合には、Ping 送信モードになります。パラメータ ping_url, title, url が指定されているかチェックし、問題なければ send_ping により Trackback Ping を送信します。送信した結果は $message に格納されるので、フォームと同時に画面に出力します。
パラメータに不備がある場合も、その旨メッセージがフォームとともに表示されます。
sub show_ping_form {
my($query, $message) = @_;
$message ||= '';
print $query->header, <<HTML;
<html>
<body>
$message
<form>
Ping URL: <input type="text" name="ping_url" size="30" /><br />
Title: <input type="text" name="title" size="30" /><br />
Blogname: <input type="text" name="blog_name" size="30" /><br />
Blog URL: <input type="text" name="url" size="30" /><br />
Excerpt: <input type="text" name="excerpt" size="50" /><br />
<input type="submit" value="Send" />
</form>
</body></html>
HTML
;
}
Trackback を送信するための簡易フォームを表示します。
sub send_ping {
my $v = shift;
my $ua = LWP::UserAgent->new();
$ua->agent("tb_send/1.0");
my $req = POST $v->{ping_url}, [
title => $v->{title},
url => $v->{url},
blog_name => $v->{blog_name},
excerpt => $v->{excerpt},
charset => 'utf-8',
];
my $response = $ua->request($req);
unless ($response->is_success) {
return "HTTP error: " . $response->status_line;
}
$response->content =~ m!<error>(\d+).*<message>(.+?)</message>!s;
return $1 ? "Error: $2" : "Ping to $v->{ping_url} successful";
}
send_ping では、LWP::UserAgent オブジェクトを生成、CGI パラメータから POST リクエストを作成して、request メソッドによりリクエストを送信します。先述したように、charset パラメータに utf-8 をセットしていることに注意してください。
HTTP レスポンスがエラーであった場合には、ステータス行とともに return します。HTTP レスポンス自体が成功した場合は、返り値の XML 内の error 属性の値を調べ、1 であった場合にはエラー、0 であった場合には Ping 成功として表示します(*3)
実行例
このスクリプトを、CGI 実行可能なパスに設置し、ブラウザから.../tb_send.cgi?mode=form として呼び出してみましょう。
このようなフォームが表示されます。一番上の Ping URL に、Trackback Ping 先の URL (mt-tb.cgi/1234 など)、以下の4つには、Ping 元となるエントリ(通常は自分の Blog エントリでの記述内容) を入力し、Send のボタンを押します。
Ping が成功すれば、
Ping to http://example.com/tb.cgi successful.失敗した場合には、
HTTP error: 500 Internal Server Error.といったメッセージが表示されます。
Hack the Hacks
Trackback のリファレンス実装である tb-standalone が MovableType サイト内でオープンソースで公開されています。このツールの中にも、Trackback を送信するモードが用意されていますListings
List 1: tb_send.pl
#!/usr/local/bin/perl -w
# tb_send - Send Trackback Ping
use strict;
use CGI;
use HTTP::Request::Common;
use LWP::UserAgent;
my $query = CGI->new();
$query->charset('utf-8');
my $mode = $query->param('mode');
if ($mode && $mode eq 'form') {
show_ping_form($query);
} else {
my $v = $query->Vars();
if ($v->{ping_url} && $v->{title} && $v->{url}) {
my $message = send_ping($v);
show_ping_form($query, $message);
} else {
show_ping_form($query, "invalid parameters");
}
}
sub show_ping_form {
my($query, $message) = @_;
$message ||= '';
print $query->header, <<HTML;
<html>
<body>
$message
<form>
Ping URL: <input type="text" name="ping_url" size="30" /><br />
Title: <input type="text" name="title" size="30" /><br />
Blogname: <input type="text" name="blog_name" size="30" /><br />
Blog URL: <input type="text" name="url" size="30" /><br />
Excerpt: <input type="text" name="excerpt" size="50" /><br />
<input type="submit" value="Send" />
</form>
</body></html>
HTML
;
}
sub send_ping {
my $v = shift;
my $ua = LWP::UserAgent->new();
$ua->agent("tb_send/1.0");
my $req = POST $v->{ping_url}, [
title => $v->{title},
url => $v->{url},
blog_name => $v->{blog_name},
excerpt => $v->{excerpt},
charset => 'utf-8',
];
my $response = $ua->request($req);
unless ($response->is_success) {
return "HTTP error: " . $response->status_line;
}
$response->content =~ m!<error>(\d+).*<message>(.+?)</message>!s;
return $1 ? "Error: $2" : "Ping to $v->{ping_url} successful";
}
*1) Feature: Trackback が、Trackback をはじめて紹介しているエントリと思われます。
*2) もちろん他の Blog ツールでも同様に記事ごとに固有の Trackback URL が用意されていることが多いようです。
*3) 簡易のため正規表現で拾っています。XML::Simple などを使用してもいいですが、これだけシンプルな XML にわざわざパーサをつかうのは、鉛筆をノコギリで削るようなもので、ちょっとオーバースペックな気もします。
*2) もちろん他の Blog ツールでも同様に記事ごとに固有の Trackback URL が用意されていることが多いようです。
*3) 簡易のため正規表現で拾っています。XML::Simple などを使用してもいいですが、これだけシンプルな XML にわざわざパーサをつかうのは、鉛筆をノコギリで削るようなもので、ちょっとオーバースペックな気もします。
posted at: 03:54 by miyagawa | category: Trackback Pings | permalink
Trackback (6) | Printer Friendly | Email this blog