kinoppyd.dev

blog

products

accounts & contact

MobbのCron

posted at 2018-12-04 03:27:06 +0900 by kinoppyd

このエントリは、Mobb/Repp Advent Calendar の四日目です

Cron Job

Mobbには、Botのための定期実行の仕組みが備わっています。MobbはSinatraをベースとしたBotフレームワークですが、完全にSinatraと同じことをするわけにはいきません。その一つが、Cronです。

Botの重要な役割の一つとして、定期実行が存在します。これはWebアプリケーションという世界には存在しない概念ですが、Botには必ず備わっていて欲しい機能です。例えば、BotをSlackに接続して、毎日決まった時刻に備忘のためのメンションをくれる、とかは重要な機能です。

重要な機能である一方、Webアプリケーションの世界に存在しないこの機能をどう扱おうかという考えはなかなか難しかったので、詳細はこのエントリを読んでください。

http://tolarian-academy.net/mobb-0-3-out-now/

Mobbでは、Cron実行のためにそのままCron Syntaxを採用しました。それに加えて、より人間にわかりやすいCron記述のために、WheneverというGemのパーサーも利用しています。CronとWheneverのどちらが簡単かは人によりますが、多くの人はWheneverのシンタックスのほうが親しみがあると思います。

https://github.com/javan/whenever

詳細はWheneverのドキュメントを参考にしていただければと思いますが、簡単な例をいくつかあげておきます。

require 'mobb'

every 1.hour, dest_to: 'times_kinoppyd' do
  '一時間経ったよ'
end

every 3.hours, dest_to: 'times_kinoppyd' do
  '三時間経ったよ'
end

every 1.day, at: '13:00', dest_to: 'times_kinoppyd' do
  '昼飯を食え'
end

every :friday, at: '4pm', dest_to: 'times_kinoppyd' do
  'プレミアムフライデーだ、早く帰れ'
end

タイマーアプリの例

require 'mobb'

clear :trigger

on /(\d+) min timer/ do |minutes|
  unless settings.trigger
    settings.trigger = Time.now + (minutes.to_i * 60)
    "#{minutes}タイマーセットしました"
  end
end

every 1.minute do
  if settings.trigger && Time.now > settings.trigger
    settings.trigger = nil
    '@kinoppyd 起きろ'
  end
end

これは、非常に簡単なタイマーアプリの例です。ひとつ注意してほしいのは、このタイマーは正確にn分を図ってくれるわけではなく、最大で+59秒の誤差があります。なぜなら、MobbのCronパーサーの最小の解像度は分であり、秒ではないからです。

最大で約一分の誤差があるタイマーですが、その一方でたったこの十数行のコードでSlack上のタイマーアプリが手に入ります。何かいい感じの応用を思いついて、アイディアを秒でbotにするには良い行数ではないでしょうか?