アルクマスケジュールをGoogleカレンダーへ登録するRubyスクリプトを、Herokuで定期的に実行する

前回の記事では、コマンドラインからアルクマスケジュールをGoogleカレンダーに登録しました。

Rubyを使って、アルクマスケジュールをGoogleカレンダーへと登録する - メモ的な思考的な


ただ、毎日コマンドラインから実行するのは手間なため、Herokuを使って定期的に実行するようにしてみました。
Herokuのスケジュール化にはアドオンを追加する方法もありますが、今回はgemで手軽に試せる「Clockwork」を使ってみましたので、その時の作業をメモしておきます。

主な追加したもの

  • gem
    • Clockwork: Heroku上でRubyスクリプトをスケジュール実行するために使用
    • dotenv: Heroku上で環境変数を設定するために使用
  • Herokuプラグイン
    • heroku-config: ローカルにある.envファイルの内容をHerokuの環境変数として設定するために使用

Heroku対応の流れ

Gemfileの修正

HerokuでRuby2.0.0とclockworkを使うため、Gemfileを修正します。なお、Rubyのバージョンを指定しない場合、現時点では2.0.0が使われるようです。

ruby "2.0.0"
gem "clockwork"
gather_scheduled.rbの作成

clockworkで使えるようにするため、「gather_scheduled.rb」ファイルを作成し、その中にHeroku + clockwork用の記述を追加します。

# coding: utf-8

require 'rubygems'
require 'clockwork'
include Clockwork

require_relative 'google_calendar'
require_relative 'arukuma_schedule'
 
handler do |job|
    arukuma = ArukumaSchedule.new
    cal = GoogleCalendar.new


    # カレンダー登録する日付のイベントを、一度削除する
    if arukuma.delible?
        events = cal.list_events_from_today
        cal.delete_events(events)

        puts "今日以降のイベントを削除しました"
    end


    # スクレイピング
    schedules = arukuma.list_events_from_today

    # カレンダー登録
    cal.insert_events(schedules)

    puts "今日以降のイベントを登録しました"
end
 
every(1.day, 'gather_arukuma')

Herokuでcron?もう古いかも、それ - Meltdown Countdown rev.



Procfileの作成

clockworkで「gather_scheduled.rb」を使うように記載します。

clock: bundle exec clockwork gather_scheduled.rb
Google API用の各種キーの取得方法を変更

GoogleAPI用の各種キーを保存したyamlファイルを .gitignore に登録しているため、そのままpushしてもHerokuでは動作しません。
そのため、Herokuではコマンドラインから「heroku config:set」で環境変数を設定することになりますが、環境変数が多いと手作業で行うのが手間になります。


探してみたところ、heroku-configプラグインを使えば、ローカルの.envファイルの内容をHerokuの環境変数としてpushできるとあったので、今回はそちらを利用してみます。
なお、ローカルでの実行は特に不要なため、gem「foreman」は利用していません。
Configuration and Config Vars | Heroku Dev Center


まずは、heroku-configプラグインをインストールします。

> heroku plugins:install git://github.com/ddollar/heroku-config.git
Installing heroku-config... done


あとは、以下の作業を行います。

  • .envファイルに、APIキーなどを追加
  • APIキーなどが含まれるため、.envファイルを.gitignoreに追加
  • .envファイルの読み込みに使うため、Gemfileに「dotenv」を追加
  • 各種キーを.envファイルから読み込むよう、google_calendar.rbを修正
アプリのタイムゾーンの変更

アプリではアルクマスケジュールを登録するかどうかを日本標準時で判断しているため、Herokuのタイムゾーンを変更する必要があります。
Herokuのタイムゾーン環境変数「TZ」に値を設定することで変更できますが、これも .env ファイルに記載しておきます。

TZ=Asia/Tokyo
bundle install

プログラム側の修正は完了したので、bundle installしておきます。

> bundle install --path vendor/bundle
コミット

以上の変更をcommitします。念のため、.envがステージングされていないか確認しておきます。

> git add .
> git status
> git commit -m 'hoge'
Herokuへアプリをアップ
> heroku create arukuma-scheduled
> git push heroku master


なお、Windowsで開発した場合、git pushのところで以下のワーニングが出ます。
今回のスクリプトは特にgemのバージョンには依存していないと思いますし、実際、問題なく動作します。

-----> Warning:
       Removing `Gemfile.lock` because it was generated on Windows.
       Bundler will do a full resolve so native gems are handled properly.
       This may result in unexpected gem versions being used in your app.
       In rare occasions Bundler may not be able to resolve your dependencies at all.
       https://devcenter.heroku.com/articles/bundler-windows-gemfile
Herokuの環境変数を設定

heroku-configプラグインを使い、Herokuの環境変数を設定します。


現在の環境変数の状態を確認します。

> heroku config
 has no config vars.


heroku-configプラグインにより、.envファイルの内容をpushします。

> heroku config:push
Config in .env written to 


再度確認すると、登録されていることが分かります。

> heroku config
=== pure-plains-2236 Config Vars
GOOGLE_ACCESS_TOKEN:  ...
(略)
Herokuアプリのタイムゾーンを確認

先ほど.envファイルに記載したタイムゾーンが反映されているかを確認します。
「heroku run console」を使い、現在のタイムゾーンが日本標準時となっていることを確認します。

> heroku run console
Running `console` attached to terminal... up, run.8244
irb(main):001:0> Time.now
Time.now
=> 2013-12-28 06:37:05 +0900

herokuでタイムゾーン設定 - Qiita


なお、以前は使用できた、heroku consoleは削除されているようですので、実行すると以下のメッセージが表示されます。

> heroku console
`heroku console` has been removed. Please use: `heroku run` instead.
For more information, please see:
 * https://devcenter.heroku.com/articles/one-off-dynos
 * https://devcenter.heroku.com/articles/rails3#console
 * https://devcenter.heroku.com/articles/console-bamboo


また、heroku run console などはOne-off Dynoに当たることから、課金時間に加算されるため使いすぎには気をつけます。
知っておきたい!Herokuを使う上では当たり前?の16の常識 | mah365



Herokuのプロセスを作成する

今回はRubyスクリプトだけなので、プロセスは起動していないことを確認します。
特に結果は返ってきませんが、プロセスが存在していないと考えられます。

> heroku ps


今回はProcfileの中に「clock」というプロセスを記載しているので、clockプロセスを1つ加えます。

> heroku scale clock=1


再度確認すると、clockプロセスができたことが分かります。

> heroku ps
=== clock (1X): `bundle exec clockwork gather_scheduled.rb
clock.1: up 2013/12/28 06:38:20 (~ 2s ago)

実行と確認

Clockworkによる実行結果の確認

Herokuのログを確認すると、問題なく動作しているようです。

> heroku logs

Logging | Heroku Dev Center



Herokuでgather_all.rbを実行

Googleカレンダーに今月分を登録するには、Heroku上でRubyスクリプトを直接動かすため、以下のコマンドを実行します。

> heroku run bundle exec ruby gather_all.rb
Running `bundle exec ruby gather_all.rb` attached to terminal... up, run.5979
今月のイベントを削除しました
今月のイベントを登録しました


こちらも問題なく動作しました。



ソースコード

この記事を書いた時点のソースコードは以下にアップしました。
thinkAmi/arukuma2gcal at v20131229 · GitHub