はてブをプログラムから追加する

投稿日 : 2008年7月27日 22:31

 はてなはあまり利用してないのだけど(人気エントリは昼休みに見てる)、ヘルプをさまよっていたら、はてなブックマークAtomAPI というのがあったのでVB.NETで実装してみたよ! 2005年からあったのかー。

 まず、つまづいた点から。ブックマークを追加する際にPOST投稿する必要があるのだけど、HttpWebRequestクラスを使って投稿した場合、サーバーから 417 Expectation Failed というエラーが返ってきていた。期待されるものがおかしいのか?? と思ってリクエスト内容がおかしいのかなーと調べてたけど、このエラーコードは、Expect リクエストヘッダフィールドに関するものらしい。.NET で通常 POSTするとこの Expect リクエストヘッダフィールドに「100 (Continue) ステータス」が指定されるようだ。これを指定するとPOSTデータを受け取る前に、サーバが受付拒否ができ、トラフィックを有効に利用できる感じだ。はてなサーバーはこのExpect リクエストを理解できねーとエラーを返してたのですな。

 .NETのコードで、どうやって解決するかというと、検索したらありました。

ServicePointManager.Expect100Continue = False

Sharedなプロパティです。これで一律 Expect を使用しない送信方法になるっぽい。Sharedなので使い方が微妙。作ったコードでは処理前に元の値を覚えておいて、処理後に元の値に戻しているけどマルチスレッドで破綻 オワタ。

 さて認証は、WSSE認証というものを使うらしい。仕様書のリンクはきれてるし詳細がよくわからないのだけど、とりあえず動いたのでOKでしょう。クライアントソフトはユーザのパスワードを記憶しておかないといけないので、少しめんどいですね。

 というわけで、説明もほどほどに(してないけど)コードはこちら。

Public Class HatenaBookmarkApi

    Private Shared _servicePostUri As String = "http://b.hatena.ne.jp/atom/post"

    Private Shared Function createWsseHeaderValue(ByVal username As String, ByVal password As String) As String

        Dim sha1 = New System.Security.Cryptography.SHA1CryptoServiceProvider
        Dim created = Now.ToString("s")
        Dim nonce = Guid.NewGuid.ToString
        Dim passwordDigest = Convert.ToBase64String( _
            sha1.ComputeHash(System.Text.Encoding.ASCII.GetBytes(nonce & created & password)))

        Return String.Format("UsernameToken Username=""{0}"", PasswordDigest=""{1}"", Nonce=""{2}"", Created=""{3}""", _
                             username, passwordDigest, Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(nonce)), created)

    End Function

    Public Shared Function PostUri(ByVal username As String, ByVal password As String, ByVal uri As String, ByVal comment As String) As WebExceptionStatus

        Dim except100Continue = ServicePointManager.Expect100Continue
        ServicePointManager.Expect100Continue = False

        Dim request = CType(WebRequest.Create(_servicePostUri), HttpWebRequest)
        request.Method = "POST"

        request.Headers.Add("Authorization", "WSSE profile=""UsernameToken""")
        request.Headers.Add("X-WSSE", createWsseHeaderValue(username, password))
        request.Accept = "application/x.atom+xml, application/xml, text/xml, */*"
        request.ContentType = "application/x.atom+xml"

        Dim entry = <entry xmlns="http://purl.org/atom/ns#">
                        <title>dummy</title>
                        <link rel="related" type="text/html" href=<%= uri %>/>
                        <summary type="text/plain"><%= comment %></summary>
                    </entry>

        ' こっちでもまったく問題なし
        'Dim entry = "<entry xmlns=""http://purl.org/atom/ns#""><title>dummy</title><link rel=""related"" type=""text/html"" href=""" & uri & """ /><summary type=""text/plain"">" & comment & "</summary></entry>"


        Dim buf = System.Text.Encoding.UTF8.GetBytes(entry.ToString)
        request.ContentLength = buf.Length

        Try
            Dim stream = request.GetRequestStream
            stream.Write(buf, 0, buf.Length)
            stream.Close()

            request.GetResponse.Close()
            Return WebExceptionStatus.Success

        Catch ex As WebException
            Return ex.Status
        Finally
            ServicePointManager.Expect100Continue = except100Continue
        End Try

    End Function
End Class

 使い方はこちら。戻り値が、WebExceptionStatusなんだよねー。そういう使い方普通するんだろうか。でもBooleanはどうかと思う。

HatenaBookmarkApi.PostUri(username, password, "http://yahoo.co.jp", "[tag1][tag2][tag3]")

 

参考になったサイト

 作ってから知ったのだけど、こちらのサイトが参考になりそうですね。

 もっと調べて(検索して)から作れば良かった。というか、これ作るつもりではてなのヘルプをさまよってなかったからなぁ。

フィードバック

# はてダとWindows Live Writer

2008/08/30 1:04 by katamari.wankuma.com
はてダとWindows Live Writer

# re: はてブをプログラムから追加する

2008/12/03 13:48 by kk
上記のソースを参考に、VBではてブに登録するプログラムを作成したのですが、先日リニューアルしたはてブでは、"request.GetResponse.Close() " のレスポンスを閉じる部分でHTTPの403エラーが返ってきてしまうようになってしまいました。

サーバからこの部分でアクセス拒否されているようですが、色々試してみましたがやはり403エラーが返ってしまいます。。


何か考えられる要因はありますでしょうか。

# re: はてブをプログラムから追加する

2008/12/03 20:48 by JZ5
コメントありがとうございます。
確認してみたところ、リニューアルされて今までのAPIが使用できない状態みたいですね。そのうち修正されるかもしれません……。

#  ??????????????????????????? - SharpLab.

2008/12/16 10:52 by Pingback/TrackBack
??????????????????????????? - SharpLab.

# laPAfzBcEw

2014/08/06 23:15 by http://crorkz.com/
iMcuLW Muchos Gracias for your article post.Thanks Again.

# GROUdrjixJIFsKwv

2014/09/03 9:52 by http://ecommerce-investments.com/boat-safety-acces
I savor, lead to I discovered just what I was having a look for. You have ended my four day long hunt! God Bless you man. Have a great day. Bye

# obrQyQuqZZTmiZKVZYp

2014/09/09 10:41 by http://vender-na-internet.com/
I was suggested this web site via my cousin. I am no longer certain whether this submit is written by him as nobody else realize such designated about my problem. You are incredible! Thanks!

# jdRVXPRkOFLhg

2014/09/09 15:15 by http://musiccomposingsoftware.org.
Great website. A lot of helpful information here. I am sending it to some friends ans additionally sharing in delicious. And certainly, thanks to your sweat!
コメントの入力
タイトル
 
名前
 
Url
コメント