【ハンズオン】Slack AppとGASでSlackチャンネル投稿内容をスプレッドシートに記述する

# はじめに
最近の社内のチャットツールとしてSlackがよく使われていると思います。Slackには便利なデフォルト機能に加え、さまざまなアプリや拡張機能が用意されています。

今回は、SlackアプリとGoogle Apps Script (GAS) を活用し、特定のチャンネルに投稿された内容を自動的にGoogleスプレッドシートに記録するシステムを構築するハンズオンを行います。

今回のハンズオンを体験すれば、単に投稿内容を記録するだけでなく、さまざまな応用ができると思います。

# Slackアプリ作成手順

## 1. Slack APIページでアプリ作成

### 1. Slack APIページにアクセスします。  
   URL: [https://api.slack.com/](https://api.slack.com/)
   
### 2. Create an Appボタンをクリックして、新しいアプリを作成します。
![スクリーンショット 2024-09-19 2.29.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3739285/d80774bf-c7db-20f4-5ed2-70e110556b9e.png)


### 3. From scratchを選択します
![スクリーンショット 2024-09-19 2.29.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3739285/e3c8b3ab-5d28-92cd-0b41-eade49de734b.png)


### 4. アプリ名とワークスペースを指定します。
![スクリーンショット 2024-09-19 2.30.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3739285/862ef9b6-3a00-8f97-1107-1519fc4456f5.png)

## 2. Appの設定
### 1. 作成したアプリのダッシュボードに移動し、 OAuth & Permissionsをクリックします。
![hide.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3739285/b5886673-7b43-0959-31d5-5c251662897a.png)



### 2. Scopes セクションで必要な権限を選択します（下記一例）
   - `chat:write`：メッセージを送信するための権限
   - `channels:read`：チャンネルの情報を取得するための権限
   - `groups:read`：プライベートチャンネルの情報を取得するための権限
   - `channels:join`：チャンネルに参加するための権限（必要な場合）
![スクリーンショット 2024-09-19 23.51.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3739285/1c3bccc9-fb46-e9f9-0b87-00ec81184bd3.png)
今回は

   - `channels:history`：パブリックチャンネル内の過去のメッセージを読み取る権限
   を設定しました。
[Scope権限一覧](https://api.slack.com/scopes)

### 3. App HomeからDisplay Nameを設定
※これを設定しないとワークスペースにインストールすることができません
![スクリーンショット 2024-09-19 23.53.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3739285/057ddd1b-d79c-0c97-6012-76f44eb6e6b1.png)

## 3. Appのインストール
### 1. Install Appセクションに移動し、Install to Workspaceボタンをクリックします。
![スクリーンショット 2024-09-19 10.32.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3739285/5abccaf4-5738-9410-13ed-df7830af52ba.png)

:::note warn
Scopeを変更すると再度ワークスペースにインストールしないといけません
:::

### 2. チャンネルにアプリをインストールする
追加したいチャンネルに移動し、**上部の太文字のチャンネル名**をクリックするとモーダルが開く、その中で**インテグレーション**というタブがあるので開く。
アプリを追加するというボタンがあるのでそこから先ほどワークスペースに追加したアプリを追加する
![スクリーンショット 2024-09-20 0.02.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3739285/e5368ced-257b-b0f3-a28e-1e6c3cd14744.png)



ここまでできたら、slackでの設定は終了です。次はGASの設定に移りましょう

## 4. GAS (Google Apps Script) の設定
### 1. スプレッドシートにアクセスしてApps Scriptを開く

1. 対象の**スプレッドシート**を開きます
2. **拡張機能**メニューをクリックし、**App Script**を選択してGoogle Apps Scriptのエディターを開きます。

### 2. プロジェクトの設定から環境変数を設定する（何をGASでしたいのかで変わるので必要な環境変数を確認してください）
**環境変数**に以下の情報を設定します
![スクリーンショット 2024-09-20 0.10.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3739285/c4867da4-7161-91f0-c0ad-f7003b905118.png)

- `CHANNEL_ID`：Slackのアプリを追加したチャンネルのチャンネルID
![スクリーンショット 2024-09-20 0.13.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3739285/8ced7bef-3064-0358-9949-0f28bad0bda6.png)



- `SHEET_NAME`：シートの名前　今回の場合だと`sheet`
![スクリーンショット 2024-09-20 0.15.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3739285/db699981-da6c-a292-15d7-5640f09d6a0b.png)


- `SLACK_API_TOKEN`：作成したアプリのToken
![スクリーンショット 2024-09-20 0.18.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3739285/c999be96-3b19-94fc-ebe5-37264952610b.png)



- `SPREADSHEET_ID`：スプレッドシートのID　URLのd/と/edit の間の英数字の羅列です
![スクリーンショット 2024-09-20 0.20.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3739285/020f10ee-17a3-9105-10c8-a5f63115aee0.png)

### 3. エディタの方でコードを記述する（下記は一例です）
```js
// Slackからのメッセージ取得
function fetchSlackMessages() {
  const url = "https://slack.com/api/conversations.history";
  const options = {
    method: "get",
    headers: {
      Authorization: "Bearer " + PropertiesService.getScriptProperties().getProperty("SLACK_API_TOKEN"),
    },
    muteHttpExceptions: true,
  };

  const channelId = PropertiesService.getScriptProperties().getProperty("CHANNEL_ID");
  const response = UrlFetchApp.fetch(`${url}?channel=${channelId}`, options);
  const data = JSON.parse(response.getContentText());

  if (!data.ok) {
    throw new Error("Slack API call failed: " + data.error);
  }

  return data.messages;
}

// メッセージをスプレッドシートに書き込む
function logMessagesToSheet() {
  const sheet = SpreadsheetApp.openById(PropertiesService.getScriptProperties().getProperty("SPREADSHEET_ID"))
                              .getSheetByName(PropertiesService.getScriptProperties().getProperty("SHEET_NAME"));
  const messages = fetchSlackMessages();

  messages.forEach(message => {
    sheet.appendRow([new Date(), message.user, message.text]);
  });
}

// トリガー設定
function setTrigger() {
  ScriptApp.newTrigger("logMessagesToSheet")
           .timeBased()
           .everyMinutes(10)
           .create();
}

```

### 4. デプロイ
![スクリーンショット 2024-09-20 0.27.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3739285/dd32f003-a268-cffb-e2b2-7df3510c5e6e.png)
コードが完成したら、デプロイします
アクセスできるユーザーは**全員**や**自分のみ**が選択できるのですが、どちらでも大丈夫です。
自分のみの方がセキュリティ上は安全です。

これで完成です。あとはslackで投稿されれば自動で書き込みをしてくれます。

# まとめ
結構簡単に作ることできるね