はじめに
複数アカウントにシェアするスクリプトを前回書いた。投稿予告をしたいなと思っていたので実装した。
はてなブログのAPI
はてなブログAtomPub - Hatena Developer Center
AtomPub形式でxmlが取得できる。単純にcurlをすれば良い。ログイン後の設定→詳細設定にルートエンドポイントとAPIキーがある。このユーザ名とAPIキーが認証情報だ。実際の実行方法は次。
cronで実行するシェル
# hatena-yokoku.sh #!/bin/sh curl --user take_she12:<APIキー> https://blog.hatena.ne.jp/take_she12/take-she12.hatenablog.com/atom/entry > output.xml chmod 755 /home/take/script/output.xml ruby /home/take/script/hatena-yokoku.rb
これを以下のcronで呼んでいる。
# crontab 0 8 * * 1,3,5 take /bin/bash -lc '/home/take/script/hatena-yokoku.sh >>/tmp/exec.log 2>>/tmp/exec_error.log'
月水金の朝8時に実行する。 bashの設定読み込みは不要だったかもしれない。 なぜ出力したxmlファイルの権限を変えているかというとrubyファイルでの読み出してpermissionエラーになったから。多分、実行権がいる。
rubyスクリプト
#hatena-yokoku.rb require 'rubygems' require 'twitter' require 'pp' require 'rexml/document' require 'date' require 'time' # open xml file doc = REXML::Document.new(File.new("/home/take/script/output.xml")) # initialize title = [] updated = [] draft = [] hash = {} # element extraction doc.root.elements['//feed'].elements.each do | elem | elem.elements.each do |elems| if elems.name == 'title' title << elems.text end if elems.name == 'updated' updated << elems.text end end end #store hash only future entry updated.zip(title) do |updated, title| date = DateTime.parse(updated) if date > DateTime.now hash.store(date.mon.to_s + "/" + date.day.to_s,title) end end # sort and take 3 entry cnt = 0 @tweet = "" hash.sort.each {|key,val| @tweet << "#{key}=>#{val}," cnt += 1 break if cnt == 3 } # authentication client = Twitter::REST::Client.new do |config| config.consumer_key = (省略) config.consumer_secret = (省略) config.access_token = (省略) config.access_token_secret = (省略) end client.update("ブログの更新予告です。#{@tweet}")
本当はnet/httpでrubyファイル1つでapi発行からやりたかったんだけどうまくいかず。。。予告ツイートをとりあえず実装するためにcurlと分けました。
zipってメソッドははじめて知った。便利ですね。
xmlのfeed以下を読み込んで、titleとupdateの項目を取得して配列に格納。 そのあとupdateをdatetime型にparseして、現在時刻より先のものだけ、titleとペアでhashに格納。 hashをkeyでsortしてstringに変換、そしてツイートという流れです。
課題
大きく2つあります。
- 1ページ目しか取得していない
これ、今のストック数だと2,3ページ目まで取得しないとちゃんと直近の予告になりません。2/8なのに2/12・13・14の予告になっちゃったりする。 xmlを見るとnextのpage番号が記載されてるのでこれを取得して次のファイルを取得ってしないといけない。面倒。。。
- 公開も下書きも一緒に取得している
xmlをよく見ると以下の項目がある。
<app:control> <app:draft>yes</app:draft> </app:control>
これでdraftのものだけを取得すればもっと楽になるかな??あんまり変わらないかもしれないけど。
rexmlがまだあんまり分かってない。。。けどxmlをrubyでいろいろやるって知ってて損はないのでもうちょっと最適化を図りたいです。