【GAS無し】Googleスプレッドシート + Slack Workflowのみで祝日通知を作成する

# 前書き
この記事のやり方で、以下のような投稿を行うSlack Workflowを作成することができます。
![スクリーンショット 2023-02-28 0.17.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280230/8e001e9d-08bb-1e6b-a2ad-8cfc15f2171f.png)

この記事で紹介するやり方は、`GAS`や特別な`API`作成や契約を必要とせず、GoogleスプレッドシートとSlack Workflowで完結し、自動更新にも対応しています。
あまり知識が無い状態で作成しているので、何か改善点など有りましたら教えて頂けると助かります。

# やり方
この記事では、主に祝日管理用スプレッドシートの作成方法に関して解説します。
Slack Workflowの作成方法やスプレッドシートを参照する方法に関しても軽く解説します。

なお、Slack Workflowでスプレッドシートを使用するには、公式から提供されている`Google Sheets for Workflow Builder`を導入する必要が有ります。
申請など必要なら先に済ませることをお勧めします（自分の環境では導入済みでした）。

https://slack.com/intl/ja-jp/help/articles/11086384874259-%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%95%E3%83%AD%E3%83%BC%E3%83%93%E3%83%AB%E3%83%80%E3%83%BC%E3%81%A7-Google-%E3%82%B9%E3%83%97%E3%83%AC%E3%83%83%E3%83%89%E3%82%B7%E3%83%BC%E3%83%88%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B

## 祝日管理スプシの作成方法
スプシのサンプルは以下のURLに置いてあります。
ご自身で用意したシートに上2行をコピーしてご利用下さい（後述の理由から、最初は表示エラー状態になります）。
`加える日数`セルを適当な日数に変更し、`フォーマット済み`セルの結果表示セルだけSlack投稿に組み込めば、それで動きます。

https://docs.google.com/spreadsheets/d/1ra77halivEyq71aIiDxUEScxPgBGIVbV_jzBe8QUtvA

![スクリーンショット 2023-02-28 10.13.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280230/828108d1-b7a4-43e8-9fd6-bb6180d399bd.png)

このスプシに関しては、特にリロードすると表示エラーが出ることを確認しています。
そうなった場合、`今日`セルの値を一度消してから戻すことで、表示エラーを解消できます。
一応表示エラーが起きている間も通知は正常に動くようでした。

<details>
<summary>表示エラー時のスクショ</summary>

![スクリーンショット 2023-02-28 10.14.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280230/5a24d4b7-4562-e031-88f1-a0797a577267.png)
</details>

以下、このスプシでやっていることを解説します。

### 集計期間の指定
まず、`B2:D2`の範囲で集計期間を設定しています。

| 今日       | 加える日数 | 集計末日 | 
| ---------- | --- | -------- | 
| `=today()` | 100 | `=B2+C2` | 

サンプルでは期間を100日としていますが、ここを14にすれば2週間、0にすれば今日だけ、と調整することができます。

### 祝日の取得
祝日は`今年・来年の祝日`セルで取得しています。

| 今年・来年の祝日 | |
| - | - |
| `= { IMPORTDATA("https://holidays-jp.github.io/api/v1/" & Year(B2) & "/date.csv", ",");   IMPORTDATA("https://holidays-jp.github.io/api/v1/" & Year(B2) + 1 & "/date.csv", ",") }` |  | 

祝日の取得には @matsuoshi 様の公開されている[日本の祝日一覧を返す API](https://holidays-jp.github.io/)を利用させて頂きました。
こちらの`API`は https://holidays-jp.github.io/api/v1/2023/date.csv というように、年指定で祝日一覧を取得することができます。
データソースはGoogleカレンダーで、期間的には去年〜来年分まで取得できるそうです。

これらのセルでは、`今日`から取得した年を使って`API`を実行し、結果を`IMPORTDATA`関数で取り込んでいます。
このシートでの取得対象は、年末年始を考慮して来年分までとしています。

**追記**
`GAS`無し・スプレッドシートのみで祝日カレンダーを作成できたので、外部`API`に依存するのがどうしても嫌という方はこちらをご利用下さい。
上で紹介している方法とデータソースは同じです。

https://qiita.com/wrongwrong/items/1c235ea33e254580ff45

<details>
<summary><b>補足: こちらの<code>API</code>を採用した理由</b></summary>

こちらの`API`を採用した理由は、無料かつ`CSV`で取得できることです。

まず、記事執筆時点で、Googleスプレッドシートがデフォルトで読み込めるのは`CSV`等の限られたデータだけでした。

https://support.google.com/docs/answer/12188454?hl=ja

他の`API`もいくつか確認しましたが、`CSV`で結果を提供しているものは見つからなかったです。
~~[Googleの提供する祝日カレンダーの生データ（`ICS`）](https://calendar.google.com/calendar/ical/ja.japanese%23holiday%40group.v.calendar.google.com/public/basic.ics)を利用することも考えましたが、残念ながら`GAS`無しで利用する方法は見つけられませんでした（正確には、頑張って解析することも不可能ではなさそうでしたが、難しそうだったため諦めました）。~~ 追記した通り、こちらはできるようになっています。
また、[内閣府の公開している`CSV`](https://www8.cao.go.jp/chosei/shukujitsu/gaiyou.html)は文字化けで読めなかったため、利用しませんでした。
</details>

### 集計期間内の祝日の切り出し
**追記**
`=IFNA(FILTER(E2:F40, (B2 <= E2:E40) * (G2:G40 <= D2)))`とすることで、下記で紹介しているフィルタリングはまとめられます。

---

集計期間内の祝日の切り出しは`フィルタ済み1（今日以降）`と`フィルタ済み2（今日以降集計末日まで）`で行なっています。

| フィルタ済み1（今日以降） |  | フィルタ済み2（今日以降集計末日まで） |  |
| - | - | - | - |
| `=FILTER(E2:F40, B2 <= E2:E40)` | | `=FILTER(G2:H40, G2:G40 <= D2)` | |

やっていることはヘッダの通りですが、シンプルなやり方が分からず、2段階に分けて「今日以降集計末尾まで」を切り出しています。

### 投稿用にフォーマット
最後に、`フォーマット済み`セルで投稿用にフォーマットした文字列を用意しています。

| フォーマット済み |
| - |
| `=IF(ISBLANK(I2), "なし", TEXTJOIN(CHAR(10), TRUE, MAP(I2:I40, J2:J40, LAMBDA(date, label, IF(ISBLANK(date), "", CONCATENATE(TEXT(date, "yyyy/MM/dd(ddd)"), ": ", label))))))` |

範囲内に祝日が無ければ`なし`、有る場合は`2023/03/21(火): 春分の日`というようなフォーマットを改行で結合した文字列になります。

## Slack Workflowの作成について
実際に利用しているSlack Workflowに設定している内容を簡単に書きます。
この辺りは他の解説記事の方が詳しいと思われるため、ここでは詳細までは書きません。

### `Select spreadsheet row`ステップ
`Select spreadsheet row`ステップでは以下を設定しています。

- `Select a spreadsheet` -> 作成したスプシ
- `Sheet` -> 作成した祝日管理シート
- `Choose a column to search` -> `LOOKUP`（※サンプルシートの`A1`セル）
- `Define a cell value to find` -> `TRUE`（※同`A2`セルの値）

### `Send a message`ステップ
上のステップを経ることで、`Insert a variable`の`Select a spreadsheet row`セクションから、作成したスプシ内の値を変数として取り込むことができます。

# おまけ: この方針を選んだ理由
この方針のキモは、スプシとSlack Workflowを扱える人間なら誰でもメンテナンスできることです。
仮に利用可能な祝日`API`が無くなったとしても、年1回のメンテナンスだけで済むなら手動で十分運用できるでしょう。

検索で見つかった`GAS`などに依存する方針を採用しなかったのは、この辺りのことを考えたからです。
弊社内ではSlack Workflowからスプシを参照するのも一般的なやり方だったため、そちらは問題になりませんでした。