【GAS】Slackのメッセージの履歴をスプレッドシートに書き出す



## 目的
Slackのメッセージの履歴をスプレッドシートに書き出すGoogleAppScriptです。
90日分だけもSlackのメッセージを書き出したいため作成しました。
GASの時間が6分を超えるほどメッセージが多い場合はタイムアウトするため取り出せません。
スレッドや90日より前のメッセージは取り出せません。



###  全体の流れ



1．SlackとGASを連携するためSlack API Token を作成します。

2．SkackアプリのAPI連携で必要なスコープを設定します。
※今回Slackのユーザー一覧取得のGASと
　Skaclのメッセージの履歴取得のGASのスコープ（権限）となります。

3．SlackをGASで利用できるよう許可します。

4．トークンを取得します。
※1～4までは下記の手順をご参照ください。
https://qiita.com/80syokumotsu/items/041e99e99d8ecaa3c42b

5．SlackのチャンネルIDを取得します。
PCでSlackアプリを開き希望のチャンネルを選択します。
右上のチャンネル名をクリックし画面をスクロールしてチャンネルIDを取得します。
![slackチャンネルID取得.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/436175b0-8e4b-3ca6-2e2d-eb2f6ff0ff07.png)





6．スプレッドシートを作成します。
Googleドライブ ⇒ 新規 ⇒ Googleスプレッドシート ⇒ 空白のスプレッドシート
![新規Googleスプレットシート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/5c72d2bc-bb18-b59d-3c7b-2991db5a8e73.png)


7．シートを追加し、シート名を小文字で「slack」にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/c24c06cd-5428-43dc-8765-9d05e798b8a8.png)


8．GAS（GoogleAppScript)を作成するため
slackシートを開き　右上の「拡張機能」⇒「App Script」の順にクリックします。
![AppScript立ち上げ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/104c73aa-de2c-9c37-3ea8-5a2f036b83e2.png)

9．Tokenを登録するGASを作成します。
ファイル右横の＋　⇒スクリプト　を選択
コードを追加し保存する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/0e47bdbc-d983-ecff-996f-f4a733b9a6da.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/f009a004-84c4-82fe-aadb-dcb974c4d6ef.png)


```token.js
function SetScriptProperty() {
  PropertiesService.getScriptProperties().setProperty('slack_token', 'ここにAPIトークンを入力してください');
 
}

```

10．slackのユーザー一覧を取得するGASを作成します。
ファイル右横の＋　⇒スクリプト　を選択

11． 下記のコードを記入します。
```slack_id_get.js
const slack_app_token = PropertiesService.getScriptProperties().getProperty("slack_token");
function getSlackUser() {
  const options = {
    "method" : "get",
    "contentType": "application/x-www-form-urlencoded",
    "payload" : {
      "token": slack_app_token
    }
  };
  const url = "https://slack.com/api/users.list";
  const response = UrlFetchApp.fetch(url, options);
  const members = JSON.parse(response).members;
  let arr = [];
  for (const member of members) {
    //削除済、botユーザー、Slackbotを除く
    if (!member.deleted && !member.is_bot && member.id !== "USLACKBOT") {

      let member_id = member.id;
      let chid = getChannelID_(member_id);
      let dispname = member.profile.display_name; //表示名
      let real_name = member.real_name; //氏名(※表示名ではない)
      console.log(dispname);
      arr.push([member_id,chid,dispname,real_name]);
    }
    //let channelID = getChannelID_(id);
  }
  //スプレッドシートに書き込み
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('slack');

  sheet.getRange(1,1,1,1).setValue("Member_ID");
  sheet.getRange(1,2,1,1).setValue("Channel_ID");
  sheet.getRange(1,3,1,1).setValue("表示名");
  sheet.getRange(1,4,1,1).setValue("氏名");

  sheet.getRange(2, 1, sheet.getMaxRows()-1, 2).clearContent();
  sheet.getRange(2, 1, arr.length, arr[0].length).setValues(arr);
}

function getChannelID_(member_id) {
  const options = {
    "method" : "post",
    "contentType": "application/x-www-form-urlencoded",
    "payload" : {
      "token": slack_app_token,
      "users": member_id
    }
  }
  //必要scope = im:write
  const url = 'https://slack.com/api/conversations.open';
  const response = UrlFetchApp.fetch(url, options);
  const obj = JSON.parse(response);
  console.log(obj);
  return obj.channel.id;
}
```

12．slackシートにユーザー一覧が追加されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/cb4822ba-fa9b-93b1-8a3b-c1aebfce35f1.png)


13．シート1 を開き、A1のセルに手順5 で取得したチャンネルIDを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/47454a70-050b-7664-cbee-449010f0f686.png)

14．スプレッドシートの「sheet1」にSlackのメッセージを取得するGASを作成します。
ファイル右横の＋　⇒スクリプト　を選択

15． 下記のコードを記入し実行します。
```SlackGetMessage.js

const slack_token = PropertiesService.getScriptProperties().getProperty("slack_token");

const sheet = SpreadsheetApp.getActiveSheet();
var channelID = sheet.getRange("A1").getValue();
Logger.log(channelID);

function SlackGetMessage() {
  var fetchUrl = 'https://slack.com/api/conversations.history?' + 'channel=' + channelID + '&limit=1000';
  const options = {
	"headers": { 'Authorization': 'Bearer ' + slack_token }
  };
  var res = UrlFetchApp.fetch(fetchUrl,options);
  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.reverse());

  //E 列　Linux時間を日本時間に変更
  var n =2; //
  for (var i=0; i<  messages.length; i++) {
    var date = messages[i][4];
    date = new Date(date * 1000);
    date =Utilities.formatDate(date, 'Asia/Tokyo', 'yyyy/MM/dd/ HH:mm:ss');
    Logger.log(date);
    sheet.getRange(n, 5).setValue(date);
    n=n+1;

  }

    
}
```

17．Slackメッセージの履歴が「sheet1」に書き出されます

18．Slackメッセージのやり取りのユーザー名がIDでだれか分からないので、VlookUpなどでsheet1とSlackシートのユーザー名を紐づけます。

19．シート名を任意の名前に変更します。

別のチャンネルのメッセージを取得したい場合はシートを追加しA1 にSlack チャンネルIDを入力して　手順　15 のGASを実行してください


## 関連記事

[Slack の特定のチャンネルのメッセージ一覧をスプレッドシートにエクスポートするツールを作ってみた](https://qiita.com/tanabee/items/0d17d58ac6008329fdaa)