Google Driveのフォルダを監視し、画像以外が配置されたらChatworkに通知する


はじめに

Googleドライブのフォルダを複数人で共有し、「画像専用置き場」にしたい!それ以外のファイルが置かれたら検知したい!という需要が出てきました。

ですがGoogleドライブのフォルダは拡張子制限のような機能は無いですし(無いですよね…?)、人が目視でチェックするのは精度・頻度としては厳しいものがあります。

そこで、画像以外のファイルが配置されたらChatworkで通知するGASのスクリプトを作ってみました。

完成イメージ

画像置き場があり、「hoge.txt」のようなMimeTypeが画像以外のファイルが置かれた時に

こんな感じに通知してみましょう。

画像置き場のフォルダの作成

まずは画像置き場を作ります。
Googleドライブで新規→フォルダを選び、そこに画像を置きます。

GASファイルの作成

監視用のGASファイルを作成します。
今回はスプレッドシート不要なので、「Container Bound Script」ではなく「Standalone Script」(GAS単独のファイル)で作成しましょう。

Googleドライブで新規→その他→Google Apps Scriptを選びます。
選択肢にGoogle Apps Scriptが無い場合は、その他→アプリを追加からGoogle Apps Scriptを選んで追加します。

画像置き場のフォルダとは別の場所に保存してください。
同じフォルダだと、このファイル自体が「画像ファイル以外」と認識されてしまいますし、フォルダを共有したユーザーに編集・削除されてしまうリスクも伴う為です。

seachFiles.gs

var roomId = 'YOUR_ROOM_ID'; // chatworkの部屋ID
var token = 'YOUR_TOKEN'; // chatworkのAPIトークン

function myFunction() {
  var folderId = 'YOUR_FOLDER_ID';
  var folder = DriveApp.getFolderById(folderId);
  var files = folder.searchFiles(
  'mimeType != "image/jpeg" and mimeType != "image/gif" and mimeType != "image/png"')

  var fileNames = '';
  while (files.hasNext()) {
    var file = files.next();
    fileNames += file.getName() + "\r\n";
  }

  if (fileNames) {
    var driveUrl = 'https://drive.google.com/drive/folders/' + folderId;
    var body = '[info][title]不正なファイルの配置を検知しました[/title]' + fileNames + driveUrl + '[/info]';
    postToChatworkMessage(body);
  }

}

// chatworkにメッセージ投稿
function postToChatworkMessage(body) {
  var payload = {
    'body': body
  }
  var headers = {
    'X-ChatWorkToken': token
  }
  var options = {
    'method' : 'POST',
    'payload' : payload,
    'headers' : headers
  }
  var url = 'https://api.chatwork.com/v2/rooms/' + roomId + '/messages';
  UrlFetchApp.fetch(url, options);
}

上記コードで、以下は設定変更の必要があります。

var roomId = 'YOUR_ROOM_ID'; // chatworkの部屋ID
var token = 'YOUR_TOKEN'; // chatworkのAPIトークン

YOUR_ROOM_ID部分にはChatworkの部屋IDを入れてください。
部屋IDはURLの#!rid以降の数字です。
https://www.chatwork.com/#!ridXXXXX // XXXXX部分

Chatwork APIのトークン取得手順に関しては、以前書いたこちらの記事を参考にしてください。

  var folderId = 'YOUR_FOLDER_ID';

ここはGoogleドライブのフォルダIDを入力します。
フォルダIDもChatworkの部屋IDと同じく、URLから取得します。
https://drive.google.com/drive/folders/XXXXX // XXXXX部分

画像以外のファイルをsearchFilesで取得します。

searchFiles(params)
https://developers.google.com/apps-script/reference/drive/folder#searchFiles(String)

searchFilesで使う、検索条件の指定方法は以下を参照。
https://developers.google.com/drive/v3/web/search-parameters

余談ですが、最初はfolderからgetFiles()で全ファイルを取得し、1ファイルずつfile.getMimeType()を使って判定しようと考えていました。
が、画像専用フォルダともなると膨大なファイル数になるので1ファイルごとに判定するのは冗長ですし、Google Apps Scriptは実行時間が5分を過ぎるとタイムアウトするという仕様があるので避けました。
たぶん全ファイル取得して判定するより、searchFilesで必要なファイルだけ取得して判定する方が早いはずです。

スクリプトを実行する

ファイル名は適当でOKです。
保存したらツールバーにある実行アイコンをクリック。

初回実行時はドライブ操作や外部URLの許可をする必要があります。


「許可を確認」を押して以下のようなメッセージが出た場合は、左下の「詳細を表示」を押してXXXXX(安全ではないページに移動)を押し、Googleアカウントを選択し許可を選択。

chatwork通知の確認

画像以外のファイルを試しに配置してみましょう。

その後スクリプトを実行すると、Chatworkに以下の通知が来ます。

Chatwork通知が来ない場合は、

  • 変数fileNamesの中身があるか
  • chatworkの部屋IDが合っているか
  • chatworkの部屋に、トークンを発行したユーザーがいるか(案外忘れがち)

あたりを確認してみてください。

定期実行のセット

Google Apps Scriptは簡単に定期実行ができるので、この監視スクリプトを5分ごと起動に設定しましょう。
ツールバーのストップウォッチアイコンをクリックし、以下のようにセットします。

あとは5分に1回自動的にチェックが走るので、画像以外のファイルがあればChatworkに検知します。
消すまで通知され続けます。結構邪魔なので、「前回実行時間以降に配置されたファイルのみ」を検索条件に足すのもいいかもしれないです。

過激派のあなたは…

いちいちファイル検知して手動削除するのが面倒くさい!
不正ファイルは問答無用で自動的に削除してやる!
という過激派(自動化推奨派)なあなたは、whileのループを以下のように書き換えてください。

removeFile.gs
  while (files.hasNext()) {
    var file = files.next();
    fileNames += file.getName() + "を自動削除\r\n";
    folder.removeFile(file);
  }

これで、画像以外のファイルが自動的に削除されます。