Google Apps Scriptでファイル所有権を変更する【GAS】

自分はよくGoogle Apps Scriptでフォームを作成し、その際に入力データを予め用意しておいたテンプレートに書き込みをしています。しかし、この場合生成したファイルの権限というものは、生成した先のフォルダの権限に依存し、尚且つファイルそのもののオーナーは自分の権限でフォームを公開してる場合、入力者ではなく自分になってしまいます。

また、その際に実行権限を自分ではなく入力者にすれば、オーナー権限は入力者になりますが、この場合メール送信などのプログラムを組んでいると、メールの送信元も自分ではなく入力者となり、なんだかちょっと気持ち悪い。最初の1回は、入力者が承認作業をしないといけないおまけ付きです。

ということで、こんな時にフォームの実行権限は自分のままで、生成したファイルのオーナー権限は入力者のものにしたい & 他にも権限を追加したい場合のテクニックとして、今回まとめてみました。今回のテーマでは2パターンのファイル権限追加&変更方法を紹介します。

※以前は確かに動作していましたが、現在はDrive APIの手法でもオーナー移譲で通知は送られるように、この「sendNotificationEmails」というオプション自体が機能していないようです(セキュリティ面から対処されたのかも)。v2には記載が無いのですが、v3のほうでは、その旨の記載があります。

使用するクラス、メソッド等

今回は、ケースに応じて以下のメソッドやクラス・サービスを利用します。また、今回はファイル権限の問題から、サンプルファイルはありません。コードを参考に実装してみてください。

  1. DriveAppクラスのaddViewerメソッドやsetOwnerメソッド
  2. Drive APIサービスのinsertメソッドやupdateメソッド

ソースコード

Google Apps Scriptで通常使用するDriveAppaddViewersetOwnerメソッドは、必ずメールで追加した人やオーナーに変更した人にメールが飛んでしまいます。これが結構不評なケースがあり、最初から入力者はオーナーにしておけ、といったようなケースの場合困った事になります。オプション設定もないので、このままではどうにもなりません。よって、2パターンとは、通常の権限変更時(メール通知あり)と、メール通知をしない権限の変更時の2つとなります。

通常の権限変更時(メール通知あり)

対象のファイルが所属してるフォルダやファイルに、該当者の権限が全くない場合には、いきなりオーナー権限を付与できません。よって、一度閲覧者や編集者としてユーザを追加し、すかさずオーナー権限を付与するようなコードを記述します。そのため、編集のお誘いメールが2度も飛ぶので具合はよくありません。かといって、厳格に権限運用してる場合、いちいちフォルダに権限を付与を手動でするというのも困った話ではあります。

※ちなみにDriveAppじゃなくてもSpreadsheetAppでも権限の追加は可能ですが、Owner権限の変更は出来ません。

Drive API v2を利用した変更

Google Apps ScriptのHTML Serviceを使用したウェブアプリケーションでは、自分の権限で動かすか?入力者が承認作業をしてその人の権限で動かすかを選択できます。しかし、後者の場合例えばメール送信を行うとその人がその人に向けてメールを送信してる事になるので、オカシナ感じになります。故に、自分の場合、実行権限は自分としてファイルのオーナー権限のみを入力者に渡したい(尚且つ、メール通知をしないで)となると、これまでは、手動でGoogle Driveから通知なしでオーナー権限を移譲する作業をしていました。

しかし、Googleの拡張サービスを利用するとこれが可能になります。そのため、開発者は以下の手順で事前にDrive APIを利用可能な状態にしておく必要があります。Drive APIの場合、メール通知をせずに共有設定を行うことが可能です。

プロジェクトを移動

今回の発表直前の2019年4月8日より、Google Apps ScriptからCloud Platform Projectへ直接アクセスが出来なくなりました。これまでにデプロイしてるものについては、これまで通り「リソース」⇒「Google Cloud Platform API ダッシュボード」からアクセスが可能です。

今回の変更はスプレッドシート上で動かすスクリプトやGoogleの拡張サービスを利用しないタイプのスクリプトであれば特に問題はありませんが、「Apps Script API」や「Google Picker API」、「Cloud SQL接続」などGCP上のAPIを利用する場合には以下の手順を踏んで、Google Apps Scriptにプロジェクトを連結する必要があります。これまでは、自動的にGCP上にGoogle Apps Script用のプロジェクトが生成されていたのですが、今後は自分の組織(もしくはGCPプロジェクト)上で作成されたプロジェクトでなければならないということです。詳細はこちらのページを見てください。

連結する手順は以下の通り

  1. Google Cloud Consoleを開く
  2. 左上にある▼をクリックする
  3. ダイアログが出てくるので、新規プロジェクトを作るか?既存のプロジェクトを選択する。この時、G Suiteであれば選択元は「自分のドメイン」を選択する必要があります。
  4. プロジェクト情報パネルから「プロジェクト番号」をコピーする
  5. 対象のGoogle Apps Scriptのスクリプトエディタを開く
  6. 「リソース」⇒「Cloud Platform プロジェクト」を開く
  7. 4.で入手した番号をプロジェクトを変更のテキストボックスに入れて、プロジェクトを設定ボタンをクリックする
  8. 無事に移動が完了すればメッセージが表示されます。
  9. この時、元の自動作成されたプロジェクトはシャットダウンされて消えます。これで設定完了です。

今回のこの変更だと1つ作ったプロジェクトに集約する必要があるので、クォータについてプロジェクト毎のカウントだったので問題なかったものが、集約されることで、クォータに引っ掛かる可能性があります。

図:プロジェクト番号をコピーしておきます

図:プロジェクトを他のプロジェクトに紐付けしました。

図:GCPの拡張サービスを使うには手順が必要になった

Drive APIサービスをONにする

  1. スクリプトエディター画面に於いて、メニューの「リソース」⇒「Googleの拡張サービス」を開く
  2. Drive APIを探しだして、トグルをONにする
  3. 続いて、下のGoogle Cloud Platform API ダッシュボード をクリックする
  4. APIライブラリ画面が出るので、Driveと検索するか直接Google Drive APIを探しだし、クリックする
  5. 有効にするボタンをクリックする

これでDrive APIがGoogle Apps ScriptでDrive APIを使えるようになります。

図:Drive APIをオンにした

図:Google Cloud Consoleでもオンにする

権限変更のソースコード

  • Drive.Permissions.insertで権限の追加、Drive.Permissions.updateで権限の変更となります。後者の場合あらかじめ該当ファイルにそのユーザの権限が追加されていないと、エラーになります。
  • Drive.Permissions.insertでは、いきなり編集権限を付与する事が可能です。
  • sendNotificationEmailsオプションをfalseにすることで、メール通知なしでファイルオーナー権限を移譲できます。

共有期限を決めて共有するケース

現在のGoogle Driveは共有期限を決めて権限を付与することが可能になっています(但し、閲覧者かコメント可のどちらかの権限で)。これらはDrive上からは設定できますが、スクリプトからもDrive API v2を利用してセットする事が可能になっています。

編集権限でリミット制限を掛けたい場合には、スプレッドシートなどでユーザと日付を管理し、スクリプトトリガーなどの仕掛けで共有解除するようなコードを自前で記述する必要があります。

  • 新規に追加したい場合には、まずDrive.Permissions.Insertで追加してから、Drive.Permission.updateで変更を掛ける必要があります。
  • permissionIdを取得し、引数に加えてあげる必要があります。
  • 付与権限は閲覧者かコメント可のどちらかが使用できます。
  • 日付はRFC3339形式で指定する必要があります。
  • new Dateで普通に日付をセットし、toISOStringでRFC3339形式の日付に変換するのが楽な方法になります。
  • メアドはユーザ、グループ両方使用可能
  • 日時は未来の日付である必要があります。
  • 期限は最大1年後を超えて設定することは出来ません。

図:編集権限でのリミット制限は仕様上出来ない

関連リンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)