はてなブログに API 経由で投稿する

本ブログは、 Git の til リポジトリに上げたエントリのうちまとまったものを、 はてなブログに投稿するというフローで更新している。 このあたりを自動化したいと常々考えていて、 はてなブログAPI を使ったエントリの投稿を試してみる。

はてなブログAPI の仕様

プロトコルは REST ではなく AtomPub。 JSON の代わりに XMLエンコードすればいいだけ、と思いきや、XML はオブジェクトに値を持たせる方法が要素と属性の2種類ある分 JSON よりも複雑なので、やや面倒に感じる。

基本的に API を叩くには認証が必要だが、これには OAuth 認証, WSSE認証, Basic認証の3つが用意されている。 テンポラリなキーを発行できる点で OAuth 認証が一番厳しくて、クレデンシャルが平文で送られる点で Basic 認証が一番ゆるい。

実行例: エントリ取得

$ curl -XGET -u minagoro0522:{API キー} https://blog.hatena.ne.jp/minagoro0522/minagoro0522.hatenablog.com/atom/entry/8599973812281828868

API の URL はドキュメントの通り。 ちなみに、ブログの「設定 > 詳細設定 > AtomPub」に「ルートエンドポイント」として、URL のプレフィクスが掲載されているので、これをコピペすると早い。

entry_id はドキュメントの説明だけだとわからない。 結論としては、記事の編集ページの URL のパスの末尾が entry_id で、例えば編集ページの URL が http://blog.hatena.ne.jp/minagoro0522/minagoro0522.hatenablog.com/edit?entry=8599973812281828868 なら 8599973812281828868 がその記事の entry_id である。

あと、出力結果は整形されていないので、xmllint するのがオススメ。

$ curl -sL ... | xmllint --format -

エントリ投稿に関して

エントリの作成と更新

作成は POST で、更新は PUT。 また、更新の場合は POST で必要なパラメータ(はてなのアカウント, ブログの ID)に加えて、エントリ ID が必要になる。 まだそのエントリが存在しない場合は作成、すでに存在する場合は更新、という風にしたかったんだけど、メソッドの違いはともかくパラメータまで違っていて厳しそう。

とりあえず試してみる

API の仕様に従って、リクエストボディを作る。

// ドキュメントのサンプルをコピーしただけ
$ vi sample.xml
<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
       xmlns:app="http://www.w3.org/2007/app">
  <title>エントリタイトル</title>
  <author><name>name</name></author>
  <content type="text/plain">
    ** エントリ本文
  </content>
  <updated>2008-01-01T00:00:00</updated>
  <category term="Scala" />
  <app:control>
    <app:draft>{yes | no}</app:draft>
  </app:control>
</entry>

エントリ作成 APIcurl でコールする。

$ curl -XPOST -u minagoro0522:{API キー} -d @sample.xml https://blog.hatena.ne.jp/minagoro0522/minagoro0522.hatenablog.com/atom/entry/8599973812281828868

成功を確認。 (すでに削除済みだが)実際にエントリが作成された。

...
< HTTP/1.1 201 Created
...

参考