on Rails : トラックバックの仕組みを学ぶ

トラックバックのやり方ではなく,どういう事すればトラックバックが実装できるかという考察ですのでご注意ください.


まずは,適当にググって見る.と,トラックバックトラックバックPingという,Linuxpingコマンドみたいなヤツをトラバ受信先鯖に飛ばし,受信鯖が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を使うから,色々設定してなくて余計に面倒だった.