社内向け発表資料をQiitaに投稿。
GAS (Google App Script) とは
GASの特徴
ChatGPTさんに尋ねてみるとこんな事いってきます。
Google App Script(グーグルアプスクリプト)とは、Googleが提供しているプログラミングツールです。
これを使うと、Googleのさまざまなアプリ(たとえば、Gmail、Googleドライブ、Googleスプレッドシートなど)をもっと便利にするためのプログラムを書けるようになります。
- 定期的にスクリプトを実行でき、決まった処理を自動化することができる
- スプレッドシートに格納されたデータを処理することができる
- ウェブブラウザとGoogleのアカウントがあれば簡単に始められる
- 利用は基本的に無料
- Googleのサービスと簡単に連携することができる
GASのデメリット
- 実行時間に制限がある
- スクリプトの実行時間は1回の処理につき最大6分
- 6分を超えたらスクリプトが強制終了される
- スクリプトの実行時間は1回の処理につき最大6分
- JavaScriptベースのプログラミング言語である
- Python等に比べると配列の処理に不便
- デバッグが難しい
- TypeScriptに慣れてると型チェックがない言語で使いづらい
- テストが書けない・書きづらい
- Googleのサービスに依存している
- たまに起こるGoogleサービス停止が発生すると、なんにもできん
- 開発・実行するにはインターネット接続が不可欠
- Git等でコードをバージョン管理できない
google clasp
これらGASのデメリットをちょびっとだけ改善できる Google 謹製のプロジェクト・google clasp(Command Line Apps Script Projects)を使ってみる。
特徴: ローカルの環境で好きなエディタを使ってGASを開発
claspを使うと、Google Apps ScriptのコードをローカルマシンのテキストエディタやIDE(統合開発環境)で編集できるようになる。
これによりVS Codeなどの高度なエディタの機能を活用して、効率的に開発が可能になる。
ローカルの環境でコードは書けるけど、実行環境はあくまでクラウドのGAS側。GASにコードをpushしないと動作の確認ができないので注意。
特徴: 書いたコードをバージョン管理できる
ローカルの環境でコードを保存できるため、Gitなどのバージョン管理システムでコードを管理することもできる。これにより、コードに対して行った変更履歴を追跡可能となる。また、複数人での共同開発や過去の変更の管理も容易になる。
特徴: 既存のGASもローカル環境にインポートできる
既に開発済みのGASもローカルの環境に保存することができる。
特徴: ローカルの環境からデプロイできる
GASの実行環境に対し、pushやデプロイは以下のコマンドを入力するだけ。
$ clasp push
$ clasp deploy -i AKfyAAAvqg
特徴: コード整形、Lint、ユニットテストを外部ツールを使って行うことができる
ESLintなどのコード解析ツールや、Jestなどのテストフレームワークと組み合わせて使用することが可能。
特徴: TypeScriptが使える
claspではTypeScriptで開発ができる。TypeScriptの静的型付けにより、コードの安全性や可読性の向上が期待できる。
ただ、GASの実行環境はTypeScriptがそのまま動かせない。GASのpush・デプロイ時、JavaScriptにトランスエンコードしたものをデプロイすることができる。
claspの開発手順
プロジェクトの初期化
以下のコマンドで初期化。よろずバージョン管理ツール・asdfを利用して nodejs の環境を構築。
$ asdf local nodejs 22.2.0
$ npm i @google/clasp
$ clasp login
https://accounts.google.com/o/oauth2/v2/auth/oauthchooseaccount?access_type=offline&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fscript.deployments%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fscript.projects%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fscript.webapp.deploy%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.file%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fservice.management%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Flogging.read%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform&response_type=code&client_id=xxxxxxxxxxxxx-vm2v2i5dvn0a0d2o4ca36i1vge8cvbn0.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A61078&service=lso&o2v=2&ddm=0&flowName=GeneralOAuthFlow
プロジェクト作成
clasp create
でプロジェクトの作成。ここでは standalone を選択してGASを構築。
$ clasp create calc_sample --rootDir ./src
(node:27646) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
? Create which script? (Use arrow keys)
❯ standalone
docs
sheets
slides
forms
webapp
api
? Create which script? standalone
Created new standalone script: https://script.google.com/d/1bNq6bqZpsYxHaT0_FvADKz0I4iyh5_GLaS9Gt9iu3UFL7bvD76q8ivlW/edit
Warning: files in subfolder are not accounted for unless you set a 'src/.claspignore' file.
Cloned 1 file.
└─ ./src/appsscript.json
このあとできるファイル類。
drwxr-xr-x 10 yusuke staff 320 7 1 20:49 .
drwxr-xr-x 11 yusuke staff 352 7 1 20:36 ..
-rw------- 1 yusuke staff 91 7 1 20:35 .clasp.json
-rw-r--r-- 1 yusuke staff 14 6 30 18:42 .tool-versions
drwxr-xr-x 221 yusuke staff 7072 7 1 20:09 node_modules
-rw-r--r-- 1 yusuke staff 113315 7 1 20:09 package-lock.json
-rw-r--r-- 1 yusuke staff 282 7 1 20:20 package.json
drwxr-xr-x 6 yusuke staff 192 7 1 20:49 src
## src 以下
yusuke@suzuki-m2-Mac-mini calculate_sample % ls -al src
total 32
drwxr-xr-x 6 yusuke staff 192 7 1 20:49 .
drwxr-xr-x 9 yusuke staff 288 7 1 20:57 ..
-rw-r--r-- 1 yusuke staff 119 7 1 20:38 appsscript.json
src/appsscript.json の中身
{
"timeZone": "America/New_York", # > "Asia/Tokyo" に変更
"dependencies": {
},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8"
}
.clasp.json の中身
{"scriptId":"1bNq6bqZpsYxHaT0_FvADKz0I4iyh5_GLaS9Gt9iu3UFL7bvD76q8ivlW","rootDir":"./src"}
GAS 側を開いてみる
このスクリプトが関連しているGASを以下のコマンドで開く。
$ clasp open
まだ何も push してないので、中身は空。
また作成時に指定したのがスタンドアローンスクリプトなので、関連する SpreadSheet も存在してない。
TypeScriptを書いてみる
claspでTypeScriptで開発するには、下準備が必要。
$ npm install --save-dev typescript @types/google-apps-script
added 4 packages, changed 1 package, and audited 279 packages in 2s
86 packages are looking for funding
run `npm fund` for details
tsconfig.jsonは特に要らない。
TypeScriptのコードを書いてみる。srcディレクトリに Main.tsを作る。
src/Main.ts
// Main.ts
function add(a: number, b: number): number {
return a + b;
}
function subtract(a: number, b: number): number {
return a - b;
}
function logMessage(message: string): void {
Logger.log(message);
}
function main() {
const resultAdd = add(5, 3);
const resultSubtract = subtract(5, 3);
logMessage(`Addition Result: ${resultAdd}`);
logMessage(`Subtraction Result: ${resultSubtract}`);
}
TypeScriptをGASにpushしてみる
package.jsonをこんな感じに変更する。
package.json
{
"name": "clasp-calculate-sample",
"version": "1.0.0",
"dependencies": {
"@google/clasp": "^2.4.2"
},
"devDependencies": {
"@types/google-apps-script": "^1.0.83",
"typescript": "^5.5.2"
}
}
clasp をpushすることで、claspが自動的にTypeScriptをGASにトランスコンパイルしてから、GASの実行環境に転送してくれる。
$ clasp push
(Use `node --trace-deprecation ...` to show where the warning was created)
└─ src/appsscript.json
└─ src/Main.ts
Pushed 2 files.
TypeScriptがトランスコンパイルされ、変換されたGASのコードはこんな感じ。
// Compiled using clasp-calculate-sample 1.0.0 (TypeScript 4.9.5)
// Main.ts
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
function logMessage(message) {
Logger.log(message);
}
function main() {
var resultAdd = add(5, 3);
var resultSubtract = subtract(5, 3);
logMessage("Addition Result: ".concat(resultAdd));
logMessage("Subtraction Result: ".concat(resultSubtract));
}
main関数を実行してみる。
claspの欠点
ここまでの説明にて、一見便利に見える clasp だけども、いくつかの欠点も存在する。
TypeScriptのコード分割記法 import 構文が機能しない
- 機能するようにするには webpack を使うなど、いくつか方法がある
- が、package.json を変更・定義するのがめんどくさい
TypeScriptの型チェックがデプロイ時に機能するわけではない。
例えば add 関数の引数に文字列を設定した場合、TypeScriptのチェックが入るテキストエディタでは型チェックが入り、引数の型が間違ってるよーと怒られる。
が、エディタで警告されたからといって、clasp push によるデプロイが失敗するわけではない。なので、push後、に反映されたGASを実行すると、普通に文字列の足し算が実行されちゃうという悲しみ。
コード整形、lint、ユニットテスト等の環境を自分で用意する必要がある
ファイル構成が自由であるが故、開発者それぞれで設定のやり方が異なり、こうすべきであるといった決まったやり方が定まっていない。
これらのデメリットを改善する方法は一応用意されてるが、後編にて。
まとめ
- 素のGASを書くのは色々とツライ。が、claspを使うとメリットが色々享受できる
- claspは便利。だが自由度が高すぎて環境整えるのが大変
以上