Herokuのdynosが切れたのでHubotやめてGASに移行した話。

CircleCIのビルド結果を受け取ってSlackに通知してた自前のHubotのHerokuのdynosが切れたので、Herokuを年末の大掃除してGASに移行した話です。

## HTTPリクエストの受け取り

CircleCiからは[Postでこういうjsonを受け取る](https://circleci.com/docs/configuration/#notify)とします。

```
{
  "payload": {
    "vcs_url" : "https://github.com/circleci/mongofinil",
    "build_url" : "https://circleci.com/gh/circleci/mongofinil/22",
    "build_num" : 22,
    "branch" : "master",
    ...
  }
}
```

HubotにはrouterというHTTPリクエストを受け取る機構がありますが、

例
* https://ota42y.com/blog/2014/08/29/hubot-post-server/
* http://qiita.com/bouzuya/items/8e8ee8e2e8f83513ad35
* http://int128.hatenablog.com/entry/2015/11/14/162217

これをGASで代用するとこうなります

```ParameterClass.js
export class ParameterClass {
  constructor(e) {
    const req = JSON.parse(e.postData.contents);
    const payload  = req.payload;
    this.status    = payload.status;
    this.subject   = payload.subject;
    this.build_url = payload.build_url;
    this.branch    = payload.branch;
    this.reponame  = payload.reponame;
    this.username  = payload.username;
  }

  returnParams() {
    return {
      status:    this.status,
      subject:   this.subject,
      build_url: this.build_url,
      branch:    this.branch,
      reponame:  this.reponame,
      username:  this.username
    }
  }
}
```

## Slackへの通知

Hubot運用時にはSlackのHubotのintegrationを使ってましたが、GASへの移行に伴いincomming webhookに変えました。以下はincomming webhookにpostするクラスです。

```PostClass.js
export class PostClass {
  constructor(e) {
    this.webhookUrl = "webhookのurl";
    this.params = e;
  }

  createPost() {
    const value = `${this.params.subject}\n` +
      `CircleCI: ${this.params.build_url}` +
      `branch: ${this.params.branch}`
    const status = (this.params.status == 'failed') ? '#D00000':'#36a64f';
    const payload = {
      "attachments": [
        {
          "fallback": "ハラショー！ビルド成功！",
          "pretext": "ハラショー！ビルド成功！",
          "color":   status,
          "fields": [
            {
              "title": this.params.username + "、マスターにマージしてデプロイしてね♪",
              "value": value,
              "short": false
            }
          ]
        }
      ]
    };
    const options = {
      "method": "post",
      "payload": JSON.stringify(payload),
      "contentType": "application/json"
    };
    UrlFetchApp.fetch(this.webhookUrl, options);
  }

```

ちなみにPost実行をaxiosでやろうと試みましたが失敗しました。JavaScriptの実行をブラウザでなくGoogleのサーバー内で行うため、どうもGASでは一般に使われるライブラリを一部使えないみたいです。

## 上の二つの機能をbundleして実行する

上の二つのクラスをbundleして一つのファイルにして、GASにアップロードします。

```main.js
import {ParameterClass} from './ParameterClass';
import {PostClass} from './PostClass';

global.doPost = function(e) {
  const parameterClass = new ParameterClass(e);
  const params         = parameterClass.returnParams();
  const postClass      = new PostClass(params);
  postClass.createPost();
}

```

`browserify -t babelify -p gasify ./main.js -o ./src/code.js`を実行し、code.jsをGASにあげてください。

動かしてみるとこういう感じになります。
<img width="722" alt="スクリーンショット 2017-01-04 17.50.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/68020/0c101558-53e1-b12f-cc0c-2c31c85ff659.png">

メッセージの内容は自分好みによしなに変えちゃってください。
また今回GASにアプロードする方法を説明していないので、それは[これ](http://technica-blog.jp/entry/2016/04/28/190236)を参考にしてください。

## 参考文献
* [CircleCI notification](https://circleci.com/docs/configuration/#notify)
* [CircleCIのビルド結果をSlackのダイレクトメッセージに送信する](http://blog.excite.co.jp/exdev/26496823/)
* [CircleCIでトピックブランチのビルドは失敗/復旧時だけ通知、デプロイするブランチのビルドは全通知する](http://qiita.com/kkanazaw/items/bf44ec6d004d51a5236a)
* [Google Apps Scriptの開発をモダンに行う方法](http://technica-blog.jp/entry/2016/04/28/190236)
* [受け取ったPOSTデータをチャットに送信するHubotスクリプトを作った](https://ota42y.com/blog/2014/08/29/hubot-post-server/)
* [Hubot でホームページをつくろう](http://qiita.com/bouzuya/items/8e8ee8e2e8f83513ad35)
* [HubotでWebHookのHTTPリクエストを受け取る](http://int128.hatenablog.com/entry/2015/11/14/162217)