Google Apps Scriptでファイル所有権を変更する【GAS】
自分はよくGoogle Apps Scriptでフォームを作成し、その際に入力データを予め用意しておいたテンプレートに書き込みをしています。しかし、この場合生成したファイルの権限というものは、生成した先のフォルダの権限に依存し、尚且つファイルそのもののオーナーは自分の権限でフォームを公開してる場合、入力者ではなく自分になってしまいます。
また、その際に実行権限を自分ではなく入力者にすれば、オーナー権限は入力者になりますが、この場合メール送信などのプログラムを組んでいると、メールの送信元も自分ではなく入力者となり、なんだかちょっと気持ち悪い。最初の1回は、入力者が承認作業をしないといけないおまけ付きです。
ということで、こんな時にフォームの実行権限は自分のままで、生成したファイルのオーナー権限は入力者のものにしたい & 他にも権限を追加したい場合のテクニックとして、今回まとめてみました。今回のテーマでは2パターンのファイル権限追加&変更方法を紹介します。
※以前は確かに動作していましたが、現在はDrive APIの手法でもオーナー移譲で通知は送られるように、この「sendNotificationEmails」というオプション自体が機能していないようです(セキュリティ面から対処されたのかも)。v2には記載が無いのですが、v3のほうでは、その旨の記載があります。
目次
使用するクラス、メソッド等
今回は、ケースに応じて以下のメソッドやクラス・サービスを利用します。また、今回はファイル権限の問題から、サンプルファイルはありません。コードを参考に実装してみてください。
ソースコード
Google Apps Scriptで通常使用するDriveAppのaddViewerやsetOwnerメソッドは、必ずメールで追加した人やオーナーに変更した人にメールが飛んでしまいます。これが結構不評なケースがあり、最初から入力者はオーナーにしておけ、といったようなケースの場合困った事になります。オプション設定もないので、このままではどうにもなりません。よって、2パターンとは、通常の権限変更時(メール通知あり)と、メール通知をしない権限の変更時の2つとなります。
通常の権限変更時(メール通知あり)
対象のファイルが所属してるフォルダやファイルに、該当者の権限が全くない場合には、いきなりオーナー権限を付与できません。よって、一度閲覧者や編集者としてユーザを追加し、すかさずオーナー権限を付与するようなコードを記述します。そのため、編集のお誘いメールが2度も飛ぶので具合はよくありません。かといって、厳格に権限運用してる場合、いちいちフォルダに権限を付与を手動でするというのも困った話ではあります。
※ちなみにDriveAppじゃなくてもSpreadsheetAppでも権限の追加は可能ですが、Owner権限の変更は出来ません。
1 2 3 4 5 6 7 8 9 10 |
function driveadd(){ var mail = "ここに該当者のメールアドレスを入力"; var fileid = "ここに対象となるファイルIDを入力"; var fileman = DriveApp.getFileById(fileid); fileman.addViewer(mail); fileman.setOwner(mail); } |
Drive API v2を利用した変更
Google Apps ScriptのHTML Serviceを使用したウェブアプリケーションでは、自分の権限で動かすか?入力者が承認作業をしてその人の権限で動かすかを選択できます。しかし、後者の場合例えばメール送信を行うとその人がその人に向けてメールを送信してる事になるので、オカシナ感じになります。故に、自分の場合、実行権限は自分としてファイルのオーナー権限のみを入力者に渡したい(尚且つ、メール通知をしないで)となると、これまでは、手動でGoogle Driveから通知なしでオーナー権限を移譲する作業をしていました。
しかし、Googleの拡張サービスを利用するとこれが可能になります。そのため、開発者は以下の手順で事前にDrive APIを利用可能な状態にしておく必要があります。Drive APIの場合、メール通知をせずに共有設定を行うことが可能です。
プロジェクトを移動
Drive APIサービスをONにする
- スクリプトエディター画面に於いて、メニューの「リソース」⇒「Googleの拡張サービス」を開く
- Drive APIを探しだして、トグルをONにする
- 続いて、下のGoogle Cloud Platform API ダッシュボード をクリックする
- APIライブラリ画面が出るので、Driveと検索するか直接Google Drive APIを探しだし、クリックする
- 有効にするボタンをクリックする
これでDrive APIがGoogle Apps ScriptでDrive APIを使えるようになります。
図:Drive APIをオンにした
図:Google Cloud Consoleでもオンにする
権限変更のソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
function myFunction() { var mail = "ここに追加したいユーザのメールアドレスを入力"; var fileid = "対象のファイルIDを入力する"; //ファイルオーナー権限を移譲する Drive.Permissions.insert( { 'role': 'owner', //writerとすると編集者権限になります 'type': 'user', 'value': mail //valueにmailのメアドを入れる }, fileid, //ここにfileid変数のファイルのIDを入れる { 'sendNotificationEmails': 'false' //trueとすると通知が飛んでしまいます } ); } |
- Drive.Permissions.insertで権限の追加、Drive.Permissions.updateで権限の変更となります。後者の場合あらかじめ該当ファイルにそのユーザの権限が追加されていないと、エラーになります。
- Drive.Permissions.insertでは、いきなり編集権限を付与する事が可能です。
- sendNotificationEmailsオプションをfalseにすることで、メール通知なしでファイルオーナー権限を移譲できます。
共有期限を決めて共有するケース
現在のGoogle Driveは共有期限を決めて権限を付与することが可能になっています(但し、閲覧者かコメント可のどちらかの権限で)。これらはDrive上からは設定できますが、スクリプトからもDrive API v2を利用してセットする事が可能になっています。
編集権限でリミット制限を掛けたい場合には、スプレッドシートなどでユーザと日付を管理し、スクリプトトリガーなどの仕掛けで共有解除するようなコードを自前で記述する必要があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
function expirePermission() { var mail = "ここにメールアドレスを入力"; var fileid = "ここにファイルのIDを入れる"; var tempdate = new Date("2021/07/25 19:00:00"); //日付と時刻をセットする var expireDate = tempdate.toISOString(); //RFC3339フォーマットに変換("2021-07-25T10:00:00+09:00") //メールからパーミッションIDを取得 var permissionId = Drive.Permissions.getIdForEmail(mail); //リミットを設定する Drive.Permissions.update( { 'role': 'reader', //readerかcommenter 'expirationDate': expireDate //RFC3339の日付形式で指定 }, fileid, //ここにfileid変数のファイルのIDを入れる permissionId.id ); } |
- 新規に追加したい場合には、まずDrive.Permissions.Insertで追加してから、Drive.Permission.updateで変更を掛ける必要があります。
- permissionIdを取得し、引数に加えてあげる必要があります。
- 付与権限は閲覧者かコメント可のどちらかが使用できます。
- 日付はRFC3339形式で指定する必要があります。
- new Dateで普通に日付をセットし、toISOStringでRFC3339形式の日付に変換するのが楽な方法になります。
- メアドはユーザ、グループ両方使用可能
- 日時は未来の日付である必要があります。
- 期限は最大1年後を超えて設定することは出来ません。
図:編集権限でのリミット制限は仕様上出来ない