[GAS]スプレッドシートの更新を通知する勉強

以前、ちょろっと勉強したっきり触ってなかったGASについて勉強していく。

まず思いついたのは、Googleドライブ上のファイルが更新されたら通知を飛ばすみたいな処理。

ちょっと調べただけでも、たくさんそんな様なソースが出てきた。

試しに新規のGoogle Apps Scriptを作って張り付けたらサクサク動いた・・・チョー便利。。。

 

でも、これじゃなんの勉強にもならないので試しに動かしたソースを咀嚼してみる。

今回試したのはこちら。

Google Driveでフォルダ内のファイルが更新されたらメール通知を送るGoogle Apps Script

 

2019/09/24時点でアップされていたコードはこんな感じ↓↓↓

 

1.まず、考え方を理解する。

Excelマクロの延長で勉強しようとして、最初に「あっ・・・ふぅーん。」ってなったところ。

今回、ファイルが「上書き保存」されたタイミングで通知が欲しいと思った。

Excelマクロで言うと、WorkbookのAfterSaveイベントあたりになんか仕込むかーって感じだけど

スプレッドシートでは、Simple Eventsとしてハンドルできるのが5種類しかない。

  • onOpen(e)
  • onEdit(e)
  • onInstall(e)
  • doGet(e)
  • doPost(e)

サーッとイベントの名前だけ見て思うよね。

「こりゃ、ファイル更新のイベントは取れないな」って。

で、今回引用したコードがどうなってるかっていうとスプレッドシートから通知をキックするんじゃなくて個別にスクリプトを定期実行させて、ポーリング監視みたいにして管理用のスプレッドシート上で個別にファイルの最終更新日時を管理してるんですね。

Googleドライブは、サーバ上でデータ管理してるんだなーって実感しました。

なるほど、NASでExcelファイルを管理するのとは訳が違うぜ。

 

2.使ってるAPIを見ていく。

そう長いコードじゃないけども、Googleリソース上で、以下の権限を必要としてる。

  • 監視対象のGoogleドライブフォルダ情報を取得
  • スプレッドシートの更新
  • 代理でGmailを送信

どれも、スクリプトの冒頭で可変項目として纏められてるパラメータ使う部分ですね。

 

Googleドライブ フォルダの取得

DriveApp.getFolderById(TARGET_FOLDER_ID);

IDは、URLから取れる長いトコ。

取得されたオブジェクトからgetFoldersとかgetFilesでフォルダやファイルの一覧が取得できるのは直感的でスッと入ってくるね。

そこから順番にファイルを取得するには、.hasNext()でループチェックしつつ.next()して取る感じですか。
Fileオブジェクトからは、.getName()でファイル名取って.getId()でID取って更新日時は.getLastUpdated()を取得する感じですね。

 

スプレッドシートの操作

SpreadsheetApp.openById(UPDATE_SHEET_ID);

こちらも、IDはURLから取れる長いトコね。

で、取得されるのはExcelで言うとこのWorkbookみたいなオブジェクトだから次にシートを取得してるね。

spreadsheet.getSheetByName(UPDATE_SHEET_NAME);

シートからデータ取る時には、次の構文でセルのデータが2次元配列的な感じで取得される訳ね。

sheet.getDataRange().getValues();

あとの更新されてるか比較する処理は、Javascriptまんまだからそのまま読めるね。

 

日付フォーマット変換

Utilities.formatDate(item.lastUpdate, “JST”, “yyyy-MM-dd HH:mm:ss”)

プレーンなJavascriptだと日付の変換処理ってメンドクサイけど、Utilitiesっていうのでサクッと日付変換してますね。

覚えとこ。仕様はこんな感じらしい。(Utilities.formatDate

 

直リンクURLの取得

DriveApp.getFileById(item.fileId).getUrl()

最初の方で、GoogleドライブAPI使ってFoldersとFiles取得してたけど、逆にIDから直リンクURL取得するにはこれ使うみたいだ。覚えとこう。

 

Gmailを送る

SEND_MAIL_ADDRESS.forEach(function(o,i) { MailApp.sendEmail(SEND_MAIL_ADDRESS[i],targetFolder.getName() + “更新連絡通知”, “【” + targetFolder.getName() + “】が更新されました。\n\n”+ updateText ); });

MailApp.sendEmailの引数は、順番に「送信先」、「件名」、「本文」になってるみたいだね。

直感的でわかりやすいじゃないの。

 

API便利だなー。。。

Leave a Reply

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