Google Apps Scriptは着実に機能を増強しているとはいえ、開発画面はあの「スクリプトエディタ」画面が基本です。とはいえ、GASで巨大システムなど作ることもないので、十分と言えば十分。しかし、チームで開発を行ったりする場合には面倒というのも事実。

そこでGoogleが2018年1月に出してきたツールが「clasp」というNode.jsで動作する、ローカルPCでGoogle Apps Scriptを好きなエディタで開発し、簡単にデプロイが出来る便利なツールです。それまでのnode-google-apps-scriptを廃止し、様々な追加機能を持って現在、一部の開発者の間で使われています。今回はこのツールで、実際に開発をしてみたいと思います。

今回使用するライブラリやファイル等

  • 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をインストールする

2019年1月現在、最新版LTSはv10.15.0となっています。以下の手順でnode.jsをインストールします。

  1. Node.jsからnode-v10.15.0.pkgをダウンロードする。Windows(32bit)ならnode-v10.15.0-x86.msiとなります。64bit版も別に存在するので、注意してください。
  2. ダブルクリックで実行して、インストールを進める。
  3. 最後にインストールしたパスが表示されて終了。

図:インストール自体は超カンタン

ここで一応、ターミナルを起動して、node.jsおよびnpmのバージョンを確認しておきましょう。Windowsの場合は、コマンドプロンプトになります。

  1. ターミナルを起動する
  2. node -vコマンドにて、バージョンを確認する
  3. npm -vコマンドにて、バージョンを確認する

図:バッチリ最新版になってるのを確認した。

claspのインストール

まずはともあれ、Node.jsがインストール完了したら、clasp本体をインストールします。sudoで実行する点に注意が必要です。

図:あっという間にインストール完了

claspでGoogleにログイン

claspのインストールが完了したらターミナルからログイン認証を行います。以下のコマンドを入力すると、いつものGoogleアカウントの認証画面が出るので、ログインしましょう。ログインが完了すると、.clasprc.jsonというファイルが自分のユーザフォルダ直下(/Users/ユーザ名/.clasprc.json)作成されます。macOSの場合、nodeへの受信許可の可否を問う画面が出ますので、許可してあげましょう(でないと通信が出来ません)。

Logged in! You may close this page.とメッセージがでたら閉じます。ちなみに、clasp logoutとするとファイルは削除され、認証も消えます。ログインするアカウントを間違えないように!!

図: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しか弄れない使えないプラグインでした)。

主に、新規作成(既存データ読み込み)、コードアップロード、デプロイが主な機能になります。createcloneを実行すると、プロジェクトフォルダ以下に.clasp.json(macOSだとデフォルトだと非表示)というファイルが出来ており、Nested clasp projects are not supported.というエラー発生時には一回このファイルを削除してから、再チャレンジしましょう。このファイルには、スクリプトIDが書き込まれています。

コードを作成する

新規作成をする

ほとんどの場合、Google Apps Scriptを使うのはスプレッドシート上になるでしょう。スプレッドシートと共にプロジェクトをローカルPCに作成します。ただし、通常スプレッドシートを使う場合、設定項目やテーブルなどをスプレッドシートにある程度作り込んでからの作業になるので、次項のコードを持ってくるほうが利用頻度は高いと思います。

  1. ユーザのドキュメントフォルダ以下にプロジェクトフォルダを作っておく(/Users/ユーザ名/Documents/projectfolder
  2. ターミナルを起動し、プロジェクトフォルダまで進む
  3. 以下のコマンドで新規作成する
  4. 途中、選択画面が出ますが、sheetsを選んでEnterキーを押すと作成開始
  5. 完了すると、プロジェクトフォルダには、「appsscript.json」だけが作成され、create new google sheetsの表記と共にURLが表示されます(ファイルはGoogle Drive直下にClaspというファイル名で作成されます。)。
  6. appsscript.jsonの中のTimezoneがUSになってるので、Asia/Tokyoに書き直しておきましょう。

図:中身が空のスプレッドシートと紐ついたappsscript.jsonが作られる

図:ドライブ直下に作られるので、移動が必要ですね。

コード:中身はこざっぱり。TimezoneがAmericaになっとる・・・

既存のコードを持ってくる

一番利用する方法はこちらの「既存のファイルから持ってくる」方法でしょう。今回はまだ未公開ですが、すでに5年前から開発を続けて実際に利用している「物品購入修理伺いフォーム(改」のコード類をクローンしてみたいと思います。スクリプトID単位となるため、1つのファイルに複数プロジェクトを作り込んでる場合、それぞれのプロジェクトのID分だけ作業が必要になります。

  1. スクリプトエディタ画面に入る
  2. ファイル⇒プロジェクトのプロパティを開き、スクリプトIDをコピーしておく
  3. 事前にプロジェクトフォルダを作っておく
  4. ターミナルを起動し、プロジェクトフォルダまで進む。
  5. 以下のコマンドでプロジェクトをクローンします。

図:スクリプトIDが重要なキーです

図:14個ものファイルがダウンロードされました。

図:Finderでファイルを確認してみる

図:ダウンロードしたappsscript.jsonには色々書かれてる 

コードをアップロードする

コードプッシュ

ダウンロードされたコードは、.jsファイルが「Google Apps Script」のファイル。htmlがウェブアプリケーションのHTMLやCSS、JavaScriptを格納するファイルです。本来GASは拡張子はgsなのですが、clasp経由ではjsファイルになるようですね。また、cssといった拡張子のファイルはサポートされていないので、これらやHTML側のjs類はhtmlファイルに格納しましょう。

編集を行ったら、アップロードしなければなりません。以下の手順でコードを反映させます。

  1. ターミナルを起動し、プロジェクトフォルダまで進む
  2. 以下のコードを実行する
  3. 全ファイルがアップロードされ、反映される
  4. jsではなくTypescriptのtsファイルの場合、自動でトランスパイルされてアップロードされます。

これだけです。非常に簡単ですね。ちなみにすぐにデバッグ作業などを行いたい場合は、続けて、clasp openと実行するとスクリプトエディタ画面へ直行出来ます。コードが反映されているか確認ができますよ。あらかじめテンプレを自分で用意しておくと、書き始めがとても楽に済みます。その場合は

  1. 一旦空のスプレッドシートを作っておく
  2. clasp cloneでダウンロードしておく
  3. プロジェクトフォルダにテンプレファイル群を放り込む
  4. clasp pushでプロジェクトにファイル群を反映させる

これでスタート開始が楽になります。

Webアプリケーションをデプロイ

Google Apps Scriptを使う一番の目的は実はウェブアプリケーションの開発にあると思ってます。VBA的にスプレッドシートやCalenderに登録も確かに重要なのですが、ウェブアプリが作れるからこそこの言語は美味しい。スプレッドシートを使うのもデータの保存や設定値を作り込んだりが出来る良い土台だから。

ということで、claspからもウェブアプリケーションのデプロイが出来るようになっています。以下の手順でウェブアプリケーションを公開しましょう。コマンドラインでデプロイまで出来ると、色々自動化ができそうですね。

  1. ターミナルでプロジェクトフォルダまで進む
  2. 以下のコマンドでバージョン指定、説明文を入れて実行するとデプロイされます。
  3. 当然ですが、ファイルのオーナーでないとこの処理は出来ません。

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は何をどうしたのかさっぱりわからないことになるので、丁寧に説明文を入れたいものですね。

  1. clasp versionsで現在の版すべての一覧を取得できます。
  2. clasp version バージョン 説明文にて新しい版を保存できます。

図:きちんと説明文を入れないと何の版なのかさっぱり・・・

フォルダ構造

Google Apps Scriptのエディタはファイル類に関してフォルダ構造をサポートしていません。全てのファイルが1つの平面に並べられてる状態です。しかし、pushする場合にフォルダで管理したいという要望もあると思います。実際にやってみましょう。するとスクリプトエディタ画面上で、対象のファイルのファイル名に変化が起きます。

こんな感じに。例えば、srcというフォルダの中にtestman.jsというファイルという構造にすると、スクリプトエディタ上では「src/testman.gs」という表記になります。もちろん、スクリプトエディタ上でこの表記にしてダウンロードすると、フォルダ構造が復元される仕組みになっています。この方法は、Google Apps Script Github アシスタントでも見たものですね。

ですので、ローカルでフォルダ管理を行って問題なく開発は進められます。ローカルに保存されてるわけですから、そのままGithub上でバージョン管理も可能になるので、claspは複数開発者の場合便利ですね。

図:ファイル名でツリー管理をする

アップロードするファイルを制限する

基本全てダウンロード、全てをアップロードするのがclaspですが、同じフォルダ内に入れておきたいファイル類などがあったりするケースではこのままだと未対応のファイルということで、エラーが出てしまいます。そこで、アップロードするファイルを制限する手段が.claspignoreファイルです。

macOSだとドットファイルは標準では見えないので、以下のコマンドで見えるようにしておくと良いでしょう。または、Shift + Command + .キーで切り替えが可能です。

さて、.claspignoreファイルですが、プロジェクトフォルダ内に入れておくと、clasp pushした時に記載されているファイルだけをpushするようになります。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はこちら

事前準備

プロジェクトを移動

今回の発表直前の2019年4月8日より、Google Apps ScriptからCloud Platform Projectへ直接アクセスが出来なくなりました。これまでにデプロイしてるものについては、これまで通り「リソース」⇒「Google Cloud Platform API ダッシュボード」からアクセスが可能です。

今回の変更はスプレッドシート上で動かすスクリプトやGoogleの拡張サービスを利用しないタイプのスクリプトであれば特に問題はありませんが、「Apps Script API」や「Google Picker API」、「Cloud SQL接続」などGCP上のAPIを利用する場合には以下の手順を踏んで、Google Apps Scriptにプロジェクトを連結する必要があります。これまでは、自動的にGCP上にGoogle Apps Script用のプロジェクトが生成されていたのですが、今後は自分の組織(もしくはGCPプロジェクト)上で作成されたプロジェクトでなければならないということです。詳細はこちらのページを見てください。

連結する手順は以下の通り

  1. Google Cloud Consoleを開く
  2. 左上にある▼をクリックする
  3. ダイアログが出てくるので、新規プロジェクトを作るか?既存のプロジェクトを選択する。この時、G Suiteであれば選択元は「自分のドメイン」を選択する必要があります。
  4. プロジェクト情報パネルから「プロジェクト番号」をコピーする
  5. 対象のGoogle Apps Scriptのスクリプトエディタを開く
  6. 「リソース」⇒「Cloud Platform プロジェクト」を開く
  7. 4.で入手した番号をプロジェクトを変更のテキストボックスに入れて、プロジェクトを設定ボタンをクリックする
  8. 無事に移動が完了すればメッセージが表示されます。
  9. この時、元の自動作成されたプロジェクトはシャットダウンされて消えます。これで設定完了です。

今回のこの変更だと1つ作ったプロジェクトに集約する必要があるので、クォータについてプロジェクト毎のカウントだったので問題なかったものが、集約されることで、クォータに引っ掛かる可能性があります。

図:プロジェクト番号をコピーしておきます

図:プロジェクトを他のプロジェクトに紐付けしました。

図:GCPの拡張サービスを使うには手順が必要になった

Apps Script APIを有効化する

  1. 対象のスクリプトのメニューより「リソース」⇒「Googleの拡張サービス」を開きます。
  2. 出た画面の下にある「 Google Cloud Platform API ダッシュボード」をクリックします。
  3. APIライブラリを開き、「Apps Script API」を検索して、有効にします。
  4. 認証情報をクリックし、認証情報を作成⇒OAuthクライアントIDを選択します。
  5. アプリケーションの種類は「その他」を選択し、作成します。
  6. クライアントIDとクライアントシークレットがでますが、何もせずに閉じます。
  7. 認証情報画面に戻り、今作成したクライアントIDなどが詰まったファイルは右の方にある↓のアイコンをクリックすると、JSONファイルでダウンロード出来るので、creds.jsonとリネームしてとりあえず、取っておく
  8. この時、URLに出てるProject IDが必要になるので、控えておく(例:project-id-0120117117
  9. また、この後の工程でスコープの設定があるので、ファイル⇒プロジェクトのプロパティ⇒スコープにあるOAuthスコープを控えておきましょう。

ここまでで、creds.jsonProject IDOAuthスコープが手に入りましたので、一旦スクリプトエディタは閉じておきます。

※ターミナルからclasp open –credsで直接対象のプロジェクトのページに飛んで作業も可能です。

実行可能APIとして導入する

実行可能APIとして導入するという機能は、ウェブアプリケーションとして導入と同じく、ソースコードを変更する度に発行し直さないと行けないので注意が必要です。ソースコードを変更後に再度導入をせずに実行しても、以前のソースコードのままで返ってくるので嵌るポイントです。

実行可能APIとして導入する手順は以下の通りです。

  1. スクリプトエディタのメニューより、「公開」⇒「実行可能APIとして導入」を実行します
  2. この作業を行わないと、Script API executable not published/deployed.とエラーが出ます。

これだけです。

図:配置ボタンを押すと完了

creds.jsonでログインする

一旦現在のプロジェクトファイルは捨てて、新しくclasp cloneするかclasp pullしておきましょう。すると、appsscript.jsonにはexecutionApiの項目が追加されているのがわかります。

この状態で以下の作業を行います。

  1. プロジェクトフォルダにcreds.jsonを入れておく
  2. ターミナルを起動し、プロジェクトフォルダまで移動しておく
  3. clasp login –creds creds.jsonでログインして、ブラウザが立ち上がったら、認証作業をする
  4. 続けてターミナルに戻ると、「What is your GCP projectId?」と問われるので、コピーしておいたProject IDを入力してEnterを押す

これでプロジェクトフォルダ内に.clasp.jsonが作成され、scriptidの他にprojectidが格納されました。また、.clasprc.jsonにはaccess token他の情報が加わり、claspからApps Script APIを実行できる準備が完了します。

スコープの設定

最後の作業はスコープの追加です。予め控えておいたスコープを.clasprc.jsonに追加するのですが、手動だと面倒なので、以下の手順で追加が可能です。

  1. ターミナルを起動して、プロジェクトフォルダまで移動しておく
  2. clasp run 実行する関数名を実行する
  3. 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回押す
  4. Added x scopes to your appsscript.json’ oauthScopesと出て終了する
  5. 再度、clasp login –creds creds.jsonを実行して認証を行う。
  6. 認証が完了すると、.clasprc.jsonに追加したスコープ情報が書き加えられる。

コード:この時点でappsscript.jsonにはexecutionApiやoauthScopesなどの情報が追加されています。

図:ターミナルで色々作業しなくてはならない

実際に実行してみた

GetUserという現在アクセスしている人間のGoogleアカウントのメアドを返す関数を作っておきました。これを叩いてみます。なおコードはひどく単純なコードです。

ターミナルから以下の手順で実行します。

  1. ターミナルを起動してプロジェクトフォルダに移動しておく
  2. clasp run GetUserを実行
  3. Logger.logの情報は返ってこないが、StackDriver Loggingを使ったconsole.logの場合には、clasp logsで内容を確認可能。この手法で、リモート実行&リモートデバッグが可能です。

すると、ターミナルにGetUserからのreturnされた値が返ってきます。なお、関数名を付けないでclasp runを実行すると「どの関数を実行するか?」聞いてきます。選んでEnterキーで実行が可能です。また、値を返さない関数の場合、undefinedが返ってきます。

関連リンク

共有してみる: