い、い、、いっくし!!

各記事はkwskってコメントすると詳しく書き直します

The GAS開発 in 2016 その3

前回Googleドライブの準備

実際にコードを書くための準備をします。 ここからはほとんど、Visual Studio Codeで作業

まず、dev ディレクトリと secret ディレクトリを作成。

.gitignoreファイルの末尾に次を追加

.vscode/
secret/
src/
gapps.config.json

f:id:ixsiid:20180119214735p:plain

これを怠ると、アクセス用のAPIキーやファイルIDが外部に漏れて、とんどもないことが起こりえます。

初心者がAWSでミスって不正利用されて$6,000請求、泣きそうになったお話。 - Qiita

気を付けなければいけないポイントはここだけでもないので、この辺の認証の仕組みや、 Github や GAS で何が公開されるのかは、よく確認しましょう。

続いて package.json を編集

@@ -xx,yyy +xx,zzz @@
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
+   "build": "browserify dev/main.js -t babelify -p gasify -o src/bundle.js",
+   "upload": "gapps upload",
+   "watch": "watchify dev/main.js -t babelify -p gasify -o src/bundle.js"
  },
+ "babel": {
+   "presets": [
+     "es2015",
+     "gas"
+   ]
+ },

secret ディレクトリの中に Google.js を作成。こちらにファイルIDなどを記載する。

module.exports = {
    token: 'TEST_TOKEN',
    log: '第2回でメモしたログファイルのIDを記載',
};

さらに dev ディレクトリの中に Log.js を作成。

module.exports = function (tag) {
    const self = this;
    const fileId = require('../secret/Google.js').log;

    const file = DocumentApp.openById(fileId);
    const body = file.getBody();

    const levels = 'newidv';
    this.level = 4;

    const put = (level, object) => {
        if (self.level < levels.indexOf(level)) return;

        const text = typeof object === 'string' ? object : JSON.stringify(object);
        const datetime = JSON.stringify(new Date()).substring(1, 20);
        body.appendParagraph('[' + datetime + '] (' + tag + ') ' + level.toUpperCase() + ': ' + text);
    };

    [].map.call(levels, level => {
        self[level] = object => put(level, object);
    });
};

最後に、 dev ディレクトリの中に動作確認用のスクリプト index.js を作成

const Log = require('./Log');

global.log = new Log('MAIN');
global.token = require('../secret/Google').token;

global.doGet = function (query) {
    const log = global.log;
    log.v('Call doGet function');
    log.v(`Query is '${JSON.stringify(query)}'`);

    if (query.parameter.token !== global.token) {
        log.e('Bad token access');
        return false;
    }

    return true;
};

これをGASようにビルドします。すでにビルド設定は済ましているため、VSCodeのタスクから npm build を実行

f:id:ixsiid:20180119214749p:plain

f:id:ixsiid:20180119214803p:plain

無事に終わればターミナルに次のように表示される。 また src/main.js がビルドされたスクリプトに書き換わっている。

f:id:ixsiid:20180119214816p:plain

無事にビルドされたらアップロードする。タスクの実行から npm upload を選択

ターミナルに

The latest files were successfully uploaded to your Apps Script project.

と表示されたらアップロード完了

実際にアクセスして動作確認してみる。 今回は第2回でメモしたURLをブラウザで開く。ただし、本来 doGet の返り値に必要な結果を返していないため、次のようなエラーとなる。

f:id:ixsiid:20180119215605p:plain

これが表示されず「その操作を実行するには承認が必要です。」とでる場合は、一度Google ドライブから関数を実行して、権限の承認をしなければならない。

f:id:ixsiid:20180119215811p:plain

その後URLの最後尾に `?token=TEST_TOKEN' を付加して再度アクセス。 ドライブに用意しておいたログドキュメントを確認。

次のようなアクセスログが記録されているはず。

[2018-01-19T12:53:29] (MAIN) V: Call doGet function
[2018-01-19T12:53:29] (MAIN) V: Query is 'undefined'
[2018-01-19T12:54:09] (MAIN) V: Call doGet function
[2018-01-19T12:54:09] (MAIN) V: Query is '{"parameter":{},"contextPath":"","contentLength":-1,"queryString":"","parameters":{}}'
[2018-01-19T12:54:09] (MAIN) E: Bad token access
[2018-01-19T12:54:51] (MAIN) V: Call doGet function
[2018-01-19T12:54:51] (MAIN) V: Query is '{"parameter":{"token":"TEST_TOKEN"},"contextPath":"","contentLength":-1,"queryString":"token=TEST_TOKEN","parameters":{"token":["TEST_TOKEN"]}}'

ここまでで、ローカルでGASを作成、Google ドライブにアップロードし、Webからアクセスして動作という開発の流れは完成

次回はローカルでのテスト環境の構築