GAS×Slack×スプレッドシートを用いたLT管理Bot作成

# はじめに
LT文化の定着・活性化を図ろうと、社内で使用しているSlackを連携させたLT管理用のBotを作成しました。
作成方法を自分の中での備忘録として記述していきます。

# 機能概要
スプレッドシートに発表者の名前やLTを行う日付、発表テーマを入力すると、当日の朝にSlackで全体に通知するというものを作成しました。

![スクリーンショット 2021-08-17 16.48.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/32bf9057-c4ce-d542-ce85-1fcde76b7cf9.png)


![スクリーンショット 2021-08-16 10.36.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/dbfda88b-feb1-6415-2afc-9ab0697bf749.png)


# Slackの設定

まず、SlackAPIの利用登録を行なっていきます。
①[Slack API](https://api.slack.com/apps)のページにアクセスして、「Create New App」ボタンから作成していきます。
![スクリーンショット 2021-08-16 8.46.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/15fa404c-9e74-fb77-527a-28f2e195ac4a.png)

②その後、アプリの設定をどのように構成するかの選択画面が表示されるので、今回は0から設定を行うので、
From scratchの方を選択します。
![スクリーンショット 2021-08-16 8.50.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/f54cebaa-7db5-48c7-3cc6-3799c69c959b.png)

③次にアプリ名とどのSlackのワークスペースに反映するかを選択できるので、入力していきます
（Select a Workspaceのセレクトボックスを押下すると、自分が所属しているslackのワークスペースを選択できます）
![スクリーンショット 2021-08-16 8.53.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/4c1779b3-b2bb-1004-549c-70555fa86041.png)

④続いて、作成したSlackアプリでできる権限を決めるスコープとパーミッション設定をします。
OAuth & Permissions画面から設定できます。
![スクリーンショット 2021-08-16 9.03.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/2fba0655-91a6-3451-1bbe-3457218a5d61.png)

⑤Scopesメニューの「Add an OAuth Scope」ボタンから、Botに必要な「chat:write」「chat:write.customize」「chat:write.public」を選択します。
「chat:write」：Botにチャットへの書き込み権限を与える
「chat:write.customize」：Botのアイコン画像や名前を書き換えられる
「chat:write.public」：パブリックチャンネルに許可なしで書き込める
![スクリーンショット 2021-08-16 9.05.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/8aede605-62b5-fa42-5224-045210361305.png)

⑥最後にSlackBotを作成して、導入したいSlackワークスペースにインストールしていきます。
「App Home」を選択し、「App Display Name」で「Edit」ボタンをクリックします。
![スクリーンショット 2021-08-16 9.14.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/1cc02811-5001-8a52-5551-5f22f784e940.png)

⑦Slackに表示するBotの名前とデフォルトのユーザー名を入力し、「Add」ボタンをクリックします
これでSlackBotの作成が完了します！
![スクリーンショット 2021-08-16 9.17.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/71f73d90-845d-337f-2eb6-30f7734b5358.png)

⑧Botが作成できたら、「Install App」を選択し、「Install to Workspace」ボタンをクリックし、Botをワークスペースにインストールします
![スクリーンショット 2021-08-16 9.19.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/83fc762f-61c5-ab1a-1212-2f6f20728014.png)

⑨Slackボットの権限リクエスト画面が表示されるので、実行内容を確認した上で、「許可する」ボタンをクリックします。
![スクリーンショット 2021-08-16 9.19.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/cb97ab0b-0e6f-089e-1e43-504a449d2d4b.png)

⑩最後にGoogle Apps Script(GAS)のスクリプトで利用する、Slack APIでボット用のトークンを取得します。
このトークンは後ほどGASのコードで使用するので控えておいてください！ここまでで、Slack上での設定は完了です。
![スクリーンショット 2021-08-16 9.20.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/81c14ed9-9f8b-9896-b245-cef5128f48a9.png)

# Google Apps Script(GAS)の設定

GASは、スプレッドシートのツール→スクリプトエディタから使用することができます。
![スクリーンショット 2021-08-16 10.03.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/8caabb10-7b17-3088-746c-1bb6358d1c41.png)

①開くと下記画面に遷移しますので、ここからSlack用のライブラリを導入していきます。
まず、「ライブラリ」の横にある+ボタンをクリックして、ライブラリを追加していきます。
![スクリーンショット 2021-08-16 10.05.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/cebd4b32-fb40-107e-86b0-fdd7110bacca.png)

②すると「ライブラリの追加」画面に遷移するので、下記のSlackAppスクリプトIDを入力していきます
SlackAppのスクリプトID：**1on93YOYfSmV92R5q59NpKmsyWIQD8qnoLYk-gkQBI92C58SPyA2x1-bq**
![スクリーンショット 2021-08-16 10.08.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/2d5f1149-2bd6-94d4-90c2-d6835d7063c2.png)

③検索ボタンをクリックすると、SlackAppのIDが出現するので、バージョンを最大にして、追加ボタンをクリックします。
![スクリーンショット 2021-08-16 10.08.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/07baea7e-6fb1-b0fd-868c-95a9b4a9d3eb.png)

④すると、ライブラリに「SlackApp」が出てくるので、これでライブラリの導入は完了です。
![スクリーンショット 2021-08-16 10.08.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/fd9c9381-be0d-a642-d50d-0f22e5d7c075.png)

# Slackのチャンネルに自動投稿するコード作成

ここからは、Slackのチャンネルに実際に投稿するための、コードを記述していきます。
まず全体的なコードを記述し、詳細部分について確認をしていきます

```javascript
///////////
// 定数定義
///////////

const SLACK_BOT_TOKEN = "Slack Apiトークン"
const SPREADSHEET_ID = "スプレッドシートのID"

function postSlackbot() {
  let token = SLACK_BOT_TOKEN;
  let slackApp = SlackApp.create(token);
  let channelId = "#投稿したいチャンネル名"
  let message = getMessage();
  slackApp.postMessage(channelId, message);
}

function isToday(today, dateObj) {
    return today.toString() == dateObj;
}

function getMessage() {
  const spreadsheet = SpreadsheetApp.openById(SPREADSHEET_ID);
  const sheet = spreadsheet.getSheets()[0];
  const range = sheet.getDataRange();
  const values = range.getValues(); 

  const date = new Date();
  const today = new Date(date.getFullYear(),date.getMonth(),date.getDate(),0,0,0);

  for (let i = 0; i < values.length; i++) { 
    if (values[i][1] && isToday(today, values[i][1])) {
      if (values[i][2] == "") {
        ltTime = "未定"
      } else {
        ltTime = values[i][2]
      }

      if (values[i][3] == "") {
        ltSpeaker = "だれか"
      } else {
        ltSpeaker = values[i][3]
      }

      if (values[i][4] == "") {
        ltTheme = "未定"
      } else {
        ltTheme = values[i][4]
      }
    
      let postInfo =
                  ":nice_lt: 本日開催予定のLT! :nice_lt:\n" +
                  "テーマ：" + ltTheme + "\n" + 
                  "登壇者：" + ltSpeaker + "さん\n" +
                  "時間　：" + ltTime + "\n" +
                  "\n" +
                  "たのしみですね\n" +
                  "\n" +
                  "次回LTを行う方はこちらから→（スプレッドシートのURL）"
      return postInfo;
    }
  }
}

```

まず以下の部分で定数を定義しておきます。Slack Apiのトークンは先ほど#Slackの設定⑩で取得したトークンを定数に代入します。
またスプレッドシートのIDは、LTに関する情報を入力するスプレッドシートのURLから取得できます。
https://docs.google.com/spreadsheets/d/スプレッドシートID/edit#gid=597941997
d/と/editの間にある文字列がIDとなるので、その部分を抜き取り、定数に代入します。

```javascript
const SLACK_BOT_TOKEN = "Slack Apiトークン"
const SPREADSHEET_ID = "スプレッドシートのID"
```



以下の部分では実際にSlackにスプレッドシートから取得した情報を通知するメソッドになります。
SlackAppのライブラリから`create`と`postMessage`というメソッドを使用しました。
https://script.google.com/macros/library/d/M3W5Ut3Q39AaIwLquryEPMwV62A3znfOO/22
https://github.com/soundTricker/SlackApp/blob/master/src/Code.coffee

`create`部分ではtokenを渡すと、API Clientを返しており、`postMessage`の部分で、チャンネルと投稿内容を渡してSlackに投稿するようなものになっています。



```javascript
function postSlackbot() {
  let token = SLACK_BOT_TOKEN;
  // ライブラリから導入したSlackAppを定義し、トークンを設定する
  let slackApp = SlackApp.create(token);
  let channelId = "#投稿したいチャンネル名"
  let message = getMessage();
  // SlackAppオブジェクトのpostMessageメソッドでボット投稿を行う
  slackApp.postMessage(channelId, message);
}
```


以下でスプレッドシートに入力されている情報を取得してきました。
詳細については、コードの中身にコメントアウトで記述しているので、ご覧ください


```javascript

// スプレッドシートに記載されている日付が処理の動く日と同じであれば、trueを返す
function isToday(today, dateObj) {
    return today.toString() == dateObj;
}

function getMessage() {
  const spreadsheet = SpreadsheetApp.openById(SPREADSHEET_ID);
  const sheet = spreadsheet.getSheets()[0]; // そのスプレッドシートにある最初のシートを取得
  const range = sheet.getDataRange();       // そのシート上の値が存在するセル範囲を取得
  const values = range.getValues();         // そのセル範囲にある値の多次元配列を取得

  const date = new Date();
  const today = new Date(date.getFullYear(),date.getMonth(),date.getDate(),0,0,0);

  for (let i = 0; i < values.length; i++) {  // 多次元配列の行の数だけループを回す
    if (values[i][1] && isToday(today, values[i][1])) {
      if (values[i][2] == "") {
        ltTime = "未定"
      } else {
        ltTime = values[i][2]
      }

      if (values[i][3] == "") {
        ltSpeaker = "だれか"
      } else {
        ltSpeaker = values[i][3]
      }

      if (values[i][4] == "") {
        ltTheme = "未定"
      } else {
        ltTheme = values[i][4]
      }
    
      let postInfo =
                  ":nice_lt: 本日開催予定のLT! :nice_lt:\n" +
                  "テーマ：" + ltTheme + "\n" + 
                  "登壇者：" + ltSpeaker + "さん\n" +
                  "時間　：" + ltTime + "\n" +
                  "\n" +
                  "たのしみですね\n" +
                  "\n" +
                  "次回LTを行う方はこちらから→（スプレッドシートのURL）"  //Botの投稿情報
      return postInfo;
    }
  }
}
```

これで、Slackへの通知を行うまでのコードは完成です！GASの上段部分にある、実行ボタンをクリックすると投稿ができますので、試してみてください。
最後にトリガーの設定（処理が動く時間を指定）をGAS上で行って完了です！！

# トリガーの設定

①GAS上のサイドバーに時計マークがあるので、クリックすると、トリガーの表示が出てきますので、クリックします。
![スクリーンショット 2021-08-17 8.30.08（3）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/01a9bcca-f3a2-0f03-a9fa-41f12f6a9165.png)

②右下部分にトリガーの追加ボタンがあるので、クリックします。
![スクリーンショット 2021-08-17 8.31.57（3）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/c76e1547-20e7-f73c-5a9d-4a8e11fa8f23.png)

③下記画像のような追加画面が出てきますので、入力していきます。今回のコードで言いますと、実行する関数は`postSlackbot`になるので、それを指定します。また、当日LTが開催予定の場合は朝のうちに通知してた方が良いと考え、私の場合は、毎日朝8時から9時の間で動くように設定をしました。時間ベースや週ベースで動かすこともできるみたいですので、試してみてください。
![スクリーンショット 2021-08-17 8.36.05（3）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872257/c74ceaa0-f66f-af13-6f59-ecc2f90f3061.png)

これで全ての作業が終了です！！

# 参考

https://auto-worker.com/blog/?p=2904
ご参考にさせていただきました。ありがとうございました。