LoginSignup
10
6

More than 1 year has passed since last update.

Slackのバックアップ取得ツールを作ってみた

Last updated at Posted at 2022-08-25

2022/9/1からslackのフリープランの変更があります。
そこでslack-apiを使って90日より過去の投稿のバックアップを取得するツールを、Node.jsで作ってみました。

なお、公開チャンネルであれば公式のエクスポート機能があります。

バックアップの対象にするのは以下になります。

  • 公開チャンネル・非公開チャンネルへの投稿
  • リプライ
  • 添付ファイル

※DMのバックアップは行っていません。

作成したもののソースはこちらになります。
slackチャンネルの使い方によっては生成されるバックアップのファイルサイズが膨大なものになったりするかもしれません。ツールの実行は自己責任でお願いします。

環境情報

  • Node.js 16
  • slack/web-api 6.7.2

トークンの取得

こちらの記事を参考にトークンを取得します。今回作るツールに必要になるPermissionsのScopeは、

  • channels:history
  • groups:history
  • im:history
  • mpim:history
  • files:read
  • channels:read
  • groups:read
  • mpim:read
  • im:read

これらになります。

チャンネル一覧の取得

conversations.listを叩きます。公開チャンネル、非公開チャンネルの両方を取るようにします。

const list = await client.conversations.list({
  cursor: cursor,
  types: "public_channel,private_channel",
});

デフォルトでは100件分が取得できます。cursorの初期値はnullで、このAPIの応答に含まれるnext_cursorを与えることで続きの100件が取得できます。

※このAPIで取得できるチャンネルはトークンを発行したユーザーの閲覧範囲に限られます。

チャンネルの履歴の取得

conversations.historyを叩きます。

const history = await client.conversations
  .history({
    cursor: cursor,
    channel: channelID,
    limit: HISTORY_LIMIT,
  })

cursorはチャンネル一覧と同様の振る舞いをします。channelにはチャンネルのIDを指定します。こちらもデフォルトで100件分の履歴が取得できますが、一度でより多くの履歴を取れるようlimitを指定します(最大1000件まで指定できるようです)。

リプライの取得

以前のAPIではチャンネル履歴の取得で合わせてリプライまで取れていたんですが、今のAPIではリプライが取得できません。
なのであるメッセージの持つreply_countが1以上であれば、conversations.repliesを叩いてリプライを取得します。

const replies = await client.conversations
  .replies({
    channel: channelID,
    ts: message.ts,
  })

こちらを叩くことでmessageに紐づくリプライが全て取得されます。

添付ファイルの取得

メッセージに紐づく添付ファイルを取得します。ただしこちらはAPIは提供されていないので、HTTPリクエストを送る必要があります。リクエストするURLはチャンネル履歴やリプライの応答の、files.url_private_downloadになります。
中にはfilesが無いメッセージやurl_private_downloadが無い添付ファイル情報も含まれているので、そこは条件を書きます。url_private_downloadが無い場合は外部ファイルの埋め込みだったりするので、JSON自体を保存してしまえば良いでしょう。
url_private_downloadをリクエストするには、Bearerトークンで認証する必要があります。

  headers: {
    "Content-Type": "application/json",
    Authorization: "Bearer " + TOKEN,
  },

TOKENに指定するトークンは、APIで利用しているものと同じで問題ありません。

ストレージに保存

ダウンロードしたファイルはストレージに保存します。メッセージと対応付けられるようにmessage.tsをディレクトリ名にします。また、添付ファイルは同名のファイルが複数添付されている場合があるので、files.idでディレクトリをさらに掘るか、ファイル名に付与するかする必要があります。

メッセージをJSONファイルとして保存

取得してきたメッセージを一つのArrayに統合し、JSON.stringfyでJSON化してストレージに保存します。
一つのチャンネルのメッセージ全てを一つのJSONにしてしまうと、超巨大なJSONファイルとなってしまう可能性があるので、適度に小分けして保存するのが良いでしょう。

zip化

archiverを使ってストレージに保存したJSON、添付ファイルを一つのzipファイルにします。

まとめ

以上がslackのapiを使ったバックアップの取り方でした。大体10000件の投稿があるチャンネルに対して実行すると、約15分かかって約1GBのバックアップが作成されました。ファイルサイズはチャンネルの添付ファイル量が大きく影響すると思います。

10
6
0

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
10
6