はじめに
Google Apps Script (GAS) は Web ブラウザ上の JavaScript とも Node.js とも環境が異なります。その違いや、 GAS 特有の機能を理解するとさらに開発が捗るので、それらをこの記事で紹介しようと思います。
Tokyo GAS で 5 分 LT した内容です。
スライドはこちら > GAS ビギナーが GAS を使いこな すために知るべきこと 10 選
※より網羅的で最新の情報を得たい方は DevFest 2020 の登壇動画 Google Apps Script 入門 2020 をご覧ください。
1. ローカル環境で開発する
GAS を好きなエディタで開発したり、ローカルで開発したものを github に上げたりしたくなる。
Google ブログの記事 Apps Script による高度な開発プロセス で紹介されているが、 node-google-apps-script という npm パッケージをローカル環境にグローバルインストールことで、ローカルで開発したものを GAS に push することができる。
// clone
$ gapps clone <scriptId>
// push
$ gapps push
clasp というライブラリだと push だけでなく pull もできたり、コマンドも豊富なので、 clasp の方が良さげ。
// clone
$ clasp clone <scriptId>
// push
$ clasp push
// pull
$ clasp pull
2. github でソースコードを管理する
- の方法でローカルで開発する場合は、その状態を github と連携してソースコード管理すれば良い。もう一つの方法としては、 Google Apps Script Github アシスタント という Chrome Extension があるので、これを使えば、 github に push / pull することができる。
3. 複数の *.gs 間で関数を呼び出す
GAS では複数の *.gs ファイルを持つことができる。これらの関数はグローバル関数となるので、そのまま他のファイルで呼び出すことができる。以下のように書くと util.gs の add 関数は正常に呼び出せる。
function main() {
var num = add(1, 2);
Logger.log(num);
}
function add(a, b) {
return a + b;
}
グローバル関数となるので、複数ファイルで同一の名前の関数名をつけてはならない。
4. 様々な実行方法
GAS では、主に以下の実行方法から選択する。
- トリガー
- G Suite アプリケーションの特定のイベントをハンドリング
- Web 公開
トリガー
毎週月曜の朝に実行するような場合はトリガーを利用する。 Heroku でいう Scheduler みたいなもの。タイマー(分/時/日/週/月)を利用して、実行タイミングを細かく指定できる。編集
> 現在のプロジェクトのトリガー
から設定する。
トリガーの例: Google Apps Script (GAS) で毎週 30 分の雑務を自動化した話
G Suite アプリケーションの特定のイベントをハンドリング
- 特定の Docs を開いた時
- スプレッドシートの更新時
- Google フォームの回答時
など、様々なタイミングで実行することができる。公式の Event Objects
で補足できるイベントと、イベント発火時に渡される値を知ることができる。
Web 公開
公開
> ウェブアプリケーションとして導入
を選択すると、公開することができる。簡単な API を作って公開することができ、これはかなり強力。
公式の Web Apps の通り、GET の場合は doGet 関数、 POST の場合は doPost 関数を実装する必要がある。ミニマムな GET, POST API 実装を以下に記述する。
function doGet(e) {
return ContentService.createTextOutput("hello world!");
}
function doPost(e) {
return ContentService.createTextOutput("OK");
}
返り値は TextOutput か HtmlOutput のいずれかである必要がある。 HtmlService と絡めると、 html を公開できるので、簡単な Web アプリケーションを提供することも可能。
Web 公開の例: 3 分で作る無料の翻訳 API with Google Apps Script
5. スクリプト毎のデータストアがある
前回の実行結果など、スクリプト毎に簡単なデータを保存する保存領域が用意されている
。公式ドキュメントはこちら Class PropertiesService | Apps Script 。
以下のように呼び出せる。
var properties = PropertiesService.getScriptProperties();
properties.getProperty(key);// 取得
properties.setProperty(key, value);// 設定
properties.deleteProperty(key);// 削除
これで、スクリプトの途中結果を保存して、次の実行時に利用する値を参照できる。
6. スクリプトからトリガーをセットできる
TriggerBuilder を使ってスクリプトからもトリガーを設定できる。以下のコードは、 1 分後
に main
という名前の関数を実行するトリガーを登録している。
var functionName = 'main';
var d = new Date();
d.setMinutes(d.getMinutes() + 1);// 1 分後
ScriptApp.newTrigger(functionName).timeBased().at(d).create();
7. 実行時間の制限と対策
1 回の実行で 6 分間の時間制限があり、スクリプトの実行途中でも強制的に終了する。 6 分を超える場合には以下のような対策が取れる。
例として、スプレッドシートに対して各行処理するスクリプトだとすると
- 実行時間が 5 分になるのを検知
- 次回処理を開始する行数を PropertiesService で保存
- TriggerBuilder を使って新しいトリガーを 1 分後に設定
- 処理を終了させる
これは、上の 5, 6 で紹介した Tips を用いた方法。 5 分や 1 分という値は仮なので、よさげな値を使ってください。
その他の制限は公式ガイドの Quotas を参照。
8. G Suite 以外のサービスの API をたたく
GAS は G Suite のアプリケーションを簡単に操作できるが、UrlFetchApp を使って外部サービスとの連携も簡単にできる。
例として Slack にメッセージ投稿するコードを以下に示す。
function postSlack(slackWebhookUrl) {
var body = { text: 'message' };
var payload = JSON.stringify(body);
var res = UrlFetchApp.fetch(slackWebhookUrl, {
method: 'POST',
headers: { "Content-Type": 'application/json' },
payload: payload
});
}
9. Web スクレイピングの方法
GAS における Web スクレイピングは以下の流れで行う
- UrlFetchApp.fetch で html を取得
- html を parse
1 は直前で紹介したので省略する。 2 については、 GAS 公式の Parsing HTML で紹介された方法で Web ブラウザ上の JavaScript のような HTML のパースができるが、 XmlService を使っているため、エラーになる場合も多い。
2022年9月時点では cheerio を Google Apps Script 上で動作するようにライブラリ化された tani/cheeriogs を利用するのが良い選択肢だと思われる。
tani/cheeriogs の README の通りライブラリ読み込みを行った上で以下のようにパースできる。
// TODO: 別途ライブラリの読み込みが必要
const content = UrlFetchApp.fetch('https://en.wikipedia.org').getContentText()
const $ = Cheerio.load(content)
Logger.log($('#mp-right').text())
ちなみに、スクレイピングのマナーとして 1 秒間に 1 回しかアクセスしない
というものがあるが、 GAS で sleep するには、 Utilities クラスの sleep を呼び出す。そもそもクローリング拒否してるかどうかは robots.txt を見て判断する。
Utilities.sleep(1000);
Utilities は GAS に適した便利関数群が用意されているので、一度眺めてみるのを勧める。
10. GAS ライブラリの仕組み
GAS で npm モジュールを使えれば非常に便利なのだが、普通に npm install しても動作しない。ローカルでコンパイルするといける方法はあるそうなので、後日調べたら記事化します
代わりに GAS にはライブラリという仕組みがあり、他の人が作った GAS ライブラリを呼び出したり、自分の GAS を登録することができる。詳しくは公式の Libraries に書かれている。
まとめ
ここ数ヶ月で GAS を始めて、調べていて有益だと思った情報をまとめました。私もまだまだ勉強中なので、またネタを仕入れたら記事書きます。