ツナワタリマイライフ

日常ネタから技術ネタ、音楽ネタまで何でも書きます。

はてなブログ更新予告ツイート投稿スクリプトをrubyで書いた

はじめに

take-she12.hatenablog.com

複数アカウントにシェアするスクリプトを前回書いた。投稿予告をしたいなと思っていたので実装した。

はてなブログ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がまだあんまり分かってない。。。けどxmlrubyでいろいろやるって知ってて損はないのでもうちょっと最適化を図りたいです。