GAS のGoogle製CLIツール clasp


Google Apps Scriptというと以前はWebのエディター上でしかコードを書けなかった。
手に馴染んだエディタが使えないし、バージョン管理はしにくかった。

Googleからclaspが登場し開発環境は大幅に改善された。

  • 利用バージョン: clasp v1.1.5

インストール

npm コマンドでインストールできる。

npm i @google/clasp -g

npm i clasp でインストールすると以前は別モノがインストールされたが、今は An alias for @google/claspと書かれており単にclasp のみでも良さそう。

ログイン

Webエディタ側から取るにも、Webエディタ側にアップするにもユーザ認証が必要ということで、まずはログインする必要がある。

clasp loginコマンドでログインできる。
実行すると次の様にメッセージが表示され、同時にブラウザが立ち上がる。

$ clasp login
🔑  Authorize clasp by visiting this url:
https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&scope=https%3A%2F%...(長いので略)

ブラウザで開いたページでは次の許可を求めてくる1

許可するとログイン完了。次のメッセージが表示される。

Saved the credentials to ~/.clasprc.json. You may close the page.

ログイン情報は~/.clasprc.jsonに書き込まれるようだ。

ログアウト

次のコマンドでログアウトして、再度利用するには再ログインが必要とドキュメントには書いているが、実行してもログアウトが不十分な感じ。
再ログインが出来なかった。

clasp logout

新規スクリプトの作成

gappsコマンドではすでに存在するスクリプトから取得する必要があったが、claspでは新規に作ることもできる。
clasp createコマンドで sample というスクリプトを作ってみる。

$ clasp create sample
Created new script: https://script.google.com/d/1y4QuWA-C8UhyRi7sl1kVTuauhJGQ9U0EzISiQPfixxxxxxxxxxxxxxxx/edit
Cloned 1 file.
└─ appsscript.json

示されたURLにアクセスすると、見慣れたWebのスクリプトエディタが開き確かにできている。自分でURLをコピペしなくても、次のコマンドで開くことができる。

clasp open

Webエディタの方には空関数myFunctionが書かれたCode.gsファイルが作られている。
一方、ローカルのディレクトリには次の2つのファイルが新たに作成される。

  • .clasp.json
  • appsscript.json

ファイルの中はそれぞれ次の通り。

.clasp.json
{"scriptId":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}
appsscript.json
{
  "timeZone": "America/New_York",
  "dependencies": {
  },
  "exceptionLogging": "STACKDRIVER"
}

Google Apps Script APIの有効化

これまで、Google Apps Script APIを使ったことがなければ、clasp create等のコマンド実行で次の様にエラーが発生する。

$ clasp create sample
Error: Permission denied. Enable the Apps Script API:
https://script.google.com/home/usersettings

ログインの時にした許可は何だったんだろうと思いながら、指示通り https://script.google.com/home/usersettings にアクセスしてみると次のページが表示される。

Google Apps Script API が「オフ」となっている。これを「オン」にすれば良い。
クリックして「オン」にする。

その後はコマンドが実行できるようになる。

スクリプトのpull

さて、clasp createしただけではWebエディタ側に作成されたCode.gsファイルもローカルに取ってこれていない状態なので、これを pullしてみる。

clasp pullコマンドを実行する。

$ clasp pull
Cloned 2 files.
└─ Code.js
└─ appsscript.json

メッセージによれば、2つのファイルをpullしたようだ。
appsscript.jsonファイルは clasp createした時点であったので、Code.js が増えたことになる。
Webエディタで作成されていた Code.gsの拡張子が.jsに書き換えられて取れている。

スクリプトのpush

Code.jsを次のように書いてpushしてみてる。

Code.js
function myFunction() {
  Logger.log('Hello World');
}

clasp pushコマンドでpushできる。
ただ、このコマンド、カレントディレクトリにある全てファイルをpushしようとするらしい。
GASのコードをローカルで編集する動機としては、gitでバージョン管理をしたり、babelでトランスパイルしたいというものがあると思う。
そうすると、ディレクトリ内には .gitディレクトリや.gitignorenode_modulesディレクトリがあると思う。それらは GASのコードとして有効ではないのでエラーとなるようだ。
push対象のファイルからこれらを除外するために .claspignoreがある。
これに次の様に書いておけば、カレントディレクトリの *.jsファイルと、appsscript.json がpushの対象となる。

.claspignore
**/**
!*.js
!appsscript.json

で、clasp pushを実行すると、次の様に2ファイルがpushされ、書き換えたCode.jsもWebエディタ側に反映されている。

$ clasp push
└─ Code.js
└─ appsscript.json
Pushed 2 files.

このpush、gapps pushコマンド同様、ローカルのファイル構成で完全に上書きしてしまう。つまり、Webエディタ側のみにあるファイルは削除してしまうので注意が必要だ。

ディレクトリ構成

そこそこの量のコードを書くと、ファイルやディレクトリを分割したくなると思う。
例えば、srcディレクトリにコードを配置する場合、.claspignoreを次の様に書いてやると、src以下の*.jsファイルがpush対象となる。

.claspignore
**/**
!src/*.js
!appsscript.json

ローカルに次のファイルがある状態で、pushすると

./
├── appsscript.json
└── src
    └── Code.js

上記の Code.jssrc/Code.gsという名前となる。
(GASのファイル名って/使っていいんだ!と軽く驚いた。)

これをpullしてもちゃんと ./src以下にCode.jsが配置されるし、Webエディタ側で src/index.gsというファイルを作成して、pullしても、./src以下にindex.jsファイルができる。

.clasp.json ファイルのrootDir

.claspignoreファイルで、push対象を絞り込んでも良いが、.clasp.json ファイルにrootDirを指定しておくのも便利。

次のようにrootDirを追加すると、pullもpushもこの ./sources以下で行われるようになる。

.clasp.json
{"scriptId":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
 "rootDir": "sources"}

こんな感じ。

sources/
├── appsscript.json
└── src
    └── Code.js

webpack等でビルドする場合、ビルド成果物の出力先ディレクトリを指定しておくと良いと思う。

バージョン管理

GASではスクリプトにバージョンを付けて管理できるが、それも claspコマンドでできるようになっている。

clasp versionでバージョンを作成できる。
次の様に実行する。

$ clasp version '最初のバージョン'
Created version 1.

すると、次のようにできている。

バージョンを確認するにはclasp versionsを実行する。

$ clasp versions
~ 1 Version ~
1 - 最初のバージョン

既存のスクリプトからのクローン

これまで新規スクリプトを作成する流れで書いてきたが、もちろん既存のスクリプトの管理をclaspを使って始めることもできる。

clasp createの代わりにclasp cloneを利用すると既存のGASスクリプトのコードをappsscript.jsonを含めローカルにクローンすることができ、同時に .clasp.jsonも作成される。

$ clasp clone xxxSCRIPT-IDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Cloned 2 files.
└─ code.js
└─ appsscript.json

srcフォルダなど、ローカルのカレントディレクトリ以外にコードを配置したい場合は、次の手順でpullし直せばよい。

  1. 最初にっクローンしたファイルを削除する
  2. .clasp.jsonrootDir設定を追加する
  3. clasp pullを実行

ドキュメントに紐付いたスクリプトも管理可能

clasp cloneで特筆すべきなのは、GASとして独立しているスクリプトをクローンできるのはもちろん、スプレッドシートなどのスクリプトエディタで作成したドキュメントに紐付いているスクリプトもクローンできることである。
gappsコマンドではできないことだったので、これだけでも導入の価値があると思う。

clasp createのところで説明しなかったが、新規にスクリプトを作成する場合もスプレッドシート等に紐づくスクリプトとして作成できる
その場合にはスクリプト名に加えて、親となるドキュメントのIDを指定する。

$ clasp create MyScript xxxxxGOOGLEーDOCS-IDxxxxxxxxxxx
Created new script: https://script.google.com/d/xxxxxxxxxxxxxxxxxxxxxxxxxxxx/edit
Cloned 1 file.
└─ appsscript.json

Typescript

v1.5からはなんとTypescriptをサポートした。

詳しくはこちら

その他

GASのスクリプトはWebアプリとして公開できるたりするのだが、その操作もできるようだ。
ただ、自分としてはあまり使っていない機能なので、使うようになったら書こうと思う。

まとめ

  • gapps(node-google-apps-script)はディスコン。今後は claspを使おう。
  • 使い始めるまでのGoogle上の設定も claspのほうが簡単。
  • 新規のスクリプトの作成もCLIでできちゃう
  • ドキュメントに紐づくスクリプトもようやくローカル開発しやすくなった。

参考資料


  1. ブラウザのないサーバ等で実行した場合には表示されるURLをコピーしてローカルマシンのブラウザで表示すれば良いと思われる。