4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[GAS] 日本・アメリカ・台湾で明日が祝日だったらSlackに通知する

Posted at

はじめに

弊社(Whatever Co.) は、日本(Tokyo)以外にも、US(New York)や台湾(Taipei)にオフィスがあります。
基本的にはそれぞれの国内でチームを組むことが多いですが、案件によっては、日本のメンバーがUSや台湾チームと連携することがあります。

海外チームと連携するにあたり、時差もそうですが、祝日の存在に気をつける必要があります。
各国がいつ祝日なのか?を覚えるのが大変なので、非常にシンプルではありますが、
「明日が祝日だったらSlackに通知する仕組み」を作ってみました。

こんな感じで通知が届きます。
スクリーンショット 2023-04-05 18.51.08.png

(これまではメンバーが手打ちでSlackに投稿してくれていました。大変。。)

制作物

下記にコードをアップしています。

https://gist.github.com/genkitoyama/82d5d7cb9772e403e8e439a634079653

やったこと

  • 各国の祝日のGoogle Calendarを調べる
  • 次の日が平日かつ祝日だったら
  • Webhook経由でSlackに通知する
  • 毎日実行するようにトリガーを設定する

をやりました。

実装方法はいくつかあると思いますが、手っ取り早いと思ったGASで実装しました。

各国の祝日のGoogle Calendarを調べる

日本・アメリカ・台湾に関しては、Googleがすでに祝日用のカレンダーURLを用意してくれているので、それを使用します。

自分は Google Calendar の Add Calendar -> Browse calendars of interest ページに、
Regional holidays の項目があり、そこから Holidays in TaiwanHolidays in United States を見つけました。

スクリーンショット 2023-04-05 18.15.37.png

各カレンダーの詳細を見ると、 Calendar ID というものが記載されています。このURLを使用しました。
(余談ですが、最初はChatGPTに質問してたのですが微妙に違うURLが返ってきてたので手動で調べました。)

スクリーンショット_2023-04-05_18_26_53.png

1つハマったこととして、Holiday calendar content の設定があります。
これがデフォルトだと Public holidays and other holidays となっていますが、このままだと、その国の公的な祝日以外に、ローカルな祝日が含まれてしましました。(そのためオフィスは平日なのに祝日の通知が飛んでしまうことになる)
この項目を Public holidays only にすることで、公的な祝日だけを取得することができました。
スクリーンショット_2023-04-05_18_23_10.png

次の日が祝日かどうかを調べる

GASでカレンダー情報を取得するには、 CalendarApp.getCalendarById(calendarURL) を用います。
また、その日にイベント(= 祝日)があるかどうかは、 getEventsForDay(targetDate) で判定することができるので、
ここの targetDate を、明日(今日のDateに +1 したもの)に設定します。

var today = new Date();
var tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
var events = CalendarApp.getCalendarById(calendarURL).getEventsForDay(tomorrow);

これで、次の日が祝日かどうかが判定できます。

次の日が平日かつ祝日かどうかを調べる

また、次の日が土日だったら、元々休みで通知する必要がないため、
次の日が月曜〜金曜の平日だった場合のみ、上記処理を行うようにします。

//targetDateが平日だったらtrue、土日ならfalseを返す
function isWorkday(targetDate)
{
  const restOrWork = ["REST","mon","tue","wed","thu","fri","REST"]; // 日〜土
  if ( restOrWork [targetDate.getDay()] == "REST" )
  {
    //console.log("Tomorrow is not a working day.")
    return false;
  }
  return true;
}

//明日が平日の時だけ確認する
if(isWorkday(tomorrow))
{
  ...
}

WebhookでSlackに通知する

通知したい文章を用意したら、SlackのWebhook URLを取得して、叩くだけです。

function postToSlack(payload)
{
  var options = {
    "method" : "POST",
    "payload" : JSON.stringify(payload)
  }

  //slack webhook URL
  const slackURL = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

  var response = UrlFetchApp.fetch(slackURL, options);
}

今回の工夫としては、 payloadicon_emojiusername を指定することで、Slack上でわかりやすい見た目なりました。

payload = {
  "text" : remindTexts[0] + countryName + " 🇯🇵" + remindTexts[1] + events, // メッセージの本文
  "icon_emoji" : ":jp:",
  "username" : "Holiday in " + countryName,
  }

スクリーンショット 2023-04-05 19.01.44.png
(台湾に関しては、 icon_emoji がSlackに含まれていなかったので、 icon_url を使っています。)

毎日実行するようにトリガーを設定する

この処理が毎日実行されるようにトリガーを設定します。
今回は正確な時刻に毎回実行する必要はないので、1時間の幅がありますがGAS標準のTriggerを使います。

スクリーンショット 2023-04-05 23.11.11.png

おわりに

シンプルな仕組みですが、意外と役に立ちそうです。

ちなみに、弊社では ずっと祝日カレンダー というカレンダーを販売しています!
毎日がどこかの国の祝日になっているカレンダーです。よかったら買ってください。

参考にした記事

4
1
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
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?