GoogleAppsScriptローカル開発用の公式CLI(node-google-apps-script)がついに登場したので試してみる

# はじめに

これまで Google Apps Script を開発する方法として公式に提供されているものは Web 上のスクリプトエディタしかなかったんですが、
先日 Google Developer Japan のブログに GAS についての記事が投稿され、その中で **node-google-apps-script** という CLI が紹介されていました。

Google Developer Japan のブログ記事：[Apps Script による高度な開発プロセス](http://googledevjp.blogspot.jp/2016/01/apps-script.html)
元記事（英語）：[Advanced Development Process with Apps Script](http://googledevelopers.blogspot.jp/2015/12/advanced-development-process-with-apps.html)

GAS のファイルをローカルで管理するツールはこれまでにも [gas-manager](https://github.com/soundTricker/gas-manager) というCLI があったんですが、どのような違いがあるのか気になったので試してみました。
※ gas-manager については以前 Qiita に使い方を投稿しました。
[gas-managerを使ってGASのソースコードをローカルで管理する](http://qiita.com/zaki-yama/items/b2d137c2539e20c10138)

なお、はじめに述べておくと node-google-apps-script でも **アップロードできるのは Standalone Script のみで、スプレッドシートやドキュメントなどにひもづいた [Container-bound Script](https://developers.google.com/apps-script/guides/bound) には対応していません。**
(ref. https://developers.google.com/apps-script/import-export#features_and_limitations)

また、gas-manager はソースコードのダウンロードとアップロード、双方向に対応していましたが
node-google-apps-script は **アップロードのみ可能** です。

# 使い方

ここで紹介する手順はおおむね [GitHub の README](https://github.com/danthareja/node-google-apps-script) に書かれている通りです。

### node-google-apps-script をインストール

npm でインストールします。

```zsh
$ npm install -g node-google-apps-script
```

インストールすると `gapps` というコマンドが使えるようになります。

### Credentials を取得する

[Google Developer Console](https://console.developers.google.com/) のプロジェクトで Drive API を有効にし、Client ID と secret を取得します。
README を読むと2通りの方法があるそうです。

1. [Default Apps Script Developer Console Project](https://github.com/danthareja/node-google-apps-script#11-default-apps-script-developer-console-project)
2. [Independent Developer Console Project](https://github.com/danthareja/node-google-apps-script#12-independent-developer-console-project)

このうち2については gas-manager のときと同じく、新規プロジェクトを作成するやり方です。
1 の方法を知らなかったので紹介します。

(※Google Developer Console は頻繁に UI がアップデートされますが 2016年1月時点での UI で確認しています)

Google ドライブで新規 Apps Script を作成し、ファイルを開くと

```
[リソース] > [Developers Console プロジェクト...]
```

というメニューがあります。

![SS_2016-01-30_12_19_05.png](https://qiita-image-store.s3.amazonaws.com/0/36518/d324358b-1081-3dd1-4d6e-890d90ee5123.png)

ここをクリックすると、以下のようなダイアログが表示されます。

![SS 2016-01-30 12.11.35.png](https://qiita-image-store.s3.amazonaws.com/0/36518/42ba2ff7-38e0-a8d2-ff61-155f7058bbdf.png)

そして [このスクリプトが現在関連付けられているプロジェクト:] の下のリンクになっている部分をクリックするとプロジェクト画面に遷移します。
このプロジェクトに対して Credentials を取得しても OK なんだそうです。

---(ここから先の手順は新規プロジェクトを作成した場合も同様)---

左上の `≡` からメニューを開き API Manager を開きます。
または中央の [Use Google APIs] からでもいけます。

![SS_2016-01-30_12_42_33.png](https://qiita-image-store.s3.amazonaws.com/0/36518/cebbc92a-0f81-7dc4-a1fb-bb86473dca25.png)

[Overview] から Drive API を選択し、[Enable API] で API を有効にします。

![SS_2016-01-30_12_44_11.png](https://qiita-image-store.s3.amazonaws.com/0/36518/91778d29-9b51-bcec-1371-904bd9c91f52.png)

次に [Credentials] から [New Credentials] > [OAuth client ID] を選びます。

![SS_2016-01-30_12_45_52.png](https://qiita-image-store.s3.amazonaws.com/0/36518/cedbc486-1284-a598-31b0-19646194b09c.png)

[Application Type] は「Other」とし、適当な名前をつけて保存します。

保存すると一覧に表示されるので、右側のダウンロードアイコンをクリックして Credentials 情報を json ファイルとしてダウンロードします。
ファイル名は `client_secret_...googleusercontent.com.json` のようになっています。

![SS_2016-01-30_12_48_08.png](https://qiita-image-store.s3.amazonaws.com/0/36518/d4c18b47-6a7b-197f-8f28-325613af39bb.png)

### 認証する

先ほどダウンロードした json ファイルを用いて、以下のコマンドを実行します。

```zsh
$ gapps auth [ダウンロードした json ファイルへのパス]

Please visit the following url in your browser (you'll only have to do this once): https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force&scope=https%3A%2F%2Fwww.googleapis.com...
```

このように URL が表示されるのでコピーし、ブラウザでアクセスします。
認証するとコンソールには

```
Successfully Authenticated with Google Drive!
```

と表示されるので、これで認証が完了しました。
（json ファイルはもう削除してしまっても大丈夫です）

### プロジェクトの初期設定

ソースコードを管理したい Apps Script を Google ドライブで開きます。
（ない場合は新規作成します）
開くと、URL は

```
https://script.google.com/d/[file_id]/edit
```

といった形式になっているので、`[file_id]` の部分をコピーします。

次に、ローカルの適当なディレクトリに移動し、以下のコマンドを実行します。

```zsh
$ gapps init [file_id]
```

コマンドを実行すると、ディレクトリに `gapps.config.json` という設定ファイルおよび `src` ディレクトリが作成されます。

```zsh
$ mkdir gapps-sample
$ cd gapps-sample
$ gapps init 1PeGFpXV2g2ey4rfxWPffBKKjz3qk6ZkTGLgroiZibhR1K9c0ts4u4Vkl
$ tree
.
├── gapps.config.json
└── src
    └── コード.js
$ cat gapps.config.json
{
  "path": "src",
  "fileId": "1PeGFpXV2g2ey4rfxWPffBKKjz3qk6ZkTGLgroiZibhR1K9c0ts4u4Vkl"
}
```

`src` ディレクトリには `[file_id]` で指定したプロジェクトのソースコードがダウンロードされます。

### ローカルで開発する

ローカルでファイルを作成し、コードを書きます。
ファイルは拡張子を `.js` にしておくとアップロード時に `.gs` に変換され、`.html` は `.html` のままアップロードされます。
それ以外の拡張子のファイルは無視されます。

### アップロードする

`gapps upload` コマンドでアップロードが可能です。

```zsh
$ gapps upload
Pushing back up to Google Drive...
The latest files were successfully uploaded to your Apps Script project.
```

# 注意点とか

冒頭で述べましたが `gapps` はアップロードしか対応していません。
ただし、既存の Apps Script については `gapps init` 時にコードをダウンロードすることができるため
それほど問題になることは少ないのかなーと思います。

また、アップロード時はドライブ上の Apps Script プロジェクトをローカルの内容に置き換えるため
たとえばドライブ上にしかなかったファイルについてはアップロードによって削除されてしまいます。

# おまけ：gulp などのビルドツールと組み合わせる

gulp から node-google-apps-script を利用する例として、ブログ記事でも紹介されているサンプルプロジェクトがあるのでそちらを参考にするといいと思います。
https://github.com/google/google-apps-script-samples/tree/master/import_export_development

`gulpfile.js` から一部引用すると、

```js:gulpfile.js(抜粋)
var shell = require('gulp-shell');

...(省略)...

// Runs the copy-latest task, then calls gapps upload in the correct
// configuration directory based on the target environment
gulp.task('upload-latest', ['copy-latest'], shell.task(['gapps upload'],
    {cwd: 'build/' + options.env}));
```

gulp タスク内でシェルコマンドを実行できる [gulp-shell](https://github.com/sun-zheng-an/gulp-shell) というプラグインを使ってます。

また、`{cwd: `build/` + options.env}` としているのはこのサンプルの場合 `gapps.config.json` が `gulpfile.js` と同じ階層にないからで、
同じ階層に配置するようなシンプルなディレクトリ構成になっていれば必要なさそうです。

このサンプルプロジェクトは他にもいろんなことをやっているので、Google Apps Script 開発のベストプラクティスとして参考にできるところがありそうです。