LoginSignup
17
15

More than 5 years have passed since last update.

祝日にリマインドしないSlackリマインダーを作りました【Slack Reminder as Code】

Posted at

Slackの公式リマインダーが(日本の)祝日を解釈してくれないので、祝日を除外したSlackリマインダーを作りました。

tksugimoto/aws-lambda_slack-reminder-except-holiday

特徴

  • 土日祝日はリマインドしない
    • 年末年始など任意休日も設定可能
  • リマインダーをテキスト形式で管理可能(Slack Reminder as Code
  • リマインダーの作成 / 変更の反映はコマンド一発
    • terraform apply
11時30分にお昼を通知するリマインダーのレシピ
module "slack_reminder_sample" {
    source = "./slack_reminder"
    prefix = "${var.prefix}"
    iam_for_lambda_arn = "${aws_iam_role.iam_for_lambda.arn}"

    # ↓ ここから設定 ↓
    name = "lunch"
    reminder_text = "そろそろお昼です"

    schedule_name = "every_day_11-30am_JST"
    schedule_expression = "cron(30 2 * * ? *)"

    slack_webhook_url = "${var.slack_webhook_url}"

    # 祝日追加(年末年始など)
    additional_holidays = "12/30-31 1/1-7"
}

経緯

  1. Slackのリマインダー機能で平日の夕方にリマインド投稿を設定していた
  2. 2016年の勤労感謝の日(11/23)は水曜日だったのでSlackで設定した平日のみのリマインダーはいつもどおり実行された
  3. BOSS :angry: :anger:
    祝日のSlack reminderに激おこ.png

仕組み

毎日のリマインダー

  1. AWS CloudWatch Eventsのスケジューラーを使って毎日定刻にAWS Lambda起動
  2. AWS LambdaからSlackのIncoming WebHooksを使ってSlackに投稿
    • AWS Lambda関数内で土日・祝日・独自定義休日の判定を行ない平日のみ投稿

上記環境の自動構築

  • Terraformを使用
    • Terraformを使うことでリマインダーをテキスト形式で管理可能
    • AWS Lambdaの環境変数とTerraformのmodule機能でリマインダーの複数定義をサポート

設定例・書式

11時30分にお昼を通知するリマインダーのレシピ(30_main.tf)
module "slack_reminder-2" {
    source = "./slack_reminder"
    prefix = "${var.prefix}"
    iam_for_lambda_arn = "${aws_iam_role.iam_for_lambda.arn}"

    # ↓ ここから設定 ↓
    name = "lunch" # AWSのマネジメントコンソールに表示されるのでわかりやすく一意なもの
    reminder_text = "そろそろお昼です"

    schedule_name = "every_day_11-30am_JST" # AWSのマネジメントコンソールに表示されるのでわかりやすいもの
    schedule_expression = "cron(30 2 * * ? *)" # ※ UTCなので日本時間-9時間

    slack_webhook_url = "${var.slack_webhook_url}"

    # 祝日追加(年末年始など)
    additional_holidays = "12/30-31 1/1-7"

    # オプション設定(設定なし/空文字の場合はWebhookのデフォルト値)
    channel = "#random"
    username = "reminder bot"
    icon_emoji = ":bento:"
}

※ 適切なシンタックスハイライトが無かったので、一番見やすいと思ったbashにしてあります

↑のリマインダーは↓のようになります。
2016年の天皇誕生日12/23(金)にはリマインドされてないことが確認できます。
image

設定のサンプル 30_main.tf.sample を見てもらえればどんな書き方があるのか分かりやすいと思います。
注意点は、スケジューラーはUTCなので、 schedule_expression に書く時刻は日本時間-9時間である必要があることです。
スケジュール書式の詳細は → Rate または Cron を使用したスケジュール式 - AWS Lambda

使い方

tksugimoto/aws-lambda_slack-reminder-except-holidayのREADME参照。

料金

通常のリマインダーなら無料枠内で収まります。

実行環境 AWS Lambda

無料枠が多いのでこのリマインダーによって課金されることは通常は無いと思われます。

100 万件 1 か月あたりの無料リクエスト数
1 か月あたり最大 320 万秒 1 か月あたりのコンピューティング時間
12 か月間の AWS 無料利用枠期間終了後にも期限切れになりません。

無料のクラウドサービス | AWS 無料利用枠

実際の実行時間のログ(一例)を以下に示します。

休日(Slackへの通信なし)
Duration:  6.08 ms  Billed Duration:  100 ms Memory Size: 128 MB    Max Memory Used: 17 MB
Duration:  2.08 ms  Billed Duration:  100 ms Memory Size: 128 MB    Max Memory Used: 12 MB
Duration: 49.61 ms  Billed Duration:  100 ms Memory Size: 128 MB    Max Memory Used: 16 MB
平日(Slackへの通信あり)
Duration: 749.63 ms Billed Duration:  800 ms Memory Size: 128 MB    Max Memory Used: 18 MB
Duration: 983.10 ms Billed Duration: 1000 ms Memory Size: 128 MB    Max Memory Used: 20 MB
Duration: 719.58 ms Billed Duration:  800 ms Memory Size: 128 MB    Max Memory Used: 20 MB

Slack(Incoming Webhooks)へ通信しない休日は100 ms以下で、通信する平日は800m s程度でした。

簡単のために毎日が平日で1000 ms / day / reminderのLambda実行がされたとすると、無料枠を超えるには約10万リマインダーの設定が必要です。これは1秒に1回以上リマインドされる計算になります。
なお、無料枠を既に超えている場合は、メモリの最小単位128MBで $ 0.000000208 / 100 ms なので、1種類のリマインダーを1ヶ月動かすと、

$\, 0.000000208 / 100\, \mathrm{ms} \times 1\, \mathrm{s} / \mathrm{reminder} \times 31\, \mathrm{reminder} / \mathrm{month} = $\, 0.00006448 / \mathrm{month}

日本円で約 0.007円となります。

定期的な実行 AWS CloudWatch Events

とても安いので無視してよいと思います。
100万リクエストで $1 だそうなので、約300種類のリマインダーを1ヶ月動かすと1円になります。

Amazon CloudWatch Events - Custom Events
$1.00 per million custom events generated

料金 - AWS CloudWatch | AWS

祝日判定

Node.jsのpackage japanese-holidays を使っています。
npmでインストールできて、依存が少ないものを選択しました。
その年の祝日をすべて計算しているので若干計算量が多いですが、AWS Lambdaが十分高速&1リマインダーで1回しか呼ばないので計算時間は誤差と判断しました。

17
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
15