on Rails : トラックバックの仕組みを学ぶ
トラックバックのやり方ではなく,どういう事すればトラックバックが実装できるかという考察ですのでご注意ください.
まずは,適当にググって見る.と,トラックバックはトラックバックPingという,Linuxのpingコマンドみたいなヤツをトラバ受信先鯖に飛ばし,受信鯖がCGIを起動してそのトラバをもとに逆リンクを生成するんだね.
http://lowlife.jp/yasusii/stories/8.htmlによると,これらのパラメータがトラックバックPingとして送られるようだ.
パラメータ名 | 意味 |
url | 記事のURL |
blog_name | ブログ名 |
title | 記事のタイトル |
excerpt | 記事の概要 |
これらのパラメータを,HTTPのPOSTメソッドで送信するんだな.記事の概要って,送信する側がどれだけの長さを送るかってのと,受信側がどれだけの長さを受信するか,一致している必要は無いようだ.
で,よくある'トラックバックURL'ってのは'トラックバックCGIのURL'で,送られたパラメータを元にCGIを起動し,ゴニョゴニョっと処理するんだな.で,そのContent-Typeをapplication/x-www-form-urlencodedにすればよいのだな.
以下Railsで試す.
まずプロジェクトの作成.
$ rails tbtest $ cd tbtest
次にデータベースの作成.めんどくさいのでsqlite3で*1.
development: adapter: sqlite3 database: development.sqlite3
次にモデルの作成.script/generate model Trackbackで雛形を作り,db/migrate/001_create_trackbacks.rbを,以下のように編集.
class CreateTrackbacks < ActiveRecord::Migration def self.up create_table :trackbacks do |t| t.column :url, :string t.column :blog_name, :string t.column :title, :string t.column :excerpt, :text end end def self.down drop_table :trackbacks end end
コレを書いたら,rake db:migrate,次にscaffold.new.rhtmlを弄る.
<h1>New trackback</h1> <%= start_form_tag :action => 'send_tb' %> <%= render :partial => 'form' %> <%= submit_tag "Send" %> <%= end_form_tag %> <%= link_to 'Back', :action => 'list' %>
次に,送信先のアドレスを指定できるように,フォームを弄る.
<%= error_messages_for 'trackback' %> <!--[form:trackback]--> <p><label for="trackback_to_url">To</label><br/> <%# なぜか,こうしないとparamsに入らなかったorz %> <input type="text" name="to_url" id="to_url" size="30" value=""/></p> <p><label for="trackback_url">From</label><br/> <%= text_field 'trackback', 'url' %></p> <p><label for="trackback_blog_name">Blog name</label><br/> <%= text_field 'trackback', 'blog_name' %></p> <p><label for="trackback_title">Title</label><br/> <%= text_field 'trackback', 'title' %></p> <p><label for="trackback_excerpt">Excerpt</label><br/> <%= text_area 'trackback', 'excerpt' %></p> <!--[eoform:trackback]-->
これで擬似的にトラックバックを送信するためのフォームが完成した.
次はこのsend_tbアクションを実装する.トラックバックPingを送信するために,Net::HTTPのpostメソッドを使用する.send_tbはこんなかんじ.
def send_tb require 'net/http' to_url = params[:to_url] url = params[:trackback][:url] blog_name = params[:trackback][:blog_name] title = params[:trackback][:title] excerpt = params[:trackback][:excerpt] # make address & path form 'to_url' to_url.sub!(/http:\/\//,'') split_url = to_url.split(/\//) address, port = split_url.shift.split(/:/) port = 80 if port =~ /^$/ path = '/' + split_url.join('/') # make query query = "url=#{url}&blog_name=#{blog_name}" + "&title=#{title}&excerpt=#{excerpt}" # make http connection & post query http = Net::HTTP.new(address, port).start response = http.post(path, query) if response.message == 'OK' flash[:notice] = 'Trackback was successfully sended.' else flash[:notice] = 'Failure' end redirect_to :action => 'new' end
Content-Typeって,どうやって設定するのかわかんないけれど,実際に試してみるとこれで送信できた(はてなに).おぉ,これはもしや,トラバスパムを作るのって,超簡単なんじゃネーノ.
受信は,こんな感じで良いのかな.とりあえず何も考えずに,ただトラバを受信するだけのを書いてみた.
def recv_tb url = params[:url] blog_name = params[:blog_name] title = params[:title] excerpt = params[:excerpt] @trackback = Trackback.new(:url => url, :blog_name => blog_name, :title => title, :excerpt => excerpt) @trackback.save end
で,ここにさっきのトラバ送信プログラムで送信してみると,なんかTimeoutする.だけどlistをみてみると,ちゃんと入ってるんだよね.不思議.
勉強した.
*1:と思ったら,初めてsqlite3を使うから,色々設定してなくて余計に面倒だった.