学校法人角川ドワンゴ学園でプログラミング講師をしている @ohataken です。プログラミングの教材を制作したり、生徒からの技術的な質問や相談を解決するのが主な仕事です。とにかく Google Apps Script をよく使っています。
Google Apps Script について
Google Apps Script とは、Google ドキュメントとか Google スプレッドシートなどの資料をプログラミング言語(JavaScript)から読み出したり、書き換えたりすることができる実行環境です。実際に Google Apps Script を書くということはブラウザ上のエディタから JavaScript を書く、ということになります。
さらに「トリガー」という機能があり、たとえば1日に1回とか1時間に1回、関数を実行するように設定しておくことができます。自分でサーバーサイドの開発をする場合であれば cron を動かしたりする必要があるところを、トリガー機能がすでに組み込まれています。ここがとても便利に感じていて、気に入っているところです。
よくある使い方の例として、なにかデータを取得して、整形して、 Google スプレッドシートに書き出す、というのがあると思います。そのケースで便利な関数について、 今年のアドベントカレンダーの7日目に書きました。
ひとつの Google スプレッドシートに、ひとつの Google Apps Script
独自のノウハウとして「ひとつの Google スプレッドシートに、ひとつの Google Apps Script」というルールを設けて運用しています。いうまでもなくシンプルになるので、問題が起きた時の切り分けも易しくなります。また、 Google Apps Script のトリガーには1プロジェクトあたり 20 までという制約があるため、 Google Apps Script は大きいひとつのプロジェクトが頑張って働くよりも、小さいシンプルなプロジェクトがたくさん働くようなイメージのほうが合います。
いくつもの Google Apps Script を管理するための REST API
小さいシンプルな Google Apps Script をたくさん動かすためには、プロジェクトをコピーしたり編集したりする機能が欲しくなります。が「Google Apps Script の内容を書き換える Google Apps Script」というのは、そういう API がないので書けません。この点は、複数の Google ドキュメントやスプレッドシートを書き換えることができるのと対照的に思います。
なので Google Apps Script の枠組みから離れて、 REST API を利用します。最近は Google Apps Script くらいは自分で書ける方も少なからず見受けられますが、 REST API となるとハードルが高まるのではないでしょうか?Webプログラマーとしては、このあたりが面白い
Manage scripts programmatically with the REST API
Google Apps Script の projects.getContent と projects.updateContent を利用して、コードを上書きコピーする
projects.getContent と projects.updateContent という API を使って「元になるプロジェクトの内容を、他のプロジェクトに上書きする」という機能をつくることができます。
私は Ruby を使って実装しました。
service = Google::Apis::ScriptV1::ScriptService.new
service.authorization = credentials # credentials を指定する
content = service.get_project_content(source_id) # source_id はコピー元プロジェクトの ID
service.update_project_content(dest_id, content) # dest_id はコピー先プロジェクトの ID
という感じで、 API クライアントのオブジェクトをそのまま使い回す形で書くことができて、実装が楽でした。
ScriptProperties について
ここまでで、Google Apps Script をコピーするコードを書くことができましたが、もともと実現したかった「ひとつの Google Apps Script につきひとつの Google スプレッドシート」というルールをまっとうするために、スプレッドシートの URL や ID といったマジックナンバーをどう持つか、という問題がでてきます。
Google Apps Script は、 Properties という簡素なデータベースも備えています。(Properties Service
)[https://developers.google.com/apps-script/reference/properties] データベースというよりは、書き換え可能な環境変数というつもりくらいがちょうどいいと思います。
この仕組みをつかって、マジックナンバーをコード外に押しやることができます。
ブラウザ上のエディタから以下のような関数を、関数名を指定して実行することで設定します。
function setProperties() {
const props = PropertiesService.getScriptProperties();
props.setProperties({
"SPREADSHEET_ID" : "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
});
}
この作業だけはいちいち手作業でやらざるを得ず、課題として残っています。REST API から Properties を書き換えできたらいいのに、と思います。