寄稿:はてなブログのSEOが優れている7つの理由と、さらにSEO効果を高める5つのTIPS - はてなブログ開発ブログを読んでいたら、"PubSubHubbub"という見慣れない単語が出てきたので、ちょっと調べてみた。

Pub? Sub?

まず、PubSubHubbubというのは、2009年頃からGoogleが提案しているプロトコルらしい。ずいぶん前からあるんだな。全然知らなかった。PuSH、と略すそうだ。現在のドラフトはここで見れる。

PubSubHubbubでRSSもTwitter並にリアルタイムに - @ITに解説が書いてあった。ここでWeb hookと言っているのは、GitHubだとService Hooksみたいなものだろうか。要は、ポーリングするのを止めて、コンテンツ供給者であるPubから更新情報をプッシュしてもらおう、という内容のようだ。

ブログでの対応は簡単だと書いてあったので、Octopressでのやり方をググってみた。

Octopressの対応方法

Octopressでの対応方法は、Pubsubhubbub with Octopress - ~/git/blogのエントリーに具体的な方法が書いてあった。

まずは、Hubとなってくれるサービスに、登録しておく必要がある。上記エントリーにならって、Superfeedrに登録してみた。登録が完了すると、satooshi.superfeedr.comのように、ハブとなるURLが取得できる。

次は、atom.xmlにHubのURLを埋め込むように修正する。7行目に追加したのが変更点。

atom.xmllink
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[{{ site.title }}]]></title>
<link href="{{ site.url }}/atom.xml" rel="self"/>
<link href="{{ site.url }}/"/>
{% if site.hub_url %}<link href="{{ site.hub_url }}" rel="hub"/>{% endif %}
<updated>{{ site.time | date_to_xmlschema }}</updated>
<id>{{ site.url }}/</id>
<author>
<name><![CDATA[{{ site.author | strip_html }}]]></name>
{% if site.email %}<email><![CDATA[{{ site.email }}]]></email>{% endif %}
</author>
<generator uri="http://octopress.org/">Octopress</generator>
{% for post in site.posts limit: 20 %}
<entry>
<title type="html"><![CDATA[{{ post.title | cdata_escape }}]]></title>
<link href="{{ site.url }}{{ post.url }}"/>
<updated>{{ post.date | date_to_xmlschema }}</updated>
<id>{{ site.url }}{{ post.id }}</id>
<content type="html"><![CDATA[{{ post.content | expand_urls: site.url | cdata_escape }}]]></content>
</entry>
{% endfor %}
</feed>

最後は、blog更新時にSuperfeedrにPingするタスクをRakefileに登録しておく。deployタスクとは別に、pubsubタスクを作った。

Rakefilelink
desc "notify to PuSH Hub server"
task :pubsub do
require 'net/http'
require 'uri'
hub_url = "http://satooshi.superfeedr.com" # <--- replace this with your hub
atom_url = "http://blog.satooshi.jp/atom.xml" # <--- replace this with your full feed url
resp, data = Net::HTTP.post_form(URI.parse(hub_url),
{'hub.mode' => 'publish',
'hub.url' => atom_url})
raise "!! Hub notification error: #{resp.code} #{resp.msg}, #{data}" unless resp.code == "204"
puts "## Notified hub (" + hub_url + ") that feed #{atom_url} has been updated"
end