kumilog.net

データ分析やプログラミングの話などを書いています。

ワンライナーで自分がSlackにアップロードしたファイルのダウンロードと削除を行う

f:id:xkumiyu:20180330002943p:plain

シェルを使ってSlackにアップロードしたファイルのダウンロードしたり、削除したりします。ワンライナーとタイトルに書いたものの、若干無理やりです。また、ダウンロードと削除はまとめて1行ではなく、別々です。

準備

トークン作成

はじめにこちらのページからトークンを作成します。

jqのインストール

APIで得た値の処理にjqを使うので、インストールしておきます。Macの場合、brewでインストールできます。

$ brew install jq

Mac以外の場合は、インストールガイドを参考にしてインストールしてください。

ファイルのダウンロード

slack_userのところに自分のユーザ名、slack_tokenのところに先程作成したトークンを入れると、以下の1行で自分がアップロードしたファイルすべてを、カレントディレクトリにダウンロードすることができます。

標準出力は何も表示しないようにしているので、大量にファイルがあれば少し時間がかかるかもしれません。

$ slack_user=xxx; slack_token=xxx-xxx; user_id=$(curl -sS 'https://slack.com/api/users.list?token='$slack_token'' | jq -r '.members[] | select(.name == "'$slack_user'").id'); curl -sS 'https://slack.com/api/files.list?token='$slack_token'&user='$user_id'' | jq -r '.files[].url_private_download' | xargs -I{} curl -sS -O -H 'Authorization:Bearer '$slack_token'' {}

見にくいので、少し行を分けると以下のような感じになります。

slack_user=xxx
slack_token=xxx-xxx
user_id=$(curl -sS 'https://slack.com/api/users.list?token='$slack_token''\
  | jq -r '.members[] | select(.name == "'$slack_user'").id')
curl -sS 'https://slack.com/api/files.list?token='$slack_token'&user='$user_id''\
  | jq -r '.files[].url_private_download'\
  | xargs -I{} curl -sS -O -H 'Authorization:Bearer '$slack_token'' {}

大きく分けて以下の3ステップあるので、それぞれについて少し解説します。

  • ユーザIDの取得
  • ダウンロードするファイルのURLの取得
  • URLにアクセスして、ファイルのダウンロード

ユーザIDの取得

SlackのAPIで用いるuserはSlackで使う@xxxではなく、10文字くらいのランダムな英数字のユーザIDなので、まずはこのユーザIDを取得します。

直接ユーザIDは取得できないので、全ユーザのデータを取得してから、slack_userのユーザIDを抽出します。

全ユーザのデータは、users.listメソッドを使うとできます。メソッドのドキュメントのページにあるTesterを使うとブラウザ上で試すことができます。

curl 'https://slack.com/api/users.list?token='$slack_token''

結果はJSON形式で返ってくるので、jqを使ってユーザIDを抽出します。membersがkeyの配列の中から、name$slack_userと等しい要素のidを取り出します。

jq -r '.members[] | select(.name == "'$slack_user'").id'

抽出したユーザIDは変数に格納しておきます。まとめると以下のよう感じです。

user_id=$(curl -sS 'https://slack.com/api/users.list?token='$slack_token''\
  | jq -r '.members[] | select(.name == "'$slack_user'").id')

ダウンロードするファイルのURLの取得

次に、user_idがアップロードしたファイルがダウンロードできるURLを取得します。ダウンロードURLは、files.listメソッドを使うと取得できるファイルリストの中にあります。

user_idがアップロードしたファイルリストを取得します。

curl 'https://slack.com/api/files.list?token='$slack_token'&user='$user_id''

ダウンロードURLはurl_private_downloadなので、jqを使ってfilesがkeyの配列の各要素(各ファイル)から取り出します。

jq -r '.files[].url_private_download'

URLにアクセスして、ファイルのダウンロード

xargsコマンドでURLを受け取って、curlでダウンロードします。権限がないとアクセスできないので、トークンをヘッダーに入れてアクセスします。

xargs -I{} curl -O -H 'Authorization:Bearer '$slack_token'' {}

前のステップのダウンロードURLの取得と合わせると、

curl -sS 'https://slack.com/api/files.list?token='$slack_token'&user='$user_id''\
  | jq -r '.files[].url_private_download'\
  | xargs -I{} curl -sS -O -H 'Authorization:Bearer '$slack_token'' {}

と書けます。

ファイルの削除

ファイルの削除を同じように1行で書けます。

$ slack_user=xxx; slack_token=xxx-xxx; user_id=$(curl -sS 'https://slack.com/api/users.list?token='$slack_token'' | jq -r '.members[] | select(.name == "'$slack_user'").id'); curl -sS 'https://slack.com/api/files.list?token='$slack_token'&user='$user_id'&ts_to='$ts_to'' jq -r '.files[].id' xargs -I{} curl -sS -X POST 'https://slack.com/api/files.delete?token='$slack_token'&file={}'

行を分割すると

slack_user=xxx
slack_token=xxx-xxx
user_id=$(curl -sS 'https://slack.com/api/users.list?token='$slack_token''\
  | jq -r '.members[] | select(.name == "'$slack_user'").id')
curl -sS 'https://slack.com/api/files.list?token='$slack_token'&user='$user_id'' 
  | jq -r '.files[].id'\
  | xargs -I{} curl -sS -X POST 'https://slack.com/api/files.delete?token='$slack_token'&file={}'

となります。

見て分かるように、files.listメソッドを使うところまで全く同じです。

files.listメソッドの結果をjqurl_private_downloadを取り出すのではなく、ファイルのidを取り出しています。

jq -r '.files[].id

そのファイルIDとfiles.deleteメソッドを使って、ファイルを削除します。今までのAPIはGETでしたが、削除のAPIはPOSTになるので注意が必要です。

xargs -I{} curl -X POST 'https://slack.com/api/files.delete?token='$slack_token'&file={}'

取得するファイルリストにフィルタ

files.listメソッドを使って、ダウンロードするファイルリストや、削除するファイルリストを取得しましたが、全ファイルではなく、フィルタをかけることができます。

よく使うと思われるのが、作成された日時(ts_from/ts_to)やファイルの種類(types)でのフィルタです。

例えば、2018年3月30日より前にアップロードされた画像ファイルのリストは以下のようになります。

curl -sS 'https://slack.com/api/files.list?ts_to=1522335600&types=images&token='$slack_token'&user='$user_id'

ts_fromts_toはタイムスタンプなので、dateコマンド等で変換してください。

シェルスクリプトにしました

引数で指定できるようにしたりして、ダウンロードと削除を行うシェルスクリプトにしました。

github.com

使い方

※スクリプトは変更する場合があるので、READMEを優先してください。

$ ./cleaner.sh [-s] [-o] [-d] [-h] [-D day] user_name slack_token
  • -s: ファイルリストを表示する
  • -o: ダウンロードを行う
  • -d: 削除を行う
  • -D: 指定した日数より前に作成したファイルのみにフィルタ

s/o/dはオプションですが、どれか指定しないと何も実行されません。

30日より前にアップロードされたファイルすべてをダウンロードして削除する

$ ./cleaner.sh -od -D 30 xxx xxx-xxx

まとめ

SlackのAPIとjqを使ってアップロードしたファイルのダウンロードしたり、削除したりするシェルスクリプトを書いてみました。

自動的に削除するボットもあると思いますが、そんなに頻繁に使う必要がない場合は、今回のようなシェルスクリプトだと手軽に使うことができて良いのではないでしょうか?

参考