2019年12月12日木曜日

Google Apps Script を使って特定ファイルを期限付きで共有してみよう!

これは、Google Products Advent Calendar 2019 の12日目(12月12日)の記事です。

筆者の活動はだいたい、筆者ブログでまとめています。Google関連では、現在 Gmail, Googleアカウント, Chrome のヘルプコミュニティにおいて、プラチナプロダクトエキスパートをしています。何故エキスパート(旧名トップレベルユーザー)になろうとしたのかの経緯は、こちらの記事で書いています。

Advent Calendar は、12月1日からクリスマスまで特定のテーマを決めて、皆でブログを書いてバトンを繋げていくという催しです。IT業界では割と浸透しているかなぁと思います。まだ前半になるため、なにか Googleに関して書きたいことがある!という場合には参加してみてください! 筆者も WordPress Advent Calendar に何度か参加したことがあったのですが、ご無沙汰になってました(末尾参照)。最近 Google Apps Script でいろいろやっていることもあって、それに関して残したいものはここのブログに書いています(末尾参照)。それもあって、年内にもう一記事かくか!と思い立ったのです。

目標と手順


さて、Google Drive では、ダウンロード期限のついた共有ができますが、それを Google Apps Script で自動化したい!というのが目標です。それができたら、たとえばダウンロードサイトのようなものを Google Drive で実装することもできるでしょう。流れとしては
  1. Google フォームでダウンロード申請を行ってもらう
  2. 申請内容は Google スプレットシートに保存
  3. Googleスプレットシートに保存された時に、Google Apps Scriptが実行され、次の動作をする
    1. 特定ファイル(フォルダ)に対して、申請者のGoogleアカウントを読み取り専用で共有設定する
    2. 共有設定解除のスケジュール設定(トリガー)を追加する
    3. 共有リンクをメール通知する
になります。これを実装するには次の6ステップになります。
  1. Google フォームでダウンロード申請を行ってもらう
  2. 申請されたら Googleスプレットシートに申請データを保存
  3. Googleスプレットシートに Google Apps Script を設定
  4. Google Apps Script の動作テスト
  5. トリガー設定
     Googleスプレットシートに申請データが保存されたら、Google Apps Scriptを実行
  6. 最終テスト

というのがもっともシンプルです。これを順を追って説明します。また説明を簡略化するために、Google Apps Script も非常にシンプルな構成にしています。

Step 1. Googleフォームでダウンロード申請を作成する


フォーム利用者は、メールアドレスは必須です。実際にはダウンロードするときに、そのメールアドレスで Googleアカウントをとってもらい、そのメールアドレスでログインする必要があります。Gmail は Googleアカウントなので、それでもいいです。

1. Google ドライブ > 新規 > その他 > Googleフォームを選択します。




2. 設定(歯車アイコン)より、「メールアドレスを収集する」にチェックを入れます。



3. フォームを作成します。

今回は説明を簡略化するために、メールアドレスと名前と所属ぐらいにしています。




 Step 2. 申請されたら Googleスプレットシートに申請データを保存


1. Googleフォームの「回答」タブで、「Googleスプレットシート」アイコンをクリックします。


2. 新しいスプレットシートを作成を選択して「作成」リンクをクリックします。



3. すると、下図の Googleスプレットシートが開きます。
これで、Googleフォームで送信されたデータは、このGoogleスプレットシートに追加保存されていきます。保存場所は、Googleフォームと同じフォルダに、Googleスプレットシートファイルが保存されています。




Step 3. Googleスプレットシートに Google Apps Script を設定


1. Googleスプレットシートのファイルメニューから「ツール > スクリプトエディタ」を開きます。



2. 名前のない Google Apps Script ファイルができるので、名前をつけましょう。



上図の「無題のプロジェクト」をクリックすると名前変更が可能です。
ここでは、「autoexpire_for_viewusers_to_sharedLink」としておきます。

そしてコード内にある文字をすべて消した上で
のコードをすべて選択しコピーして、Google Apps Script 内にペーストします。
すると、下図のようになるでしょう。



3. 共有したいファイルを Google Drive にアップロードし、ファイルIDをチェックする

  • https://drive.google.com/drive/u/0/folders/ファイルID

アップロードしたファイル(フォルダでもよい)にアクセスし、そのURLから「ファイルID」をコピーしてください。URLの赤文字の部分になります。
そして、コードの「ファイルID」部分をそのコピーしたものに置き換えてください。

  • var URL = "https://drive.google.com/open?id=ファイルID";
すると下図のように、ファイルIDを含んだ URLになっているはずです(ここでは一部伏せ字にしています)




そして保存してください。

Step 4. Google Apps Script の動作テスト


トリガーを設定して自動化する前に、動くかどうかのテストが必要です。


上図のように手動でデータを2つ入力してみてください。
  • タイムスタンプ:年/月/日 時:分:秒   のフォーマットで、最終行(3行目)は、現在日時から7日前のものをいれてください
    • 現在が、2019年12月5日なら 2019年11月28日 11:11:22(7日前、時、分、秒は適当でよい)
  • メールアドレス:Googleアカウントとして存在するメールアドレス(Gmail等)を入力してください。
テストは3行目のデータで行います。

テスト1) Googleフォーム送信時のテスト(共有されているかどうか)

スクリプトエディタのファイルメニューから「実行 > 関数を実行 > autoexpire_for_viewusers_to_sharedLink」を選択します。


すると、アカウント選択画面が出てくるので、今ログインしているGoogleアカウントを選択します。次に、無料版 Googleアカウントの場合には、作成したスクリプトが安全かどうかわからないので警告がでます(G Suite アカウントならこれはでないはずです)。



上記の「詳細」リンクをクリックし、


 「autoexpire_for_viewusers_to_sharedLink(安全ではないページ)に移動」リンクをクリックしてください。すると、autoexpire_for_viewusers_to_sharedLink に対して、Googleドライブへのアクセス許可を聞いてきます。「許可」してください。

エラーの場合には、画面上部にビックリマークとともに赤文字でエラーが出ます。それがでない場合には、実行は成功しているはずです。詳細は、編集 > 現在のプロジェクトのトリガーを開き、「エラー率」が0ならエラーなしです。より詳細は「実行数」をみるとわかります。

設定したファイル(フォルダ)の共有設定について、Googleスプレットシートの2行目のメールアドレスが追加されていることを確認してみてください。

またメール通知がうまくされているか確認してみてください。


テスト用では、有効期限は本日の日時になっているはずです。

テスト用データでは、解除トリガーは設定されません。理由は7日前の申請にしているため、現在時間 > 申請時間 + 7日 となってトリガーが発動しない条件になっているためです。これは最終段階でテストします。

テスト2)共有されたユーザーの共有解除


今回は7日後のユーザーの共有解除ができる設定になっています。
そして3行目は、7日前のデータで入力していますので、このユーザー(メールアドレス)の共有解除を手動でできるはずです。

スクリプトエディタのファイルメニューから「実行 > 関数を実行 > autoExpireSharedUsers」を選択します。こちらの関数がGoogleスプレットシートに入ったデータのうちタイムスタンプが7日以前(実際には AfterDayの設定値)の共有を解除すr


エラーの場合には、画面上部にビックリマークとともに赤文字でエラーが出ます。それがでない場合には、実行は成功しているはずです。詳細は、編集 > 現在のプロジェクトのトリガーを開き、「エラー率」が0ならエラーなしです。より詳細は「実行数」をみるとわかります。

エラーがなければ、共有解除されていることを確認してみてください。

STEP 5. トリガー設定(Googleスプレットシートに申請データが保存されたら、Google Apps Scriptを実行)


さて最後のトリガー設定です。

1. ファイルメニューの「編集 > 現在のプロジェクトのトリガー」を選択します。




4. 「トリガーを追加」ボタンをクリックして、トリガー設定をしてください。



実行する関数:autoexpire_for_viewusers_to_sharedLink
イベントのソースを選択:スプレットシートから
イベントの種類を選択:フォーム送信時
エラー通知設定:今すぐ通知を受け取る




アカウント選択画面が出てくるので、今ログインしているGoogleアカウントを選択します。次に、無料版 Googleアカウントの場合には、作成したスクリプトが安全かどうかわからないので警告がでます(G Suite アカウントならこれはでないはずです)。
*もしかしたら、STEP 4.  のテストで権限を付与しているので警告が出ないかもしれません



上記の「詳細」リンクをクリックし、


 「autoexpire_for_viewusers_to_sharedLink(安全ではないページ)に移動」リンクをクリックしてください。すると、autoexpire_for_viewusers_to_sharedLink に対して、Googleドライブへのアクセス許可を聞いてきます。「許可」してください。

そして保存すると、下図のようにトリガーに追加されました。



これで、今回作成されたGoogleフォームで送信された時に、「autoexpire_for_viewusers_to_sharedLink」が実行されることになります。

STEP 6. 最終テスト


Googleフォームから入力してみましょう。



そして、

1. Googleスプレットシートにデータが保存されていることの確認
2. 登録したメールアドレスに通知が届いていることの確認
3. Google Drive においたファイル(フォルダ)の共有設定に登録したメールアドレスが追加されていることの確認

を確認できたら完成ということになります。


4. トリガー(Googleスプレットシート > 編集 > 現在のプロジェクトのトリガー)に、「autoExpireSharedUsers」が追加されていること、その実行時間がタイムスタンプの年月日+7日後であることを確認してみてください。



のエラー率あたりにマイスポインタをもってくると編集アイコン(鉛筆マーク)がでます。そこをクリックすると


のようにいつ実行されるかの日時がでてきます。
この日時を1, 2分後に変更して、トリガーが実行されるか確認してみてください。
トリガーが実行されると、そのトリガーのステータスは「無効」になって残ります。

これは消しても構いませんし、実行後のトリガーだという証拠として残しておいても構いません。

なお手動で一連のデータを消す場合には、
  1. 共有解除のトリガーを削除
  2. 共有設定を解除
  3. Googleスプレットシートからデータを削除
  4. Googleフォームからデータの削除
で可能です。

共有ドライブ(旧チームドライブ)でも使えるが十分な注意が必要


まず共有ドライブは、チームで作業するためが目的になります。ですので管理者が適切に共有ドライブのユーザー管理をしなければなりません。今回紹介したシステムを使えば自動登録は可能ですが、不特定多数が登録されてしまう可能性があることに留意する必要があります。
活用を鑑みると、Googleスプレットシートに手動で登録して、手動で Google Apps Script を管理者が実行することで、いちいち共有ドライブにログインして設定する手間は省けます。また一時的にダウンロードさせたいデータもあるでしょう。そうした場合には役立つものと思います。

注意点
  1. 共有ドライブの制限にあるようにダウンロード制限もあるので注意
  2. ドライブ ユーザーの共有権限を設定する(G Suite管理者によってドメイン外ユーザーが禁止されていると、ドメイン内ユーザーしか追加できません。
  3. 共有ドライブに対してユーザー追加できる権限を持つアカウント(G Suite)で Google Apps Script を実行する必要がある。
Googleフォームを経由する場合、URL を知られれば誰でもアクセスできてしまうので、知らない無料版 Googleアカウントが勝手に追加されているということもあります。外部公開するダウンロードサイトならよいのですが、そうでないなら十分に気をつける必要はあるでしょう。

このGoogle Apps Script は中大規模には向かない


この Google Apps Scriptのアルゴリズムは、解除判定のためにGoogleスプレットシートから全データを一旦取得して、各行のタイムスタンプを取得し、「現在年月日 = タイムスタンプの年月日 + AfterDay」かどうかで共有解除するかを判断しています。これは共有解除のトリガーでは関数に引数を渡せないためです。

もし、時間ベースのトリガに変数を渡すGAS で書かれているようにプロパティを使って、「autoExpireSharedUsers」関数にメールアドレスを引数で渡せるなら、そのメールアドレスのみを共有解除したらよいので簡単のはずです。プロパティを使ったやり方は筆者はまだ会得しておらず、トリガーをつかうと全データのチェックが必要になってしまうわけです。で、Google Apps Script は1つの実行に対する許容時間があります。

https://developers.google.com/apps-script/guides/services/quotas

にかかれていますが、無料版 Googleアカウントで 6分、有料のG Suite なら 30分ですね。無料版だと時間が短すぎてすぐにオーバーしてしまう可能性があります。それを回避するためには処理を分割実行([GAS]実行時間6分の壁を越えよう(不死鳥関数編))するように改良すればいけるかもしれません。ただ筆者はそこまでやる労力と興味もないので、説明しません。

参考資料



Google Apps Script 関連で過去に書いた記事


  1. 【GAS】Googleドライブ / チームドライブの特定フォルダ以下のファイル一覧を表示する方法
  2. 【ボツ / 備忘録】Gmailで予約送信するための Googleフォームを作成しよう!
  3. Gmail に予約送信機能を実装するには・・・
  4. 第一回 ローカル(非公式) Google Meetup in Okayama に参加して
    • 特定条件(Gmail検索)でGmailに添付されたメールを送信者ごとにGoogle Driveに自動保存する
    • 複数のGoogle Analytics データをまとめてHTMLとPDF形式で自動メール送信する
  5. Google Apps Script を使って、特定条件に一致した Gmail の添付ファイルを Googleドライブへ保存する方法

過去参加した Advent Calendar



2019年12月12日 @kimipooh

0 件のコメント:

コメントを投稿