Slackのプライベートチャンネルのバックアップ

## 背景と目的
- 所属先のSlackワークスペース（自分は管理者ではない）にプライベートチャンネルをつくっていた。COVID-19支援で有料サービス相当のサービスを受けていたが、これが切れるため、容量制限で過去のメッセージが閲覧できなくなる。
- 自身が運営していたプライベートチャンネルのログを取りたい。
    - 管理者ではないのでエクスポートなどの機能は使いたくない。
    - 数千人が利用するワークスペースで、ボランティアの管理者に個別に対応してもらうのは難しいので、自力で何とかしたい。
- ファイルの共有はほとんどないので、メッセージのログだけでよい。

## 実現方法
- 下のQiitaの記事を参考に、自分のプライベートチャンネルのメッセージをGoogleスプレッドシートに書き出す。
    - [Slack の特定のチャンネルのメッセージ一覧をスプレッドシートにエクスポートするツールを作ってみた](https://qiita.com/tanabee/items/0d17d58ac6008329fdaa)
- ただし、Slackのレガシートークンの発行が2020年５月はじめに終了し、上記事が用いている  slack api も deprecate しているなど、そのままでは使えなかった（2020.8.4時点）ので、やっつけ仕事で改変して対応してみる。

- Slackのアプリやボットが何なのかも理解せずに、取り敢えず目的だけ達したやっつけ仕事です。

## やったこと

### Slack App をつくる
- slack api の [Your Apps](https://api.slack.com/apps)にアクセス。
- Create New App をクリックして新しい App を作成。
    - 作るといっても、実際にはトークンを獲得するだけで、コードはすべて GAS (Google Apps Script)で書く。
    - App Name はテキトー
    - Development Slack Workspace は、保存したいプライベートチャンネルがあるワークスペースを選択

### Slack App のスコープ
- 利用するのは `conversations.history` API。
- [Slackのリファレンス](https://api.slack.com/methods/conversations.history) に、必要なスコープが列挙されている。
    - bot  `channels:history`  `groups:history`  `im:history`  `mpim:history`
    - user  `channels:history`  `groups:history`  `im:history`  `mpim:history`
- これらを、Slack Appのページの OAuth & Permissions ページで設定する。
    - ページ中段の Scopes で、チマチマ足していけばいい。

### トークンの取得
- スコープを設定し終えたら、同じページの上の方 OAuth Tokens & Redirect URLs の Install App (２回目以降は Reinstall App)をクリックして、App をインストールする。
    - OAuth Access Token, Bot User OAuth Access Token の２つのトークンをメモっておく。他者に渡したり漏洩したりしないように厳重に注意すること。

### プライベートチャンネルのIDを取得
- Webブラウザ上でSlackのプライベートチャンネルにアクセスすると、以下のようなURLになっている。
    - `https://app.slack.com/client/T12345678/C9876543210`
    - このうち、最後のスラッシュ以下の `C9876543210` の部分がプライベートチャンネルのID
    - （参考）`T12345678` は、ワークスペースのIDらしい

- slack api のwebサイトでも [`conversations.list`](https://api.slack.com/methods/conversations.list) のテストから確認できる。（このAPIを使ってGASにやらせることもできるが、今回自分がバックアップしたチャンネルは２つだけなので、手動で取得した）
    - [`conversations.list`](https://api.slack.com/methods/conversations.list) が要求するスコープ（`channels:read`  `groups:read`  `im:read`  `mpim:read`）を追加して App を Reinstall
    - `conversations.list` の [Tester](https://api.slack.com/methods/conversations.list/test) ページで、以下を入力して、Test Methodをクリック
    - `token`  OAuth Access Token
    - `types`  private_channel
    - JSON形式で、自分がアクセスできるプライベートチャンネルのリストが返ってくる。その中の `id` が、チャンネル ID

### Googleスプレッドシートを準備
- [参考にしたQiitaの記事](https://qiita.com/tanabee/items/0d17d58ac6008329fdaa) の作者 @tanabee さんは、記事の内容を [GitHub のリポジトリ](https://github.com/tanabee/slack-channel-exporter) にまとめてくださっています。
    - リポジトリの [README](https://github.com/tanabee/slack-channel-exporter/blob/master/README.ja.md) にある通り、[Google スプレッドシート](https://docs.google.com/spreadsheets/d/1VclRGzDgpEKyFYHKzmdtyFaJrrBOG0EgDavxc9sZcxM/edit?usp=sharing)を開き、好きな場所にコピーする（ファイル＞コピーを作成）。
- コピーしたスプレッドシートを開く。

### スクリプトを編集
- スプレッドシートの ツール＞スクリプトエディタ から、スクリプトを開く。
- 以下のように書き換える（後半は @tanabee さんのコードをそのまま利用させていただいています）。

```JavaScript:main.gs
var OAuthAccessToken = "{OAuth Access Token}"; 
var channelID = "{チャンネルID}";

function main() {
  var fetchUrl = 'https://slack.com/api/conversations.history?token=' + OAuthAccessToken + '&channel=' + channelID + '&limit=1000';
  var res = UrlFetchApp.fetch(fetchUrl);
  res = JSON.parse(res);
  
  var messages = [];
  var latestMessage = '';
  do {
    var newMessages = res.messages
      .filter(function (v) {
        return !('thread_ts' in v) || v.ts === v.thread_ts;
      }).map(function (v) {
        return [
          v.client_msg_id,
          v.type,
          v.text,
          v.user,
          v.ts,
          v.reply_count || 0,
          v.reply_users_count || 0,
        ];
      });
    messages = messages.concat(newMessages);
    latestMessage = 'latest=' + res.messages[res.messages.length-1].ts;
  } while (res.has_more);

  SpreadsheetApp
    .getActiveSheet()
    .getRange('A2:G' + (messages.length+1))
    .setValues(messages);
}
```

### 実行
- mainを実行すれば、チャンネル内のメッセージがスプレッドシートに流し込まれる。