28
32

More than 5 years have passed since last update.

Slackの特定チャンネルで一定期間を過ぎた昔の投稿を定期的に削除する

Last updated at Posted at 2018-02-12

はじめに

勤務する会社ではSlackを利用しています。話題の分報を導入したところ、投稿されるメッセージ数が多くなり、フリープランの「10,000件制限」で過去の投稿が表示できなくなることが多くなりました。

「有効な投稿が流れちゃうので...、もう少し長期間表示されるようにできませんか?」

通知目的で利用しているチャンネル1には、無駄なメッセージが残っているね...。ということで、特定チャンネルに対し、ある程度昔の投稿を、自動的に削除するツールを作ってみることにしました。

方針

やりたいことは、次の通り。

  • 一定期間(とりあえず1週間)を過ぎた過去の投稿を定期的に削除する
  • 対象のチャンネルは指定したい(複数)

Excelライクでメンテナンスが容易、さらに定期実行するスクリプトも書けるので、Googleスプレッドシートを利用することにしました。

Googleスプレッドシート

まず、対象チャンネルですが、以下のフォーマットで指定することにしました(チャンネル名の頭の#は無しで)。

Channel.png

Google Apps Script

SlackAppをライブラリへ追加する

Slackを外部から制御するので、Slack APIを利用します。このSlack APIをGoogle Apps Scriptから簡単に呼び出すため、SlackAppライブラリ2を利用させていただきました。

基本情報にあるLibrary Keyを、[リソース]-[ライブラリ]内の[ライブラリを追加]へ入力して[追加]することで利用できるようになります。バージョンは22を使用しました。

Library.png

SlackのLegacy tokenを発行する

SlackAppを利用するのに必要なので、SlackのLegacy tokensのページでトークン(xoxp-xxxxxxxxxx-xxxxx...といった感じのやつ)を発行しておきます。

また、このトークンはスクリプト内で利用するので、[ファイル]-[プロジェクトのプロパティ]内の[スクリプトのプロパティ]へ、SLACK_API_TOKENとして追加しておきました。

Property.png

スクリプトを実装する

続いてスクリプトです。まず、スプレッドシートに記載されているチャンネル名を取得します。そして、トークンを渡して作成したSlackAppとともに、下位関数を呼び出します。

cleaner.gs
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');
  var slackApp = SlackApp.create(token);

  for each(var channelName in channelNames) {
    cleanChannel(slackApp, channelName);
  }
}

呼び出された下位関数では、「1週間前の投稿を取得(channelsHistory())→ 削除(chatDelete())」を、投稿が取得されなくなるまで繰り返します。

cleaner.gs
function cleanChannel(slackApp, channelName)
{
  var channelId = getChannelId(slackApp, channelName);
  if (channelId.length == 0) {
    return;
  }

  var date = new Date();
  date.setDate(date.getDate() - 7); // 1週間前
  var timestamp = Math.round(date.getTime() / 1000) + '.000000';

  do {
    var optParams = {
      latest: timestamp,
      count: 1
    };
    var result = slackApp.channelsHistory(channelId, optParams);
    if (result.ok) {
      for each(var message in result.messages) {
        slackApp.chatDelete(channelId, message.ts);
      }
    }
  } while (result.ok && result.has_more)
}

途中、チャンネル名からチャンネルIDを取得していますが、次のように実装しました。

cleaner.gs
function getChannelId(slackApp, channelName)
{
  var channelId = '';
  var result = slackApp.channelsList();
  if (result.ok) {
    for each(var channel in result.channels) {
      if (channel.name == channelName) {
        channelId = channel.id;
        break;
      }
    }
  }
  return channelId;
}

プロジェクトのトリガーを設定する

最後に、[編集]-[現在のプロジェクトのトリガー]から、上記のcleanChannels()を適当なタイミングで指定すれば終了です。とりあえず、1日4回実行するように設定しました。

Trigger.png

おわりに

なんとなくですが、以前と比べると、過去の投稿に対して「あ、まだ参照できた」と思うことが多くなったように思います。スタンダードプランへ移行するまでの中継ぎとして、多少は活用できそうだな、と思っています。


  1. 各プロジェクトごとのチャンネルを用意し、Jenkinsのビルド結果、Redmineのチケット更新、ソース管理へのコミットメッセージなど、業務中に把握しておきたい情報が通知されるようにしています 

  2. Slack APIのGoogle Apps Scriptラッパ 

28
32
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
32