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