我が家でもRaspberry Piを常時起動し始めました。Raspbery Pi+CentOSという組み合わせからくる苦労もありますが、楽しく付き合っています。
Raspberry Piといえば電子工作ですが、単純に常時起動のLinuxとしても有効活用したいと思ったところから、電車遅延通知用のSlack Bot作ることにしました。
元になる電車遅延データ
元となるデータはこちらの鉄道コムさんのRSSデータを使わせていただくことにしました。
使わせていただくデータはこのあたりです。
RSS2.0形式の電車遅延データ http://api.tetsudo.com/traffic/rss20.xml
電車遅延データ(関東) http://api.tetsudo.com/traffic/rss20.xml?kanto
関連ファイル
関連するファイルは以下の3ファイルです。RubyスクリプトとYAML設定ファイルを準備して同じディレクトリに配置します。
ファイル名 | 内容 |
---|---|
notify_train_delay.rb | Rubyスクリプト(systemdによるスケジュール実行) |
notify_train_delay.yml | YAML形式の設定ファイル |
notify_train_delay.dat | 重複通知回避用の履歴情報(自動生成) |
Rubyスクリプト
Slack通知のために以下のライブラリをインストールしておきます。
gem install slack-incoming-webhooks
スクリプトは以下の通りです。notify_train_delay.rbという名前で保存します。
require 'rss' require 'yaml' require 'slack/incoming/webhooks' config_file = File.expand_path(__FILE__).sub(/\.[^.]+$/, '.yml') history_file = File.expand_path(__FILE__).sub(/\.[^.]+$/, '.dat') config = YAML.load_file(config_file) items = RSS::Parser.parse(config['url']).items DelayInfo = Struct.new(:title, :pubDate, :description, :link) delay_data = [] config['railways'].each do |r| items.select do |i| i.category.content.include?(r['domain']) && i.title.include?(r['railway']) end.each do |item| delay_data << DelayInfo.new(item.title, item.pubDate, item.description, item.link) end end history_data = File.exist?(history_file) ? YAML.load_file(history_file) : [] updated_data = delay_data - history_data open(history_file,'w') { |f| YAML.dump(delay_data,f) } updated_data.each do |data| slack = Slack::Incoming::Webhooks.new "#{config['slack']['webhookurl']}", \ channel: "#{config['slack']['channel']}", \ username: "#{config['slack']['username']}", \ icon_emoji: "#{config['slack']['icon_emoji']}" attachments = [{ title: "#{data.title}", text: "#{data.pubDate} \n ``` #{data.description} ``` \n #{data.link}", color: "warning", mrkdwn_in: ["text"] }] slack.post "", attachments: attachments end
YAML形式の設定ファイル
設定ファイルをnotify_train_delay.ymlというファイル名で保存します。
例えば今現在、こちらを確認すると湘南新宿ラインで遅延が発生しています。
設定ファイルの項目における、domainは画面左側の「JR東日本(関東地区)」や「東京メトロ」と、railwayは右側の「東海道線・高崎線・湘南新宿ライン」と文字列一致を確認して、遅延情報をチェックする仕様です。
--- url: http://api.tetsudo.com/traffic/rss20.xml railways: - domain: JR東日本 railway: 埼京線 - domain: JR東日本 railway: 湘南新宿ライン - domain: 東武鉄道 railway: 東上 slack: webhookurl: https://hooks.slack.com/services/XXXXXX/XXXXX/XXXXXX channel: "@yusuke.otomo" username: Raspberry Pi icon_emoji: ":train:"
systemd timerによるスケジュール起動
スクリプトと設定ファイルの配置が完了したら、スケジュール実行のためにsystemdの設定に入ります。
まずは、サービス定義を作ります。ExecStartに実行するコマンドを定義しておきます。
サービス定義とはなっていますが、一回コマンドが実行したらサービスも停止します。(つまり通常のコマンド実行とほぼ一緒です)
cat <<EOF > /etc/systemd/system/NotifyTrainDelay.service [Unit] Description=NotifyTrainDelay [Service] Type=simple ExecStart=/root/.rbenv/shims/ruby /root/tools/notify_train_delay.rb [Install] WantedBy=multi-user.target EOF
タイマーからサービスをスケジュール起動させてます。 重要なのはOnCalendarの項目で、月曜から金曜まで、7-10時まで毎時実行と、17-21時まで毎時チェックかけています。
Unitにはタイマーの実行対象として先ほど作成したServiceを定義します。
cat <<EOF > /etc/systemd/system/NotifyTrainDelay.timer [Unit] Description=Runs NotifyTrainDelay Script [Timer] OnCalendar=Mon-Fri *-*-* 7,8,9,10,17,18,19,20,21:00:00 Persistent=true Unit=NotifyTrainDelay.service [Install] WantedBy=multi-user.target EOF
最後にserviceとtimerを有効化しておきます。
systemctl daemon-reload systemctl enable NotifyTrainDelay.service systemctl start NotifyTrainDelay.timer systemctl enable NotifyTrainDelay.timer
タイマーが登録されているか確認します。
systemctl --system list-timers
電車遅延のSlack通知
Slack通知はこのような感じでです。