こんにちわ、野良ジニアです。
「てめえ、本当にエンジニアなのかよ」感のある記事しか投稿してないので、たまにはエンジニアっぽい記事を投稿します。
作りたいもの(これはできてから別記事にします)があり、色々と試しているところなので、その途中で得られた知見などをまとめます。今回の内容は「AtomAPIを使ってはてなフォトライフの指定フォルダに画像をアップロードする」です。
※2017/01/19(木) 12:30 追記
コメント欄にて、「指定フォルダへのアップロードは、公式ドキュメントにやり方が記載されている」とのご指摘を頂きました。改めて確認したところ、以下の記載がありました。
POSTURI
(中略)
リクエスト用XML文書に記述することができるパラメータは以下です。
(中略)
- アップロード先のフォルダ名をdc:subject要素に
- 指定されたフォルダが存在しない場合は、自動的に作成されます。
完全に私の見落としですね…本記事に書いてある方法でも実現できたので、やり方自体は間違いではない(と思う)のですが、こんな事をしなくても正式な手順があります。本記事を参照される方がいれば、公式ドキュメントの方法を利用するようにお願いします。
id:masawadaさん、ご指摘ありがとうございました。
※2017/01/19(木) 18:30 追記
公式手順でのアップロードについて記事を書きました。
追記 ここまで
※ツッコミどころ満載な可能性があるので、その場合はコメントなどいただけると幸いですm(_ _)m
参考にした情報
公式ドキュメントとあわせて、以下の記事を大いに参考にさせてもらいました。ありがとうございますm( )m
はてなフォトライフ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/post
を POST /atom/post?folder=hogehoge
にするだけです。はてなブログ用のフォルダにアップロードするなら POST /atom/post?folder=Hatena%20Blog
としてください。
※本方法は、公式ドキュメントにも記載されていない手段なので、AtomAPI の仕様変更により使えなくなる可能性が大いにあります。
AtomAPI って?
はてなが公式に用意しているインターフェースです。
GUI(画面)でポチポチしなくても、CLIで画像がアップロードできるようになったりします。上手いこと活用できれば、自分の好きな画像アップローダを作ることも可能です。
どうやって方法を見つけたの?
ウェブ関連の技術力が不足しているので、かなり泥臭いやり方で頑張りました。
『男は黙って Wireshark!!』
※何か素敵な解析方法をご存知の方がいれば教えてください。
Wireshark(ワイヤーシャーク)ってなに?
フリーのパケットキャプチャツールです。細かい説明は省きますが、パソコンが通信しているパケット(通信内容)を確認したり、細かい情報を解析できたりします。
詳しく知りたい方がいれば、以下などが参考になるかと思います。
Wireshark でどう解析したの?
前述の通り、公式ドキュメントには目的の手順など記載されていません。
※2017/01/19(木) 12:30 追記
見落としていただけで、公式ドキュメントにフォルダ指定方法が記載されていました。正式手順は『HTTP Request内XMLに<dc:subject>Hatena Blog</dc:subject>
を追加』になります。こういうやり方もあるんだなぁ、と思ってもらえるかもなので、以降の記事はそのまま載せておきます。
追記 ここまで
そこで「GUIを使った通常のアップロード時のHTTP Requestがどうなってるか」をまずは確認することにしました。
GUI アップロード時の HTTP Request の解析
まずは「はてなフォトライフ」のマイフォトにアクセスします。
右上にある「マイフォト」をクリックして移動。テスト用に「test」(安直な名前)というフォルダを作成しました。フォルダに移動後、右上にある「アップロード」をクリックして移動。
この段階で Wireshark を起動。インターネット回線と接続されているネットワークインターフェースを選択して、左上のサメの背びれのようなアイコンをクリックして、パケットキャプチャを開始。
「はてなフォトライフ」だけでなく、全ての通信内容が表示されるので、フィルターを設定しておきます。今回は「はてなフォトライフ」との通信を見たいので、 http.host == "f.hatena.ne.jp"
でフィルタしました。
こちらが何もフィルタを設定しない場合、何がなんだか分からないですね。
こちらがフィルタに http.host == "f.hatena.ne.jp"
を指定した場合、「はてなフォトライフ」との HTTP 通信のみが表示されて分かりやすくなりました。
では、画像アップロード時のリクエストを実際に見てみましょう。こちらが対象のパケットになります。
クエリ部分が長すぎて見切れていますが、以下のクエリが含まれていました。
※=
の後ろに何もない部分は、fotosize1=800&taglist=&rkm=xxxx...
のように何も入力されていませんでした。
- rk=xxxxxx...
- fotosize1=800
- taglist=
- rkm=xxxxxx...
- folder=test
- file%5Fcreated=1484491671143
- mode=enter
- fid=20170118123456
- fototitle1=
- uploader=swf
上記を見てもらえば分かるように、folder
と fid
でフォルダとファイル名を指定しているようです。なので、AtomAPI でも folder
と fid
を指定すれば、「指定フォルダ」に「指定の名前」でアップロードできるんじゃないか、と考えました。
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 の仕様変更で本方法は使えなくなる可能性がある
- 今回使ってないクエリを活用すると、もっと色々なことができるかも?
ブログにまとめると頭の中が整理できて、備忘録にもなるし、たまには技術的な内容も良いですね。