金曜の夜になったら会社の Slack 通知を自動でミュートしたい

# はじめに
「休日は会社の Slack をミュートしておきたい！」という要望は普通にあると思うのですが、
2019年12月15日現在、**Slackには特定の曜日に自動で「おやすみモード」にする機能はありません。**

そこで色々と試してみたのですが [Zapier](https://zapier.com)（または [IFTTT](https://ifttt.com/)）で [Slack API](https://api.slack.com) を叩く方法が無料かつ最も簡単にできたので、
本記事ではその手順を解説していきます。

# 手順

まず大まかにやることをまとめると、

- Slack 側で API を利用できるよう設定する
- IFTTT / Zapier 側で「時刻が金曜の21時であるとき」「Webhook / JavaScriptから API を叩く」アプレットを作る

の２つです。

### Slack側の設定

Slack 側では Web API の利用を許可し OAuth トークンを取得する必要があります。

そのためには Slack App を作成しなくてはならないので、以下では必要最低限な App の作り方を解説します。

まず[ Slack API](https://api.slack.com) のページにアクセスし、中央の [Start Building] ボタンを押しましょう。

![スクリーンショット 2019-12-15 1.14.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123809/f5813624-797c-c3d6-ffc1-ec0c6a63be53.png)

APP 名を適当に入力し、どのワークスペースに作成するかを選択後、右下の [Create App] を押します。

![スクリーンショット 2019-12-15 1.14.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123809/c9cbc0b9-e8b4-c24d-6a22-e6f2675917df.png)

すると何かゴチャゴチャしたページに飛ぶので、Add features and functionality 節の右下辺りの [Permissions] を選択します。

![スクリーンショット 2019-12-15 1.20.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123809/a8b5822d-e053-2691-3fc3-3d5ead632790.png)

このページでどういう API の使用を許可するのかを設定します。

Scope 節の [Add an OAuth Scope] ボタンを押しましょう。
（大きい緑のボタンではなく下の白いボタンの方なので注意）

![スクリーンショット 2019-12-15 1.23.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123809/9dd25222-3892-3fa8-8c6d-eba84ebf9306.png)

[今回利用するAPI の仕様](https://api.slack.com/methods/dnd.setSnooze)によると、権限として dnd:write が必要と書いてあるので、検索し選択します。

![スクリーンショット 2019-12-15 1.26.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123809/3ae49ac7-f774-9f89-6345-b9f4c8a1767c.png)

その後ページの一番上に戻ると、App がインストールできるようになっています。

![スクリーンショット 2019-12-15 1.26.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123809/9958a346-2805-f154-5836-5e0af0f7b08f.png)

インストールに成功すると API を叩くのに必要な OAuth トークンが表示されます。

このトークンを知っている人は誰でも API を叩けるので管理には一定の注意が必要です。
（今回の場合はおやすみモードの切り替えができるだけと思いますが一応）

Slack 側の設定はこれで完了です。トークンだけ後々使用します。

### IFTTT / Zapier側の手順

##### IFTTT と Zapier、どちらを選ぶべきか

どちらも似たようなサービスですが、基本的にはZapierの方が高機能と言えます。

IFTTT はアクションが一つしか登録できないなど制限は多いですが、
Webhook が無料で利用でき UI もわかりやすいため、単純な用途であれば IFTTT をオススメします。

Zapier はよりカスタマイズ性が高く、何より**Node.js や Python のコードを実行することができます**。
機能を細かく調整したい場合や拡張性を持たせたい場合は Zapier がいいと思います。

IFTTT の Webhook の使い方はググればたくさん出てくると思うので、
本記事では Zapier の Node.js からAPIを叩く方法をご紹介します。

##### Zapierの手順

Zapier への登録方法は割愛します。

ログイン後、右上の [Make a Zap!] ボタンを押してください。

![スクリーンショット 2019-12-15 1.46.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123809/7f396631-000c-9119-b2e4-ca26a87045e7.png)

まずはトリガーとなる App を選択してと言われるので、時刻をトリガーとする [Schedule by Zapier] を選択します。

![スクリーンショット 2019-12-15 12.34.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123809/c8582fb8-82f3-fa42-f5ce-663f2f13ccd6.png)

次に、どういう条件でトリガーさせるかを聞かれます。

トリガーさせたい曜日が１つだけの場合は every week, 複数ある場合は everyday を選択するといいです。

今回は説明のため everyday を選択します。

![スクリーンショット 2019-12-15 12.36.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123809/dd3fbf2c-ae13-18e0-a5e7-f4c4684f6d97.png)

上で everyday を選択するとトリガーさせる時刻を聞かれます。
金曜の午後９時以降は会社のことを忘れたいので「9pm」を選択し、CONTINUE します。

![スクリーンショット 2019-12-15 12.38.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123809/e7734b0e-8846-38e6-1fdb-41be8ee9ae2f.png)

次の画面で [TEST & CONTINUE] というボタンが出るので、押下してトリガーの設定を完了します。

次はアクションの設定です。下の [Do this...] をクリックしましょう。

![スクリーンショット 2019-12-15 12.42.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123809/a7c1ad2b-0217-396a-c0c8-cb08eb389c6c.png)

App は Code by Zapier を選択します。

![スクリーンショット 2019-12-15 12.44.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123809/a31336df-a01f-8be1-0710-c5c463ffab7b.png)

Node.js の ver 10.x.x を選択します。

![スクリーンショット 2019-12-15 12.45.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123809/82cdee6c-2df6-8577-038c-69d7100b4c79.png)

次に実行したいコードを記述していくのですが、その前に Zapier の Code のしくみをざっくり解説します。

##### Input Data

Code の設定項目には「Input Data」と「Code」があるのですが、まずはInput Dataから説明していきます。

![スクリーンショット 2019-12-15 12.53.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123809/7d237b5a-ae6c-9c88-520d-63b6c572b297.png)

Input Dataでは、一つ前のトリガーやアクションからどういうデータをどのように受け取るかを設定します。

具体的にはここで「データのプロパティ名」と「データの種類」を入力しておくと、
コード内で`inputData.プロパティ名`の形でそのデータを取得できるようになります。

今回はスケジュールトリガーから曜日データを受けとりたいので、Pretty Day Of Week（整形された曜日情報）を、`dayOfWeek`のプロパティ名で受け取れるように設定しています。

##### Code

Code 節には実行するコードを書くのですが、少しクセがあって、

- コード全体が async function にラップされている
- オブジェクトまたはオブジェクトの配列を`output`という定義済み変数に入れなければならない

となっています。

`output`に入ったものが次のアクションに渡されるしくみになっていて、
**次のアクションがない場合でも必ず値を入れなければなりません。**

また async function なので`await`を使用することが可能です。
というか非同期の場合に`await`を使わないと`output`に何も入ってないよ！とエラーになる可能性があります。

実際のコードは以下のようになりました。

```javascript:code
const https = require('https');

const endpoint = 'https://slack.com/api/dnd.setSnooze'
const token = '<Slackで取得したトークンを入れてね！>'

if(inputData.dayOfWeek === 'Friday') {   
    const numMinutes = 60 * (48 + 9) // 2 days and 9 hours.
    const url = `${endpoint}?token=${token}&num_minutes=${numMinutes}`
    
    // オブジェクトまたはオブジェクトの配列を確実に返さないとエラーになる
    output = await fetch(url).catch(error => {
        return error
    })
}
```

※細かいことを言えば、トークンを直書きしているのでZapier の中の人が見ようと思えば見ることができます。それが気になる方はセキュリティ強化された [Zapier Platform](https://zapier.com/platform) を利用するなどしてください。

上記コードを入力後、[CONTINUE] を押して次のような表示が出れば・・

![スクリーンショット 2019-12-15 13.17.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123809/63166354-3506-451e-51a4-f0e6173058e5.png)

あとは作ったアプレットを ON にするだけで全て完了です！
お疲れ様でした。

# 補足
- シンプルな要件のわりにはそれなりに実現が大変でした。公式で機能を作ってくれるといいですね。

- 今回の方法だと週末以外の休日には対応できませんが、[カレンダー](https://zapier.com/apps/google-calendar/integrations)と連携させるとより柔軟にミュートができるかもしれません。