野良ジニアのスクラップブック

野良エンジニアによる雑記帳。技術、本、便利グッズなどを気の向くままに。

AtomAPIを使ってはてなフォトライフの『指定フォルダ』に画像をアップロードする

こんにちわ、野良ジニアです。

「てめえ、本当にエンジニアなのかよ」感のある記事しか投稿してないので、たまにはエンジニアっぽい記事を投稿します。

作りたいもの(これはできてから別記事にします)があり、色々と試しているところなので、その途中で得られた知見などをまとめます。今回の内容は「AtomAPIを使ってはてなフォトライフの指定フォルダに画像をアップロードする」です。


※2017/01/19(木) 12:30 追記
コメント欄にて、「指定フォルダへのアップロードは、公式ドキュメントにやり方が記載されている」とのご指摘を頂きました。改めて確認したところ、以下の記載がありました。

POSTURI
(中略)
リクエスト用XML文書に記述することができるパラメータは以下です。
(中略)

  • アップロード先のフォルダ名をdc:subject要素に
    • 指定されたフォルダが存在しない場合は、自動的に作成されます。

完全に私の見落としですね…本記事に書いてある方法でも実現できたので、やり方自体は間違いではない(と思う)のですが、こんな事をしなくても正式な手順があります。本記事を参照される方がいれば、公式ドキュメントの方法を利用するようにお願いします。

id:masawadaさん、ご指摘ありがとうございました。


※2017/01/19(木) 18:30 追記
公式手順でのアップロードについて記事を書きました。

www.stray-scrapbook.work

追記 ここまで


※ツッコミどころ満載な可能性があるので、その場合はコメントなどいただけると幸いですm(_ _)m

参考にした情報

公式ドキュメントとあわせて、以下の記事を大いに参考にさせてもらいました。ありがとうございますm( )m

masawada.hatenablog.jp

はてなフォトライフAtomAPI - Hatena Developer Center

やりたいこと

参考にした記事に画像をアップロードする方法は書かれていたのですが、以下の通り画像がトップフォルダに入るとのこと。

このAPIで送った画像ははてなフォトライフのトップフォルダに入るので、はてなブログに貼りたいときに注意。

今回やりたかった(知りたかった)のは、どうにか以下を実現できないか、ということでした。

  • 指定フォルダへのアップロード
  • アップロードファイル名の指定

技術的なおはなし

先に結論:どうやって指定フォルダにアップロードするの?


※2017/01/19(木) 12:30 追記
以下の方法でも可能ですが、正式な手順は『HTTP Request内XMLに<dc:subject>Hatena Blog</dc:subject>を追加』になります。
追記 ここまで


POST APIのクエリに folder=hogehoge を追加すればいけました。

POST /atom/postPOST /atom/post?folder=hogehoge にするだけです。はてなブログ用のフォルダにアップロードするなら POST /atom/post?folder=Hatena%20Blog としてください。

※本方法は、公式ドキュメントにも記載されていない手段なので、AtomAPI の仕様変更により使えなくなる可能性が大いにあります。

AtomAPI って?

はてなが公式に用意しているインターフェースです。

GUI(画面)でポチポチしなくても、CLIで画像がアップロードできるようになったりします。上手いこと活用できれば、自分の好きな画像アップローダを作ることも可能です。

どうやって方法を見つけたの?

ウェブ関連の技術力が不足しているので、かなり泥臭いやり方で頑張りました。

『男は黙って Wireshark!!』

※何か素敵な解析方法をご存知の方がいれば教えてください。

Wireshark(ワイヤーシャーク)ってなに?

フリーのパケットキャプチャツールです。細かい説明は省きますが、パソコンが通信しているパケット(通信内容)を確認したり、細かい情報を解析できたりします。

forest.watch.impress.co.jp

詳しく知りたい方がいれば、以下などが参考になるかと思います。

knowledge.sakura.ad.jp

beginners-network.com

Wireshark でどう解析したの?

前述の通り、公式ドキュメントには目的の手順など記載されていません。


※2017/01/19(木) 12:30 追記
見落としていただけで、公式ドキュメントにフォルダ指定方法が記載されていました。正式手順は『HTTP Request内XMLに<dc:subject>Hatena Blog</dc:subject>を追加』になります。こういうやり方もあるんだなぁ、と思ってもらえるかもなので、以降の記事はそのまま載せておきます。
追記 ここまで


そこで「GUIを使った通常のアップロード時のHTTP Requestがどうなってるか」をまずは確認することにしました。

GUI アップロード時の HTTP Request の解析

まずは「はてなフォトライフ」のマイフォトにアクセスします。

f.hatena.ne.jp

右上にある「マイフォト」をクリックして移動。テスト用に「test」(安直な名前)というフォルダを作成しました。フォルダに移動後、右上にある「アップロード」をクリックして移動。

この段階で Wireshark を起動。インターネット回線と接続されているネットワークインターフェースを選択して、左上のサメの背びれのようなアイコンをクリックして、パケットキャプチャを開始。

「はてなフォトライフ」だけでなく、全ての通信内容が表示されるので、フィルターを設定しておきます。今回は「はてなフォトライフ」との通信を見たいので、 http.host == "f.hatena.ne.jp" でフィルタしました。

こちらが何もフィルタを設定しない場合、何がなんだか分からないですね。

f:id:ryota-17:20170205152525p:plain

こちらがフィルタに http.host == "f.hatena.ne.jp" を指定した場合、「はてなフォトライフ」との HTTP 通信のみが表示されて分かりやすくなりました。

f:id:ryota-17:20170205152527p:plain

では、画像アップロード時のリクエストを実際に見てみましょう。こちらが対象のパケットになります。

f:id:ryota-17:20170205152526p:plain

クエリ部分が長すぎて見切れていますが、以下のクエリが含まれていました。
= の後ろに何もない部分は、fotosize1=800&taglist=&rkm=xxxx... のように何も入力されていませんでした。

  • rk=xxxxxx...
  • fotosize1=800
  • taglist=
  • rkm=xxxxxx...
  • folder=test
  • file%5Fcreated=1484491671143
  • mode=enter
  • fid=20170118123456
  • fototitle1=
  • uploader=swf

上記を見てもらえば分かるように、folderfid でフォルダとファイル名を指定しているようです。なので、AtomAPI でも folderfid を指定すれば、「指定フォルダ」に「指定の名前」でアップロードできるんじゃないか、と考えました。

AtomAPI で実際に試してみる

記事タイトルなどからもお分かりのように、結論から言うと「フォルダの指定」だけしか上手くいきませんでした。

以下に実際にやったことを記載しておきます。

Consumer key の取得

AtomAPI を利用するためには、WSSE か Oauth で認証する必要があります。参考にさせてもらった内容も OAuth 認証で実施されていたので、同様に OAuth 認証でやることにします。

OAuth 認証を行うためには、事前に Consumer key を取得する必要があります。以下の手順1に従い Consumer key を取得します。アプリケーションの名称、説明、URL は適当に決めて良いです。

Consumer key を取得して OAuth 開発をはじめよう - Hatena Developer Center

アプリケーションの追加ができたら、下の方にある「承認を求める操作」の

  • read_private
  • write_private

にもチェックを入れて、一番下にある「変更する」をクリックします。

のちのち使うので、真ん中ぐらいに表示されている

  • OAuth Consumer Key
  • OAuth Consumer Secret

をメモしておきます。

Access token を取得する

Ruby のサンプルコードを、vagrant 上で動かして、Access token を取得しました。

ここで vagrant でやる際の注意点をいくつか。ローカルで動作させる場合は気にしなくて良いです。

  • サンプルコードはローカルで動かす前提になっているので…
  • Vagrantfile を編集してポートフォワーディングの設定を追加すること。 4567 -> 14567 にしました。
  • サンプルコード 28行目のポートをフォワーディングするポート番号に変更すること。{ :oauth_callback => 'http://localhost:14567/oauth_callback' },

サンプルコードを動作させたら、http://localhost:14567 にアクセスします。表示されたリンクをクリックすると、認証画面に移るので「許可する」を選択。

その後表示される

  • access_token
  • access_token_secret

をメモしておきます。

なお、この Access token には有効期限が設定されているので、有効期限が切れたら再取得する必要があります。

AtomAPI にクエリを追加して叩いてみる

最初に紹介したブログのコードをそのまま使わせてもらいました。

変更箇所は以下になります。

  • 11, 12行目の CNSUMER_KEY CONSUMER_SECRET
  • 18, 19行目の ACCESS_TOKEN ACCESS_TOKEN_SECRET
  • 32行目の '/atom/post''/atom/post?folder=test&fid=xxxx' に。

実際に試したところ、以下のような結果になりました。

  • folder=test を追加 : 成功
  • folder=test&fid=hoge を追加 : 失敗。画像のアップロード自体ができていない。fid に数値以外を指定するのはダメな模様
  • folder=test&fid=20170118 を追加 : 失敗。レスポンスは「201 Created」になるが、「はてなフォトライフ」を見ると画像が存在しないアイコンが表示されている。fid は日付だけでなく時刻も合わせたフォーマットでないとダメな模様
  • folder=test&fid=20170118123456 を追加 : 成功。指定した fid で画像がアップロードされている。
  • もう一度 folder=test&fid=20170118123456 を追加 : 成功。画像が上書き保存される。
  • folder=test&fid=20170118123456_test を追加 : 成功?画像はアップロードできているが、fid_test を除いた 20170118123456 にトリミングされている。

上記のような結果になったので、厳密に言えば「フォルダもファイル名の指定できる」のですが、「ファイル名は日付時刻形式でしか指定できない」ため、もともとやりたかった事は実現できなさそうです。

まとめ

  • AtomAPI を使えば画像をアップロードできる
  • POST /atom/post?folder=hoge とすれば指定フォルダに画像をアップロードできる。※正式手順は『HTTP Request内XMLに<dc:subject>hoge</dc:subject>を追加』。
  • はてなブログ用フォルダにアップロードする場合は POST /atom/post?folder=Hatena%20Blog を指定※正式手順は『HTTP Request内XMLに<dc:subject>Hatena Blog</dc:subject>を追加』。
  • API の仕様変更で本方法は使えなくなる可能性がある
  • 今回使ってないクエリを活用すると、もっと色々なことができるかも?

ブログにまとめると頭の中が整理できて、備忘録にもなるし、たまには技術的な内容も良いですね。