Google Apps Script (GAS)を使ってSlackの一定期間経過した投稿を自動削除のメモ

##前置き
「Google Apps Script（通称GAS？）を使ってSlackの一定期間より古い投稿を削除する」
調べると色々な記事が出てくるから楽勝だろうと取り掛かったものの、情報が古かったり、環境が違ったり、そのまま使えるものは見つからず思わぬ苦戦をする事になりました。それでも一応目的とする動作はできたのでメモとして残しておきます。

ちなみに当方GASを触るのが初めての素人です。手元では確かに動いていますが、中身は未だによく分かっていません。あしからず。。。

さて「そのまま使えるものは見つかりませんでした」とは書きましたが、そんな状況の中でも超参考にさせてもらったのが **「[簡単にSlackの一定期間経過した投稿を自動で削除する方法](https://tech.naturalmindo.com/notwork_slackapi/)」** と、サブで **「[[GAS][Slack]定期的に投稿するbotを作成](https://note.com/kawamura_/n/nede5b0f71353)」** です。先人の方々には本当に感謝しかねぇ・・・

ぶっちゃけ、一つ目のほぼ写経です。
とはいえ、最初に書いた通りそのままでは私の環境では動かなかったので、二つ目等を参考に調整しましています。

##さっそくですがコード全文
GASに記述するコード自体はここに全文書いてありますが、これを書いただけでは全然動きません。
前述の **[簡単にSlackの一定期間経過した投稿を自動で削除する方法](https://tech.naturalmindo.com/notwork_slackapi/)** とか参考に Slack API トークンの発行とか済ませた上でという事で。。。すいません、ひとつよろしくお願いします。

※トークンはオプションに書き込む方法を使っています
※トークンがBotだと上手く消えなかったのでUserを使いました（意味の分からない人は [前述の参照先](https://tech.naturalmindo.com/notwork_slackapi/) にて←）
※日数を前に持ってきたのは趣味
※削除が成功してるかのログ部分も少し変更してますが、それも趣味

```
//変数
var days = 14 // 2週間前

//mainコード
function cleanChannels()
{
  var sheet = SpreadsheetApp.getActiveSheet();
  var values = sheet.getDataRange().getValues();

  var channelNames = [];
  for (var i = 1; i < values.length; ++i) {
    channelNames.push(values[i][0]);
  }

  var token = PropertiesService.getScriptProperties().getProperty('SLACK_API_TOKEN');
  
  for (var index in channelNames) {
    var channelName = channelNames[index];
    cleanChannel(token, channelName);
  }
}

//チャンネル内投稿削除
function cleanChannel(token, channelName)
{
  var channelId = getChannelId(token, channelName);
  if (channelId.length == 0) {
    return;
  }

  var date = new Date();
  date.setDate(date.getDate() - days);
  var timestamp = Math.round(date.getTime() / 1000) + '.000000';

  do {
    var result = getChannelHistory(token, channelId, timestamp);
    if (result.ok) {
      for (var index in result.messages) {
        var message = result.messages[index];
        deleteChat(token, channelId, message.ts);
      }
    }
  } while (result.ok && result.has_more && count < limit)
}

//チャンネル名->チャンネルID取得
function getChannelId(token, channelName)
{
  var channelId = '';
  var result = getChannelList(token);
  if (result.ok) {
    for (var index in result.channels) {
      var channel = result.channels[index];
      if (channel.name == channelName) {
        channelId = channel.id;
        Logger.log("\"#%s\" Channel ID = \"%s\"", (channel.name), channelId);
        break;
      }
    }
  }
  return channelId;
}

//チャンネル一覧取得
function getChannelList(token)
{
  var url = 'https://slack.com/api/conversations.list';
  var options = {
   "method": "get",
   "contentType": "application/x-www-form-urlencoded",
   "payload": {
     "token": token,
   }
  };
  var response = UrlFetchApp.fetch(url, options);
  //Logger.log("getChannelList response = [%s]",response);
  return JSON.parse(response);
}

//チャンネル内投稿取得
function getChannelHistory(token, channelId, timestamp)
{
  var latest = timestamp;
  var url = 'https://slack.com/api/conversations.history'
  var options = {
   "method": "get",
   "contentType": "application/x-www-form-urlencoded",
   "payload": {
     "token": token,
     "channel" : channelId,
     "inclusive" : true,
     "latest" : latest
   }
  };
  var response = UrlFetchApp.fetch(url, options)
  return JSON.parse(response)
}

// 投稿削除
function deleteChat(token, channelId, timestamp)
{
  var url = 'https://slack.com/api/chat.delete'
  var options = {
   "method": "post",
   "contentType": "application/x-www-form-urlencoded",
   "payload": {
     "token": token,
     "channel" : channelId,
     "ts" : timestamp
   }
  };
  var response = UrlFetchApp.fetch(url, options)
  Logger.log("----- deleteChat -----\n%s", response);
  return JSON.parse(response)
}
```
という訳で全文はこんな感じです。
本人もちゃんと理解はできていませんが、もう少しだけ変更点を具体的に書いておきます。
##調整した部分について（ここ変えたら上手く動いた）
３箇所の・・・

```
//チャンネル一覧取得
function getChannelList(token) {
  var url = 'https://slack.com/api/conversations.list' +
            '?token=' + token;
  var response = UrlFetchApp.fetch(url)
  return JSON.parse(response)
}
```
↑こういった感じの部分を・・・
↓こう！

```
//チャンネル一覧取得
function getChannelList(token)
{
  var url = 'https://slack.com/api/conversations.list';
  var options = {
   "method": "get",
   "contentType": "application/x-www-form-urlencoded",
   "payload": {
     "token": token,
   }
  };
  var response = UrlFetchApp.fetch(url, options);
  return JSON.parse(response);
}
```  
一応書いておくと、optionの内容はそれぞれ違うので注意です。
##雑なまとめ
(そもそも私がミスってるだけの可能性もまだ全然あるけど)urlに直接記述する方法が上手くいかなかったって事なのかしら？
結果として、元のコードでurlに直接オプション（？）を書き込んでた３箇所を「option」の形に修正したら動いたって感じです。

↓これが今回のキモ

```
var url = 'https://～～～';
var options = {
  ～～～
}
var response = UrlFetchApp.fetch(url, options);
```

optionに何を書けばいいかは
https://api.slack.com/methods/conversations.list
https://api.slack.com/methods/conversations.history
https://api.slack.com/methods/chat.delete
とかそれぞれの「Reference docs」ページの **Facts** やら **Arguments** を見ると何となく分かるような気がしたりしなかったり。