【Slack】サクッとファイル一括削除するはずだったのに苦労した件【コードあり】【API】

Slack

こんにちは、panshokuです。

今回は、
なかなかに時間がかかってしまった

Slackでのファイル一括削除ツール(PHP)作成時の
エラー回避・コードなどをここに残します。


エラー回避とかいいから、サクッとコード教えてください
という方は、目次の「コード」より該当部分に飛んでください。




概要

下記の流れでファイルの削除をしていきます。

  • slack apiでアプリ作成・トークンを取得
  • 取得したトークンを含む、phpファイルを作成
  • phpファイルを実行して、ファイルを一括削除


前提 – 私の環境等

  • Windows
  • WSL2(Ubuntu)(Linux)
  • PHP 7.4.3


導入背景 – 無料プラン民なのでファイル削除したい

Slackを無料プランで使用していると、容量確保のためにファイルを削除しませんか?


私は、夫婦のコミュニケーションツールとしてSlackを使用しています。
以下の機能を頻繁に使うのですが、

  • メール自動転送
  • リマインダー(メッセージにあたるので、今回は削除対象外)

これらが結構容量を圧迫しているので、
普段から不要なファイルをこまめに削除していました。


ファイル一覧を開いて、1つ1つ削除・・・
私はこの地味~~~~~な作業が苦手です。


ファイルを一括削除できないかと調べてみると、
「このコードをコピペすればサクッと削除できます!」
みたいな記事が結構ありました。

「よし、これなら30分位で実装~削除までできそう!」
と思い、着手し始めたのですが・・・・・


エラーの嵐!!!!!!!!!!


30分でサクッと実装するはずが、
結局3時間くらい格闘していたような気がします・・・・泣


寄り道1 – 無料プランの制限について

無料プランの制限について、Slack 公式ページより抜粋しました。

今回はファイルの削除なので、メッセージ等は飛ばします。
※そのうち、メッセージもサクッと削除させます

ファイルの制限

ファイルストレージの上限は、ワークスペース全体で 5 GB です。

PDF、ドキュメント、画像、スクリーンショット、音声や動画ファイルなど、チャンネルやダイレクトメッセージにアップロードした内容はすべてこの上限に対して加算されます。
ワークスペースのストレージ上限に達しても、メンバーが引き続きファイルをアップロードすることはできますが、新しいファイルをアップロードできるように、古いファイルがアーカイブされます。

Slack

画像だけでなく、転送した「メール」や作成した「スニペット」も
ファイルの扱いになると思います。
※ファイル一覧に表示されるので

容量の確保

ファイルについて参考
ファイルを削除すると、使用容量からマイナスされるので、
削除することで、5GBに抑えることができます。

メッセージについて参考
メッセージを削除すると、カウントされた合計数からマイナスされるので、
10,000 件以内に収めておくことができます。


寄り道2 – 容量の確認方法

Slack公式に問い合わせしました。

無料プランの場合は、デスクトップアプリの左上のワークスペース名をクリックし、 設定と管理 > ワークスペースの設定 > アナリティクス とすすんだ先で使用済みファイルストレージ容量を確認いただく形になります。

Slack


使用済みファイルストレージの部分です。



手順

※遭遇したエラーについては、下方に記述しております。


1. slack api の Your app にアクセス

slack apiのページを開きます。


2. Create New App クリック

3. From scratch クリック

4. アプリの設定

  • App Name: 任意の文字列を入力 ※今回は、delete_filesにしました
  • Pick a workspace to develop your app in: 削除したいファイルのあるワークスペースを選択
  • Create App クリック

5. OAuth & Permissions を開く

6. Scopes で トークンを登録

OAuth & Permissions ページの下方にある、「Add an OAuth Scope」をクリック
「files:read」「files:weite」を検索して、クリック

7. install to Workspace から アプリをインストール

同ページの上方、緑のボタンをクリックしてインストールします ※画像はインストール後なので、Reinstallになっています

8. User OAuth Token をコピー

後で、phpファイルに記述するため使用します。

次からは、phpファイルにコードを書いていきます。



10. phpファイルを作成

私は下記の場所に tasksディレクトリを作成して、phpファイルを追加しました。

# wsl2内

# 現在地確認
$ pwd
/root

# tasksディレクトリ作成
$ mkdir tasks

# tasks内に移動
$ cd tasks
$ pwd
/root/tasks

# phpファイル作成
$ touch delete_slack_files.php

11. phpファイル編集

先程作成したdelete_slack_files.phpに、
この記事の下方にある「コード」部分をまるまるコピーして、貼り付けます。

12. User OAuth Token をdelete_slack_files.phpにペースト

delete_slack_files.php
★ 自分の User OAuth Token を記述 部分 ($token) に
先程コピーしたトークンを貼り付けます。

13. $channels 定数 を設定する

delete_slack_files.phpの定数部分にある$channelsには、
削除したいファイルがある、各チャンネルのIDを登録しておきます。

チャンネルのIDはブラウザでslackを起動して確認できます。

最後の部分(黄色)がチャンネルのIDです。
これをコピーして、例えば ‘xxxxx’ の部分に貼り付けます。

他のチャンネルも登録しておきたい場合は、$channel 配列の 2 以降に記述します。
※この 12 などを、この記事ではチャンネル番号と呼びます。

※phpファイルを実行するときに、削除したいチャンネル番号を指定

14. ファイル削除実行

※挙動がおかしい!と思ったら、 ctrl + cをすぐに押下してください。処理が終了します。


コマンドプロンプト(ターミナル)を起動して、
下記のコマンドを打ち込み、
エンターキーを押すと処理が実行されます。

※引数(10 1 2 の部分)は、ご自分にあわせて変更してください。
php delete_slack_files.php [削除したいファイルの件数] [削除対象のチャンネル番号] [削除したいファイルの種類番号]

# ファイルを作成したディレクトリに移動
$ cd /root/tasks

# 削除実行
# チャンネル番号1に投稿された、種類番号2(images)のファイルを、10件削除
$ php delete_slack_files.php 10 1 2

正しく削除できていたら、下記のように表示されます↓

....
F03D9GBQV50:【ココナラ通信 2022年4月号】直近のアップデート情報などのまとめ Delete!
F03DAAW3YJX:お役立ち資料情報」【bizocean】 Delete!
F03E0AH4MLY:参加費無料 第3弾!市場動向解説ウェビナー&交流イベントのご案内】 Delete!
10 files found.
delete 10 files.



コード

こちらをコピペして、トークンとチャンネル部分を修正してください。

<?php
/* ********************************************
* 引数
* - 第1引数: int : 削除したい件数
* - 第2引数: int : 削除対象のチャンネル番号($channels参照)
* - 第3引数: int : 削除したいファイルの種類番号($types参照)
*
* 実行コマンド例
* php delete_slack_files.php 10 1 1
******************************************** */


/* 定数 ************************************ */
$channels = [
  1 => 'xxxxx', // slackbot ------ 自分のものに変更が必要 ★
  2 => 'aaaaa', // 今日の献立チャンネル ------ 必要であれば増やす
  3 => '', //
  4 => '', //
  5 => '', //
  6 => '', //
  7 => '', //
  8 => '', //
  9 => '', //
  10 => '', //
];

// https://api.slack.com/methods/files.list#file_types
$types = [
  0 => 'all', // すべて
  1 => 'email', // メール
  2 => 'images', // Image files
  3 => 'spaces', // Posts
  4 => 'snippets', // Snippets
  5 => 'gdocs', // Google docs
  6 => 'pdfs', // PDF
  7 => 'zips', // Zip files
];
/* ****************************************** */


/* 引数 ************************************ */
$count = $argv[1];
$channel_number = $argv[2];
$type_number = $argv[3];
/* ****************************************** */


/* ファイルを検索・取得 ******************** */
$token ='xxxx-xxxxx-xxxx-xxxxxx'; // ------ ★ 自分の User OAuth Token を記述
$channel = $channels[$channel_number];
$type = $types[$type_number];

$headers = [
  'Authorization: Bearer '. $token,
  'Content-Type: application/json;charset=utf-8'
];

$op ="&count=$count" . "&channel=$channel" . "&types=$type";
$url = "https://slack.com/api/files.list?".$op;

$curl = curl_init();

// 実行設定
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

// 実行
$response = curl_exec($curl);

$result = json_decode($response, true);

$n = $result['paging']['total'];

// 実行終了
curl_close($curl);
/* ****************************************** */


/* ファイルの削除 ************************ */
$files = $result['files'];

$json_data = array('file' => 'XXX');
$i = 0;
foreach ($files as $file) {
  echo $file['id'].":".$file['name'];
  $json_data['file'] = $file['id'];
  $data = json_encode($json_data);
  $ret = postFromHTTP('https://slack.com/api/files.delete',$data,$token);

  // ターミナルに実行結果を表示
  if($ret['ok']){ echo ' Delete!';}
  else { echo ' ERROR.';}
  echo "\n";
  $i++;
}

// ターミナルに実行結果を表示
echo "$n files found.\n";
echo "delete $i files.\n";

// POSTメソッド
function postFromHTTP($url1, $data, $token) {
  $options = array(
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_AUTOREFERER => true,
  );
  $authorization = "Authorization: Bearer ".$token;
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url1);
  curl_setopt($ch, CURLOPT_HTTPHEADER,
  array('Content-Type: application/json; charset=utf-8' , $authorization ));
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  curl_setopt($ch, CURLOPT_VERBOSE, false);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt_array($ch, $options);
  $result = curl_exec($ch);
  curl_close($ch);
  $ret = json_decode($result, true);
  return $ret;
}
/* ****************************************** */
?>




エラー回避一覧

実装途中で遭遇したエラーをおいておきます。

PHP Fatal error: Uncaught Error: Call to undefined function curl_init()

エラー

$ php delete_slack_files.php 100 1 1
PHP Fatal error:  Uncaught Error: Call to undefined function curl_init()

ファイル一括削除phpファイルを実行したら失敗しました。
curl_init() が見つからないらしい。

対応

PHP cURL拡張モジュール(php-curl)をインストールします。

# apt-get使ってインストール
$ sudo apt-get install php-curl

# インストールされたか確認
# [installed] or [インストール済] と表示されていたらOK
$ apt list php-curl
php-curl/focal,now 2:7.4+75 all [installed] 

Temporary failure resolving ‘archive.ubuntu.com’

エラー

$ sudo apt-get install php-curl
...
W: Failed to fetch
   ...
   Temporary failure resolving 'archive.ubuntu.com'
...

apt-getを叩くと、ubuntu.com系が解決できず、失敗します。

対応

名前解決をします。
具体的には、/etc/resolv.confの値を下記に書き換える。

nameserver 8.8.8.8

ただこれだけだと、WSLを再起動するたびに、初期化されてしまうので、
以下の手順で名前解決します。

1./etc/wsl.confを編集

下記を記述して保存。

[automount]
enabled = true
root = /mnt/
options = ""
mountFsTab = true

[network]
generateHosts = true
generateResolvConf = false # 大事: resolv.conf(のリンク先)が生成されなくなる設定

[interop]
enabled = true
appendWindowsPath = true

2.PC再起動

PCを再起動します。

3.シンボリック解除

もし、シンボリックリンク( -> )が設定されている場合、解除します。

シンボリック確認

$ ls -l /etc/resolv.conf
lrwxrwxrwx 1 root root 29 Sep 11  2021 /etc/resolv.conf -> ../run/resolvconf/resolv.conf
$ sudo unlink /etc/resolv.conf

# うまくいかなければ、rmしてファイルを削除
$ sudo rm /etc/resolv.conf

4.名前解決

$ sudo sh -c "echo 'nameserver 8.8.8.8' > /etc/resolv.conf"

以上!

使えなかったコマンド

名前解決で記事を調べると、PSやnslookupなどが出てきますが
インストールしてないのか、使えませんでした。
インストールするの面倒なので、これらは使わずに、上記のやり方で行いました!

$ PS C:\Users\username> ipconfig.exe /all
PS: command not found

$ nslookup C:\Users\username> ipconfig.exe /all
nslookup: couldn't get address for '/all': not found

$ ipconfig  /all
Command 'ipconfig' not found

参考サイト

コメント