JavaScriptでブラウザを自動操作できるnightmarejsを使ってガストのクーポンを自動発行する

## TL;DR
[mpppk/skylarq](https://github.com/mpppk/skylarq)
![skylarq_demo.gif](https://qiita-image-store.s3.amazonaws.com/0/28464/81cd56f8-764e-d162-bf30-eb35780ccc8c.gif)
こういうやつです

## 背景
集中するためにカフェに行く方は多いと思いますが、自分は最近ファミレスで作業しています。
その中でもガストを含むすかいらーくグループでは、清算後のレシートにドリンクバーのクーポンが付いていることがあります。

![receipt.jpg](https://qiita-image-store.s3.amazonaws.com/0/28464/a878308a-7641-ff94-434c-69ff3b1ebcf3.jpeg)

ガストだとドリンクバーは199円なので、74円になると約63%OFFです。すごい。
この画像は74円ですが、無料のクーポンも有るみたいです。
さて、このクーポンですが、使うにはアンケートに答える必要があります。
まずレシートに書かれているQRコードにアクセスします。

<img width="728" alt="top.png" src="https://qiita-image-store.s3.amazonaws.com/0/28464/b229cb9c-feca-85dc-9dbb-d689bcfbdca5.png">

アクセスすると表示される画面に、クーポンに書かれている24桁の数字を入力します。
規約に同意すると、こんな感じでアンケートが表示されるので粛々と答えます。
全部で34問あるみたいです。

<img width="778" alt="question.png" src="https://qiita-image-store.s3.amazonaws.com/0/28464/bb890f09-7f69-0c0f-e0ed-4a94923f1f85.png">

全ての質問に回答すると、5桁の数字が表示されます

<img width="801" alt="result.png" src="https://qiita-image-store.s3.amazonaws.com/0/28464/ab000f65-38ee-319f-c072-6a0791c8c830.png">

これをレシートに記入すれば、ようやくクーポンとして利用することができます。
ガスト以外に行ったことがないのですが、すかいらーく系列店であるバーミヤン、夢庵、ジョナサンなどでも発行されるはずです。

## 問題点
アンケートの中には、過去の来店経験など、毎回同じ回答になる項目がいくつかあります。
できればそういうのは飛ばして、今回特筆すべき項目への回答に時間をかけたいですよね。
あと、単純に34問分マウスをポチポチして答えるのが大変というのもあります。

## そこでNightmarejs(前置きが長い)
Nightmarejsは、JavaScriptでブラウザを操作するためのライブラリです。
例えば、yahoo検索を行うサンプルコードは以下のようになります。

```yahooSearch.js
const Nightmare = require('nightmare');
const co = require('co');

co(function * (){
  yield Nightmare({show: true})
    .goto('http://yahoo.co.jp')
    .type('input#srchtxt', 'nightmarejs')
    .click('#srchbtn');
});

```

これを実行するとこんな感じになります。

```Shell
$ node yahooSearch.js
```

![nightmarejs_demo.gif](https://qiita-image-store.s3.amazonaws.com/0/28464/75bef394-d3aa-62a4-8c96-e1fe8ba735d0.gif)

いやーお手軽ですね。
これを使って、ガストのアンケートに自動回答するツールを作ります。

## 実装例
例えば、質問文を抽出するコードはこんな感じになります。

```js
extractQuestions(nightmare){
  return nightmare.evaluate(() => {
    return document.querySelector('.mainQuestion').textContent;
  });
}

extractQuestions(nightmare).then(question){ console.log(question); }
// => 質問内容が表示される
```

evaluateに渡した関数は、ブラウザ上で実行され、返り値はPromiseっぽい感じでthenの引数として得られます。
ここではブラウザ上でDOMにアクセスし、質問内容を返しているわけですね。

nightmarejsはv2からyieldableになったので、メソッドを使うときはこのように同期的に書くことができます。

```js
const question = yield extractQuestions(nightmare);
console.log(question);
```

## ガストのアンケートに自動回答するツール
こんな感じでNightmarejsを使いまくった結果、事前に作っておいた回答ファイルから自動でアンケートに回答するツールができました。

[skylarq](https://github.com/mpppk/skylarq)

以下のコマンドでインストールできます。

```
$ npm install -g skylarq
```

### 使い方
まずアンケートにどのように答えるかを設定するファイルを作成します。
以下のコマンドを実行すると、ホームディレクトリにskylarq.ymlが生成されます。

```Shell
$ skylarq --init
```

`skylarq.yml`には、以下のように質問とその回答が書かれています。
questions以下のanswerを回答したい内容に書き換えていきましょう。
`code`には、レシートに書かれているn桁の番号を入力しておきます。
一度回答してしまえば、二度目からは変わった点を変更するだけで済むようになります。

```yml
code: 018978201611070001085974
questions:  
    今回ガストを利用されて、お客様の全体的な満足度はいかがでしたか？ :
        choices :
            - 大変満足
            - 満足
            - どちらでもない
            - 不満
            - 大変不満
        answer : 大変満足
        ・
        ・
        ・
```

編集が終わったら実行しましょう。
単に`skylarq`コマンドを実行すると、skylarq.ymlの内容に基づいてアンケートに回答し、最後にクーポンコードを表示します。
--browser(or -b)オプションを指定すると、実行中の内容がブラウザに表示されます。
また、実行時には`--i-agree-terms`オプションが必須です。
事前にアンケートの利用規約を読み、同意できる方だけ、上記オプションを指定してください。

```Shell
$ skylarq --i-agree-terms
[==============================] 33/33 100% 10.0s 0.0s
coupon code: 12345
```

これでアンケートに回答しまくれますね。

## ぜひ使ってみてください
当然ですが、実行にはレシートにランダムで付与されるガストのクーポンが必要です。
このツールの開発のため毎日ガストに通っていたら、最近は入店時に禁煙か喫煙かを聞かれなくなりました。

それぐらい行ってもテスト用クーポンが足りないため、skylarq.ymlの質問網羅度は全然足りておらず、存在しない質問が表示された場合は回答が途中で中断されてしまいます。
特にガスト以外が近所にないので、他のすかいらーく系列店は現状質問が全く存在していません。
もし新たな質問文を発見したら、お気軽にissueを立てていただけるとありがたいです。

フィードバックお待ちしてます！