TypeScript で Google Apps Script を書く環境を整備する
無料で自動化環境を整備できることで有名な Google Apps Script ですが、以前はブラウザで JavaScript を用いて開発する必要があったため辛い部分もありました(人による)。
現在は公式からローカル開発をするための公式 CLI ツールが提供されているので、静的型付けの恩恵を受けるべく TypeScript を用いて開発できるようにしてみました。
公式の CLI ツール
- G Suite Developers Blog: Advanced Development Process with Apps Script
- danthareja/node-google-apps-script: The easiest way to develop Google Apps Script projects
インストール自体は Node.js が入っている環境であれば npm install
で入れられます。
npm install -g node-google-apps-script
初期設定として認証キーの発行などが必要です。GitHub の README.md に全て載っていますが、日本語情報ですと以下のブログが詳しかったのでご参照ください。
Google Apps Script の開発をモダンに行う方法 - Speee DEVELOPER BLOG
ディレクトリ構成
dev/
node_modules/
src/
.gitignore
gapps.config.json
package.json
README.md
tsconfig.json
こんな感じです。 CLI がデフォルトで src/
ディレクトリのものをアップロードするため、 dev/
を開発用のディレクトリとし、コンパイルした生成ファイルを src/
に置くようにします。( gapps.config.json
で設定できそうなので気持ち悪ければ変更すればよさそうですね。)
ローカル開発なので Git でバージョン管理できるの最高ですね!テストは今回は省略しています。
node_modules
TypeScript で開発するために Google Apps Script 用の型定義ファイルを取得します。
npm install --save-dev @types/google-apps-script
TypeScript 2.0 から tsd や typings は不要になったようですね。
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"outDir": "./src",
"rootDir": "./dev",
"alwaysStrict": true,
"inlineSourceMap": true,
"noEmitOnError": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"pretty": true,
"strictNullChecks": true
}
}
オプションは適当です。開発用ディレクトリを dev/
、出力ディレクトリを src/
としたのでそれぞれ設定しています。
これで tsc
とコンパイルを実行すれば src/
ディレクトリに js ファイルが出力されるので、 Google Apps Script にアップロードすれば OK です。
npm scripts
そんなに複雑なコマンドは使いませんが、 npm scripts 化しておきます。
package.json に以下を定義。
"scripts": {
"publish": "npm run build && npm run upload",
"build": "npm run tsc",
"tsc": "tsc",
"upload": "gapps upload"
},
これで簡単にコンパイルとアップロードができます。
npm run publish
サンプル
サンプルとして POST リクエストでカレンダーの予定を作成するスクリプトを作ってみました。 Google Apps Script 独自の Service などは型定義ファイルに global 定義されているのでそのまま使えます。
const calendarId = 'sample@group.calendar.google.com'; // replace to your calendar id
class PostEvent {
queryString: string;
parameter: { [index: string]: string; };
parameters: { [index: string]: [string]; };
contentLenth: number;
postData: {
length: number;
type: string;
contents: string;
name: string;
};
}
function _test() {
let e = new PostEvent;
e.postData = {
length: 0,
type: "",
contents: '{"title":"sample title", "startTime": "2017-03-19T09:00:00.000Z", "endTime": "2017-03-19T12:00:00.000Z"}',
name: ""
};
doPost(e);
}
class CalendarEvent{
title: string;
startTime: Date;
endTime: Date;
}
function doPost(e: PostEvent):GoogleAppsScript.Content.TextOutput {
let calendarEvent = new CalendarEvent;
let contents = JSON.parse(e.postData.contents)
calendarEvent.title = contents.title
calendarEvent.startTime = new Date(contents.startTime)
calendarEvent.endTime = new Date(contents.endTime)
let result = JSON.stringify(calendarEvent);
return ContentService.createTextOutput(result);
}
function createEvent(e: CalendarEvent) {
CalendarApp.getCalendarById(calendarId).createEvent(
e.title,
e.startTime,
e.endTime,
)
}
以上
以前は Logger.log
などで頑張ってデバッグしていたのですが、コンパイル時点でタイプミスなどを検知できてとても管理しやすいです。
Google Apps Script は業務効率化と非常に相性がいい反面、管理が属人化しがちなのが悩みだったのですが、 ローカル開発によって Git 管理やテストが可能になるだけでなく、 TypeScript で静的型付けの恩恵まで受けられるようになったので更に便利になりました。
SpreadSheet や手動スクレイピング芸などで疲弊している方々はたくさんいると思いますので、ちょろっとスクリプトを書いて自動化できるところはガンガンやっていきたい所存です。
今回のサンプルは GitHub に置いてあるので、雛形としてお使いください。