はじめに
今回の記事では、Google Apps Script(GAS)を使用してGoogle Drive上のファイルやフォルダの変更ログをスプレッドシートに記録できるツールを紹介します。
Google Drive大量のファイルやフォルダが存在する場合、特定のアイテムがいつ、誰によって変更されたのかを追跡するのは一筋縄ではいきません。
そこで今回の記事ではGoogle Apps Scriptを使用して、Google Drive内のファイルやフォルダの変更履歴を定期的にトラッキングし、Googleスプレッドシートに記録する方法を紹介します。
- 手動でのチェックが不要。定期的にスクリプトを実行するだけで、変更履歴が自動的に記録されます。
- 新規作成、編集、削除されたアイテムの情報だけでなく、変更を行ったユーザ(メールアドレス)まで取得可能。
- Googleスプレッドシートに変更履歴がまとめられるため、過去の変更を簡単に確認できます。
GASを触ったことのない方でも簡単に作成可能です。作業時間は15分ほどです。
動作イメージ
まずは簡単に本ツールの動作について説明します。
まず、記録を行いたいフォルダを用意します。今回は[test_Monitoring_Drive]としています。
また、[サンプルフォルダ]内にも画像のようにファイルが存在しています。今回のツールではサブフォルダ以下のファイルやフォルダに対しても記録が可能です。
ツールとなるスプレッドシートは以下のようになっています。A1セルには記録を行った最終実行時間が記載されており、また、もう一つ別のシートにはファイルのIDを記録するためのシートを作成しています。
GASが実行されると、A1セルの最終実行時間よりも後に作成されたファイルに対しては[新規追加]として、スプレッドシートに記録されます。
また、ファイルの中身を変更したり、ファイルやフォルダの削除を行うとその記録が追記されます。
作成方法
スプレッドシートの新規作成
まず、Google スプレッドシートにアクセスします。
アクセスしたら、[新しいスプレッドシートを作成]> [空白]をクリックして新しいスプレッドシートを作成します。
また、以下のように[FileFolderLog]というシートを作成しておいてください。
また、スプレッドシートに2行目には画像のようにヘッダーを作成しておくと後で見やすくなります。
その後、[拡張機能]>[Apps Script]をクリックします。
GASの設定
新しいタブが開きGASが表示されます。
ここから、GAS上でスクリプトを作成します。もともと記載してある以下コードは削除します。
function myFunction() {
}
削除したら、以下コードをコピーしてそのまま貼り付けてくだい。
このとき、1行目のYOUR_FOLDER_ID には記録したいフォルダーのIDに書き換えます。
フォルダIDは以下で確認できます。
①IDを知りたいフォルダを開く
②URLをチェックし『…/folders/{フォルダID}』をコピー
var FOLDER_ID = 'YOUR_FOLDER_ID'; // フォルダIDをスクリプトの一番上に記載
var LOG_SHEET_NAME = 'FileFolderLog';// ログのシート名を記載
function checkFilesAndFoldersChanges() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var logSheet = spreadsheet.getSheetByName(LOG_SHEET_NAME);
var parentFolder = DriveApp.getFolderById(FOLDER_ID);
var lastCheckedDate = new Date(sheet.getRange('A1').getValue());
var previousIds = getPreviousIds(logSheet);
var changes = [];
checkFolderRecursively(parentFolder, changes, lastCheckedDate, previousIds);
// 削除されたアイテムを検出
var currentIds = getCurrentIds(parentFolder);
previousIds.forEach(function(id) {
if (currentIds.indexOf(id) === -1) {
// 削除されたアイテム
changes.push([new Date(), '不明', '不明', '削除', '不明', id, '不明']);
}
});
// 現在のIDのリストをログシートに保存
saveCurrentIds(logSheet, currentIds);
// 変更を一度にスプレッドシートに書き込む
if (changes.length > 0) {
var targetRange = sheet.getRange(sheet.getLastRow() + 1, 1, changes.length, 7);
targetRange.setValues(changes);
}
sheet.getRange('A1').setValue(new Date()); // 最後にチェックした日時を更新
}
function checkFolderRecursively(folder, changes, lastCheckedDate, previousIds) {
var files = folder.getFiles();
var folders = folder.getFolders();
while (files.hasNext()) {
var file = files.next();
var createdDate = new Date(file.getDateCreated());
var updatedDate = new Date(file.getLastUpdated());
var userEmail = getLastModifiedUser(file.getId());
if (createdDate > lastCheckedDate) {
changes.push([file.getLastUpdated(), 'ファイル', file.getName(), '新規追加', userEmail, file.getId(), file.getParents().next().getId()]);
} else if (updatedDate > lastCheckedDate) {
changes.push([file.getLastUpdated(), 'ファイル', file.getName(), '変更', userEmail, file.getId(), file.getParents().next().getId()]);
}
}
while (folders.hasNext()) {
var subFolder = folders.next();
var createdDate = new Date(subFolder.getDateCreated());
var updatedDate = new Date(subFolder.getLastUpdated());
var userEmail = getLastModifiedUser(subFolder.getId()); // フォルダの最後の変更を行ったユーザのメールアドレスを取得
if (createdDate > lastCheckedDate) {
// 新規作成されたフォルダ
changes.push([subFolder.getLastUpdated(), 'フォルダ', subFolder.getName(), '新規追加', userEmail, subFolder.getId(), subFolder.getParents().next().getId()]);
} else if (updatedDate > lastCheckedDate) {
// 編集されたフォルダ
changes.push([subFolder.getLastUpdated(), 'フォルダ', subFolder.getName(), '変更', userEmail, subFolder.getId(), subFolder.getParents().next().getId()]);
}
// サブフォルダを再帰的にチェック
checkFolderRecursively(subFolder, changes, lastCheckedDate, previousIds);
}
}
function writeToFileSheet(sheet, lastUpdated, type, name, id, parentId, action, useremail) {
var lastRow = sheet.getLastRow();
var targetRow = lastRow + 1;
sheet.getRange('A' + targetRow).setValue(lastUpdated);
sheet.getRange('B' + targetRow).setValue(type);
sheet.getRange('C' + targetRow).setValue(name);
sheet.getRange('D' + targetRow).setValue(action);
sheet.getRange('E' + targetRow).setValue(useremail);
sheet.getRange('F' + targetRow).setValue(id);
sheet.getRange('G' + targetRow).setValue(parentId);
}
function getPreviousIds(logSheet) {
var lastRow = logSheet.getLastRow();
if (lastRow === 0) {
return [];
}
var data = logSheet.getRange(1, 1, lastRow).getValues();
return data.map(function(row) { return row[0]; });
}
function getCurrentIds(folder) {
var ids = [];
var files = folder.getFiles();
var folders = folder.getFolders();
while (files.hasNext()) {
ids.push(files.next().getId());
}
while (folders.hasNext()) {
var subFolder = folders.next();
ids.push(subFolder.getId());
ids = ids.concat(getCurrentIds(subFolder));
}
return ids;
}
function saveCurrentIds(logSheet, ids) {
logSheet.clear(); // 以前のデータをクリア
var data = ids.map(function(id) { return [id]; });
logSheet.getRange(1, 1, data.length, 1).setValues(data);
}
function getLastModifiedUser(fileId) {
try {
var revisions = Drive.Revisions.list(fileId);
if (revisions && revisions.items && revisions.items.length > 0) {
var lastRevision = revisions.items[revisions.items.length - 1];
return lastRevision.lastModifyingUser.emailAddress;
}
} catch (e) {
// エラーが発生した場合
return null;
}
return null;
}
アプリIDとスプレッドシートIDの記入が完了したら、[Ctrl+S]かApps Script 上部バーの[プロジェクトを保存]をクリックして保存します。
Drive APIの追加
Apps Scriptのエディタの左サイドバーにある「サービス」をクリックします。
「+ サービスを追加」をクリックし、”Drive API”を検索して追加します。
GASの実行
Google Apps Script 上部バーの[▶実行]をクリックします。最初のスクリプトの実行には権限が必要となるため、[承認が必要です]というモーダルが表示されたら、
[権限を確認]>[表示されているGoogleアカウント]>[詳細]>[無題のプロジェクト(安全ではないページ)に移動]>[許可]まで移動します。クリック後GASが実行されます。
この時点では、A1セルに実行した時間が記載されます。
トリガーの作成
トリガーを設定することで、スクリプトを定期的に自動実行することができます。例えば、毎日特定の時間に変更履歴をチェックするように設定することが可能です。
Apps Scriptのエディタの左サイドバーにある「トリガー」(時計のアイコン)をクリックし、下部にある「+ トリガーを追加」をクリックします。
「関数を実行」のドロップダウンから、checkFilesAndFoldersChanges
を選択します。
「イベントのソース」のドロップダウンから「時間主導型」を選択します。
「時間ベースのトリガーのタイプ」のドロップダウンから、実行の頻度を選択します。
必要に応じて他のオプションを設定し、「保存」をクリックします。
注意点
GASおすすめ本
GASをもっと勉強したい!ほかにも自分で何か作成したい!という方には以下がおすすめです。仕事で使えるアイデアなども得ることができます。