Google Apps ScriptをローカルPCで開発する方法【GAS】
Google Apps Scriptは着実に機能を増強しているとはいえ、開発画面はあの「スクリプトエディタ」画面が基本です。とはいえ、GASで巨大システムなど作ることもないので、十分と言えば十分。しかし、チームで開発を行ったりする場合には面倒というのも事実。
そこでGoogleが2018年1月に出してきたツールが「clasp」というNode.jsで動作する、ローカルPCでGoogle Apps Scriptを好きなエディタで開発し、簡単にデプロイが出来る便利なツールです。それまでのnode-google-apps-scriptを廃止し、様々な追加機能を持って現在、一部の開発者の間で使われています。今回はこのツールで、実際に開発をしてみたいと思います。
※ちょっと不穏なのが2022年9月の最終リリースからメンテが止まっています・・・
今回使用するライブラリやファイル等
- Node.js - claspはNode.js上で動作するので事前にインストールが必要です。
- clasp - 今回の主役ライブラリ。これを入れないと始まらない。公式イントロダクションはこちらのサイト。
オプション項目として、v1.5からTypescriptでの開発が可能になっています。その場合以下のライブラリなども入れておくと良いでしょう。
- Visual Studio Code - 現在ローカルでGASの入力補完が使えるElectron製のコードエディタ
- typescript - Google Apps ScriptをTypescriptで開発したい人は入れるライブラリ。tslintライブラリも必要。
- @types/google-apps-script - 上記同様、Google Apps ScriptでTypescriptを使う場合に必要(コード補完の為)。
事前準備
今回はいつものmacOS上で環境を構築しますが、基本どのOSであってもインストール自体は難しくありません。macOSの場合、コマンドラインでのインストール(homebrewを使った手法)もありますが、ここでは手軽に、インストールパッケージを利用します。以下の手順でパッケーを入手しダウンロードしましょう。また、Node.jsで利用する、今回使う予定のモジュールもインストールしておきましょう。
Node.jsをインストールする
claspのインストール
まずはともあれ、Node.jsがインストール完了したら、clasp本体をインストールします。sudoで実行する点に注意が必要です。
1 |
sudo npm install @google/clasp -g |
図:あっという間にインストール完了
claspでGoogleにログイン
claspのインストールが完了したらターミナルからログイン認証を行います。以下のコマンドを入力すると、いつものGoogleアカウントの認証画面が出るので、ログインしましょう。ログインが完了すると、.clasprc.jsonというファイルが自分のユーザフォルダ直下(/Users/ユーザ名/.clasprc.json)作成されます。macOSの場合、nodeへの受信許可の可否を問う画面が出ますので、許可してあげましょう(でないと通信が出来ません)。
Logged in! You may close this page.とメッセージがでたら閉じます。ちなみに、clasp logoutとするとファイルは削除され、認証も消えます。ログインするアカウントを間違えないように!!
1 |
clasp login |
図:clasp login後のターミナルの様子
図:nodeへ通信許可を与えます。
図:いつもの認証画面。許可を与えましょう。
Google Apps Script APIを有効にする
Google Apps Script APIと言っても、Cloud ConsoleにあるApps Script APIではありません。G Suite Developer Hubにあるセッティング項目で、ここにあるスイッチをオンにするだけです。これを行わないと、claspからGASへアクセスが出来ません。
図:スイッチをオンにするだけです。
claspを実際に使ってみる
claspはこれまでもあったローカルでGASを開発するツールとは異なり、GAS単体ファイル(standalone script)だけではなく、Google SpreadsheetやDocumentに紐ついているスクリプトも操作可能になっています。かつては、Eclipse用Pluginなども出していましたが、廃止になってしまいました(standaloneしか弄れない使えないプラグインでした)。
主に、新規作成(既存データ読み込み)、コードアップロード、デプロイが主な機能になります。createやcloneを実行すると、プロジェクトフォルダ以下に.clasp.json(macOSだとデフォルトだと非表示)というファイルが出来ており、Nested clasp projects are not supported.というエラー発生時には一回このファイルを削除してから、再チャレンジしましょう。このファイルには、スクリプトIDが書き込まれています。
コードを作成する
新規作成をする
ほとんどの場合、Google Apps Scriptを使うのはスプレッドシート上になるでしょう。スプレッドシートと共にプロジェクトをローカルPCに作成します。ただし、通常スプレッドシートを使う場合、設定項目やテーブルなどをスプレッドシートにある程度作り込んでからの作業になるので、次項のコードを持ってくるほうが利用頻度は高いと思います。
- ユーザのドキュメントフォルダ以下にプロジェクトフォルダを作っておく(/Users/ユーザ名/Documents/projectfolder)
- ターミナルを起動し、プロジェクトフォルダまで進む
- 以下のコマンドで新規作成する
- 途中、選択画面が出ますが、sheetsを選んでEnterキーを押すと作成開始
- 完了すると、プロジェクトフォルダには、「appsscript.json」だけが作成され、create new google sheetsの表記と共にURLが表示されます(ファイルはGoogle Drive直下にClaspというファイル名で作成されます。)。
- appsscript.jsonの中のTimezoneがUSになってるので、Asia/Tokyoに書き直しておきましょう。
1 |
clasp create プロジェクト名 --type sheets |
図:中身が空のスプレッドシートと紐ついたappsscript.jsonが作られる
図:ドライブ直下に作られるので、移動が必要ですね。
1 2 3 4 5 6 7 |
//appsscript.jsonの中身はこれだけ・・・ { "timeZone": "America/New_York", "dependencies": { }, "exceptionLogging": "STACKDRIVER" } |
コード:中身はこざっぱり。TimezoneがAmericaになっとる・・・
既存のコードを持ってくる
一番利用する方法はこちらの「既存のファイルから持ってくる」方法でしょう。今回はまだ未公開ですが、すでに5年前から開発を続けて実際に利用している「物品購入修理伺いフォーム(改」のコード類をクローンしてみたいと思います。スクリプトID単位となるため、1つのファイルに複数プロジェクトを作り込んでる場合、それぞれのプロジェクトのID分だけ作業が必要になります。
- スクリプトエディタ画面に入る
- ファイル⇒プロジェクトのプロパティを開き、スクリプトIDをコピーしておく
- 事前にプロジェクトフォルダを作っておく
- ターミナルを起動し、プロジェクトフォルダまで進む。
- 以下のコマンドでプロジェクトをクローンします。
1 |
clasp clone コピーしたスクリプトID |
図:スクリプトIDが重要なキーです
図:14個ものファイルがダウンロードされました。
図:Finderでファイルを確認してみる
1 2 3 4 5 6 7 8 9 10 11 |
{ "timeZone": "Asia/Tokyo", "dependencies": { "libraries": [{ "userSymbol": "ここにはライブラリ使用時の識別子が記述されている", "libraryId": "ここには使用してるライブラリのIDが記述されている", "version": "1" }] }, "exceptionLogging": "STACKDRIVER" } |
図:ダウンロードしたappsscript.jsonには色々書かれてる
V8 Runtime対応する
2020年2月6日、ついにGoogle Apps ScriptがV8 Runtime対応して大幅なバージョンアップを遂げました。この恩恵はclaspでも使えるようになっています。
手順としては以下の通り。
- clasp createで新しいプロジェクトを作成する
- 生成されたappscript.jsonを編集する
- 以下のようにコードに追記する
- typescriptで書く場合には、tsconfig.jsonも書き換える
1 2 3 4 5 6 7 |
{ "timeZone": "Asia/Tokyo", "dependencies": { }, "exceptionLogging": "STACKDRIVER", "runtimeVersion": "V8" } |
コード:appscript.jsonの場合
1 2 3 4 5 |
{ "compilerOptions": { "target": "ES2019" } } |
コード:tsconfig.jsonの場合
基本、スクリプトエディターの時と変わらないですね。
コードをアップロードする
コードプッシュ
ダウンロードされたコードは、.jsファイルが「Google Apps Script」のファイル。htmlがウェブアプリケーションのHTMLやCSS、JavaScriptを格納するファイルです。本来GASは拡張子はgsなのですが、clasp経由ではjsファイルになるようですね。また、cssといった拡張子のファイルはサポートされていないので、これらやHTML側のjs類はhtmlファイルに格納しましょう。
編集を行ったら、アップロードしなければなりません。以下の手順でコードを反映させます。
- ターミナルを起動し、プロジェクトフォルダまで進む
- 以下のコードを実行する
- 全ファイルがアップロードされ、反映される
- jsではなくTypescriptのtsファイルの場合、自動でトランスパイルされてアップロードされます。
1 |
clasp push |
これだけです。非常に簡単ですね。ちなみにすぐにデバッグ作業などを行いたい場合は、続けて、clasp openと実行するとスクリプトエディタ画面へ直行出来ます。コードが反映されているか確認ができますよ。あらかじめテンプレを自分で用意しておくと、書き始めがとても楽に済みます。その場合は
- 一旦空のスプレッドシートを作っておく
- clasp cloneでダウンロードしておく
- プロジェクトフォルダにテンプレファイル群を放り込む
- clasp pushでプロジェクトにファイル群を反映させる
これでスタート開始が楽になります。
Webアプリケーションをデプロイ
Google Apps Scriptを使う一番の目的は実はウェブアプリケーションの開発にあると思ってます。VBA的にスプレッドシートやCalenderに登録も確かに重要なのですが、ウェブアプリが作れるからこそこの言語は美味しい。スプレッドシートを使うのもデータの保存や設定値を作り込んだりが出来る良い土台だから。
ということで、claspからもウェブアプリケーションのデプロイが出来るようになっています。以下の手順でウェブアプリケーションを公開しましょう。コマンドラインでデプロイまで出来ると、色々自動化ができそうですね。
- ターミナルでプロジェクトフォルダまで進む
- 以下のコマンドでバージョン指定、説明文を入れて実行するとデプロイされます。
- 当然ですが、ファイルのオーナーでないとこの処理は出来ません。
1 |
clasp deploy バージョン名 説明文 |
The caller does not have permissionと出ることがあります。これは事前に実行承認をしていない場合に出ます。一度適当に実行しておいて、承認をしてからdeployしましょう。また、再度デプロイする場合には、clasp deploymentsで現在デプロイされているIDのリストを確認し、clasp deploy --versionNumber 3とすると、version3として新規デプロイが実行されます。
また、ウェブアプリケーションを開く場合には、clasp open --webappにて開く事が可能(ただし、今現在、Missing required parameters: scriptIdというエラーが何故か出て開かないので手動で開いてます・・・・openだけだとスクリプトエディタは開くのに・・・まだまだ新機能の申請やissueが報告されているので、今後に期待です)。
図:コマンドでデプロイ出来てしまうのは便利
図:無事にウェブアプリにアクセスできた
バージョン管理
スクリプトの版管理は重要です。コードの復元は変更履歴からできますが、完成品としての版を管理しておかないと、色々面倒なことがあります。そこで、版を管理しているわけですが、これもclaspから可能です。手抜きで版管理をしてると、v1は何をどうしたのかさっぱりわからないことになるので、丁寧に説明文を入れたいものですね。
- clasp versionsで現在の版すべての一覧を取得できます。
- clasp version バージョン 説明文にて新しい版を保存できます。
図:きちんと説明文を入れないと何の版なのかさっぱり・・・
フォルダ構造
Google Apps Scriptのエディタはファイル類に関してフォルダ構造をサポートしていません。全てのファイルが1つの平面に並べられてる状態です。しかし、pushする場合にフォルダで管理したいという要望もあると思います。実際にやってみましょう。するとスクリプトエディタ画面上で、対象のファイルのファイル名に変化が起きます。
1 |
フォルダ名/ファイル名 |
こんな感じに。例えば、srcというフォルダの中にtestman.jsというファイルという構造にすると、スクリプトエディタ上では「src/testman.gs」という表記になります。もちろん、スクリプトエディタ上でこの表記にしてダウンロードすると、フォルダ構造が復元される仕組みになっています。この方法は、Google Apps Script Github アシスタントでも見たものですね。
ですので、ローカルでフォルダ管理を行って問題なく開発は進められます。ローカルに保存されてるわけですから、そのままGithub上でバージョン管理も可能になるので、claspは複数開発者の場合便利ですね。
アップロードするファイルを制限する
基本全てダウンロード、全てをアップロードするのがclaspですが、同じフォルダ内に入れておきたいファイル類などがあったりするケースではこのままだと未対応のファイルということで、エラーが出てしまいます。そこで、アップロードするファイルを制限する手段が.claspignoreファイルです。
macOSだとドットファイルは標準では見えないので、以下のコマンドで見えるようにしておくと良いでしょう。または、Shift + Command + .キーで切り替えが可能です。
1 2 |
defaults write com.apple.finder AppleShowAllFiles TRUE killall Finder |
さて、.claspignoreファイルですが、プロジェクトフォルダ内に入れておくと、clasp pushした時に記載されているファイルだけをpushするようになります。index.jsとappsscript.jsonのみをアップしたいならば
1 2 3 |
**/** !index.js !appsscript.json |
と記載して保存するだけ。ワイルドカードが使えるので、!*.jsと記載するとjsファイルはすべてアップロード対象になります。注意しなければならないのは、ここに記載したファイルを上書きするだけじゃなく、未記載のファイルがスクリプトエディタ側にあった場合「削除される」点です。アップしたら消えちゃった・・・なんてならないように、バックアップは取っておきましょう。
また、ディレクトリ構造を意識してアップを制限するならば、!src/*.jsと記述するとsrcディレクトリ以下のjsファイル全てという意味になるので、管理が楽になります。
claspでスクリプトを実行する
claspはGoogle Apps Scriptのソースコードをダウンロードしたりプッシュするだけではなく、遠隔で実行する事が可能です。返り値を持つ関数であれば、ターミナル内に帰ってきます。また、Stackdriver Loggingを利用していればCloud Console上でデバッグ作業が可能です。
しかし、このコマンドは利用するためには事前準備が必要です。また、Cloud ConsoleよりApps Script APIを有効にしなければならないので、以下の事前準備をしないと、Could not read API credentials. Are you logged in locally?というエラーが出て実行出来ません。導入準備のreadmeはこちら。
事前準備
プロジェクトを移動
Apps Script APIを有効化する
ここまでで、creds.jsonとProject ID、OAuthスコープが手に入りましたので、一旦スクリプトエディタは閉じておきます。
※ターミナルからclasp open --credsで直接対象のプロジェクトのページに飛んで作業も可能です。
実行可能APIとして導入する
creds.jsonでログインする
一旦現在のプロジェクトファイルは捨てて、新しくclasp cloneするかclasp pullしておきましょう。すると、appsscript.jsonにはexecutionApiの項目が追加されているのがわかります。もし、追加されずにアクセスが出来ない場合にはappscript.jsonに手動で以下のように追加すると良いでしょう。
1 2 3 |
"executionApi":{ "access":"ANYONE" } |
この行を追加しclasp pushすると良いです。
この状態で以下の作業を行います。
- プロジェクトフォルダにcreds.jsonを入れておく
- ターミナルを起動し、プロジェクトフォルダまで移動しておく
- clasp login --creds creds.jsonでログインして、ブラウザが立ち上がったら、認証作業をする
- 続けてターミナルに戻ると、「What is your GCP projectId?」と問われるので、コピーしておいたProject IDを入力してEnterを押す
これでプロジェクトフォルダ内に.clasp.jsonが作成され、scriptidの他にprojectidが格納されました。また、.clasprc.jsonにはaccess token他の情報が加わり、claspからApps Script APIを実行できる準備が完了します。
スコープの設定
最後の作業はスコープの追加です。予め控えておいたスコープを.clasprc.jsonに追加するのですが、手動だと面倒なので、以下の手順で追加が可能です。
- ターミナルを起動して、プロジェクトフォルダまで移動しておく
- clasp run 実行する関数名を実行する
- Hey! It looks like you aren't authenticated for the scopes required by this script. Please enter the scopes by doing the following:と聞かれるので、控えておいたスコープをターミナルにコピペ。Enterキーを2回押す
- Added x scopes to your appsscript.json' oauthScopesと出て終了する
- 再度、clasp login --creds creds.jsonを実行して認証を行う。
- 認証が完了すると、.clasprc.jsonに追加したスコープ情報が書き加えられる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
{ "timeZone": "Asia/Tokyo", "dependencies": { "libraries": [ { "userSymbol": "ライブラリの識別子がここに入ってる", "libraryId": "ライブラリのIDがここに入ってる", "version": "1" } ] }, "webapp": { "access": "MYSELF", "executeAs": "USER_DEPLOYING" }, "exceptionLogging": "STACKDRIVER", "executionApi": { "access": "ANYONE" }, "oauthScopes": [ "https://www.googleapis.com/auth/drive", "https://www.googleapis.com/auth/script.container.ui", "https://www.googleapis.com/auth/script.external_request", "https://www.googleapis.com/auth/script.send_mail", "https://www.googleapis.com/auth/spreadsheets" ] } |
コード:この時点でappsscript.jsonにはexecutionApiやoauthScopesなどの情報が追加されています。
図:ターミナルで色々作業しなくてはならない
実際に実行してみた
GetUserという現在アクセスしている人間のGoogleアカウントのメアドを返す関数を作っておきました。これを叩いてみます。なおコードはひどく単純なコードです。
1 2 3 4 |
function GetUser() { var objUser = Session.getActiveUser(); return objUser.getEmail(); } |
ターミナルから以下の手順で実行します。
- ターミナルを起動してプロジェクトフォルダに移動しておく
- clasp run GetUserを実行
- Logger.logの情報は返ってこないが、StackDriver Loggingを使ったconsole.logの場合には、clasp logsで内容を確認可能。この手法で、リモート実行&リモートデバッグが可能です。
すると、ターミナルにGetUserからのreturnされた値が返ってきます。なお、関数名を付けないでclasp runを実行すると「どの関数を実行するか?」聞いてきます。選んでEnterキーで実行が可能です。また、値を返さない関数の場合、undefinedが返ってきます。
関連リンク
- google/clasp
- Command Line Interface using clasp
- Visual Studio Code
- 【Google Apps Script】claspを使ってローカル環境で開発する
- 5分で作るclaspを使ったGoogle Apps Scriptの開発環境
- howdy39/gas-clasp-starter
- claspを使い、Google Apps Scriptプロジェクトをgitでバージョン管理する
- Google Apps Scriptの新しい3つの機能 その③ CLI Tool Clasp
- GAS のGoogle謹製CLIツール clasp
- oshliaer/google-apps-script-awesome-list
- clasp が Typescript をサポートした!
- Apps Scriptをインポート・エクスポートする
- GAS でStackdriver Loggingを使う
- [GAS]Claspでライブラリを使う方法
- clasp depoy"でWebアプリケーションのバージョンが更新出来ない
- メモ:Google App Scriptの開発をClasp & Typescript & VSCodeでやるための準備
- VSCodeでGASの開発
- Google Apps Script をローカル環境で快適に開発するためのテンプレートを作りました
- clasp runがローカルで実行されない
- clasp run できないとき。2018-09-25
- Error retrieving access token: TypeError: Cannot read property 'project_id' of undefined
- claspがTypeError: dotf is not a functionで詰まった話
- GAS Web app をClaspからデプロイ