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

# はじめに

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

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

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

# 完成イメージ

画像置き場があり、「hoge.txt」のようなMimeTypeが画像以外のファイルが置かれた時に
![drive.png](https://qiita-image-store.s3.amazonaws.com/0/199678/12a2064e-673d-fbe1-ade0-0e4cafdb9c63.png)

こんな感じに通知してみましょう。
![chatwork.png](https://qiita-image-store.s3.amazonaws.com/0/199678/62168a17-3fb9-da2d-63a5-1cd76e02c72b.png)

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

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

![drive_image.png](https://qiita-image-store.s3.amazonaws.com/0/199678/39e8c3d4-3015-4cdd-4942-d1c8e02e7ab1.png)


# GASファイルの作成

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

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

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

```javascript: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);
}
```

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

```javascript
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のトークン取得手順に関しては、[以前書いたこちらの記事](https://qiita.com/rf_p/items/3e20e4114a1182deb7bc#chatwork-api%E3%81%AE%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E5%8F%96%E5%BE%97)を参考にしてください。

```javascript
  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です。
保存したらツールバーにある実行アイコンをクリック。
![execute.png](https://qiita-image-store.s3.amazonaws.com/0/199678/941e45af-3b49-f533-fba0-240939f3da71.png)

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

![dialog.png](https://qiita-image-store.s3.amazonaws.com/0/199678/193fea39-e857-2ad4-46cd-54d7f04e3040.png)
「許可を確認」を押して以下のようなメッセージが出た場合は、左下の「詳細を表示」を押して*XXXXX（安全ではないページに移動）*を押し、Googleアカウントを選択し許可を選択。
![dialog2.png](https://qiita-image-store.s3.amazonaws.com/0/199678/9d07f1de-88d5-1a63-e30b-097711248baa.png)

# chatwork通知の確認

画像以外のファイルを試しに配置してみましょう。
![drive.png](https://qiita-image-store.s3.amazonaws.com/0/199678/12a2064e-673d-fbe1-ade0-0e4cafdb9c63.png)

その後スクリプトを実行すると、Chatworkに以下の通知が来ます。
![chatwork.png](https://qiita-image-store.s3.amazonaws.com/0/199678/62168a17-3fb9-da2d-63a5-1cd76e02c72b.png)

Chatwork通知が来ない場合は、

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

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

# 定期実行のセット

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

![timer.png](https://qiita-image-store.s3.amazonaws.com/0/199678/3dbdc64c-6311-d559-4743-083619fd5f85.png)

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

# 過激派のあなたは…

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

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

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