id:bash0C7の進捗 過去アーカイブ[〜2019-02-23]

最新情報は https://www.pixiv.net/fanbox/creator/3780274 にて

NHKの次の番組情報を #fluentd 経由でidobataに流す

NHK番組表APIが公開されたことと、それを簡単に叩けるgemのnhk_program-for-rubyがリリースされたことを知り、とても使ってみたくなりました。 そこで、ご自宅のFluentdで定期的にNHKの次の番組の情報を取得し、idobataに流してみることにしました。

NHKの番組表APIから番組データを取得

NHK番組表APINow On Air API (Ver.1) | NHK番組表APImitukiii/nhk_program-for-ruby · GitHubを使って叩いています。

fluentdから番組データを取得する

bash0C7/fluent-plugin-ruby_eval · GitHub からnhk_programを使っています。

fluent-plugin-ruby_evalとは

こんな感じです。ご覧のとおり、まだちゃんと説明できないぐらいに考えが練られていないので、どなたか相談に乗っていただきたいところです。

gemを叩いてストリームとして流し込みのだけど、それ専用のプラギン作るの面倒だよねー。とはいえin_execでruby -eするのもまた色々大変そうな気がするだよなー。 そこで、fluentdの設定ファイルにRubyのコード片を書いて、そこからemitしてやろう。プラグインはそのコード片と、読み込むべきライブラリ、実行インターバルだけ管理してやろう。 そうすれば、アドホックにgem叩いてちょっと処理してemitするのが試しやすいんじゃないか。

そう思って作ってみました。

設定ファイルsampleはも少し下にあります。

idobataに流す

公私ともにお世話になっている素晴らしいグループチャットのIdobataに、またもお世話になることにしました。 bash0C7/fluent-plugin-idobata · GitHub 経由で流し込んでいます。

設定ファイルsample

ruby_evalが見どころ。

  • 前処理*1の中でnhk_programをrequireします。カンマ区切りで複数かけます。
  • run_intervalの間隔で、commandのコード片を実行します。このコード片は、前処理*2の中で、lambda {#{@command}}することで、プラグインの中のコードの一部として扱うようにしています。もちろんすごい勢いで自分の足を撃ちぬくことができます。
<source>
  type ruby_eval
  require_libs nhk_program
  command following = NHKProgram.new(api_key: 'API_KEY').now('130', 's3')['nowonair_list']['s3']['following'] ;Engine.emit('sekaineko', Engine.now, following);
  run_interval 900
</source>
<match sekaineko.**>
  type idobata
  webhook_url https://idobata.io_WEBHOOK_URL
  message_template 次は<%= DateTime.parse(record['start_time']).strftime("%H:%M") %>から<%= record['title'].force_encoding('utf-8') %>です
</match>

String#force_encoding('utf-8') が苦労の跡です。これがないと

Encoding::CompatibilityError, 'incompatible character encodings: UTF-8 and ASCII-8BIT

と言われてしまいました。irbから使った時は問題なかったのに…。どうしたらいいのかなあ。

実行結果

idobataには900秒ごとに下記のようにメッセージが飛びます。

Generic  1:38
次は03:30から音楽都市散歩「ウィーン」です

本当は世界ネコ歩きの気配だけわかればいいのだけど*3、encodingまわりがうまく扱えなかったので、まずは15分に一度次の番組の時間とタイトルを流してみています。

今後

特定条件に合致したときだけ、通知が流れるようにしようと思います。 よく考えたらrewriteプラグインを挟めばシンプルですね。

*1:configureメソッド

*2:configureメソッド

*3:わかったところでどうするわけじゃないんですけどね