Amazon Dash Buttonで再配達問題の解決に貢献する

## 背景
現代に生きる多くの人がそうであるように僕もAmazonをよく利用するのですが，自室にいるときなど，家にいてもインターホンに気付かずに再配達をお願いしてしまうことが最近多く，届いたはずのゲームをプレイできない・Amazonユーザによって繰り返される再配達依頼が社会的に問題になる，といった不具合が生じています．
インターホンの呼び出し音にいる場所で待機するのも再配達をお願いするのも嫌なので，どこにいてもインターホンの呼び出しに気付くシステムがほしいなぁと思いました．

そこで今回，ボタンを押すとLINEに通知が行くようにしたAmazon Dash Buttonを玄関先に設置し，来た人にボタンを押してもらうことで家のどこにいても来客に気付けるようにしました．

まあ，よくある話ですね．

## 準備
Amazon Dash Buttonによるインターホン通知を実現するためには，以下のものが必要です．

- Amazon Dash Button
    - 商品の購入はしないので，ラベルはなんでもいいです．
- 無線LANルータ
    - Amazon Dash Buttonをネットワークに接続するために必要．まあだいたいのご家庭にあるものと存じます．
- Node.jsが動作するマシン
    - 今回はNode.jsを用いてAmazon Dash Buttonのボタンが押されたことを検知してリクエストを飛ばします．
    - ラズパイとかで全然大丈夫です．もちろんご家庭にある強力なサーバのスペックを無駄遣いするのもよいでしょう．

また，サーバではAmazon Dash ButtonをMACアドレスによって指定するため，これらは同一のネットワークに属している必要があります．

## 実装
だいたい以下のような感じのものを実装します．

1. Amazon Dash Buttonを来客が押す．
2. ボタンが押されたことをサーバが検知する．
3. サーバがIFTTTのwebhookにリクエストを発射する．
4. IFTTTがリクエストを受け取りLINEにメッセージを送信する．
5. ユーザ（僕）がLINEを見る．

以下に具体的な実装を述べます．

### Amazon Dash Button編
[Amazonの公式ページ](https://www.amazon.co.jp/gp/help/customer/display.html?nodeId=201746340)を参考に，Amazon Dash Buttonのセットアップを途中まで進めます．
Dash Buttonで注文する商品を選択するところまで進めればOK．
これによってDash ButtonがLANに接続できます．
これをしないとそもそもDash Buttonをネットワークに接続できません．
また，逆に商品を指定すると来客のたびに商品が注文される地獄が顕現します．

デフォルトではDash Buttonの設定を最後まで終えずにボタンを押すとスマホに通知が飛んできてウザいことこの上ないので，スマホアプリの設定から通知を切ることを推奨します．

### IFTTT編
IFTTTを知らない方のためにクソ雑にIFTTTを説明すると，IFTTTとは時刻やSNSの通知などいろんなものをフックにしていろんなアクションを起こす機能を提供してくれるすごいサービスです．

今回はそんなIFTTTを使って，webhook（特定のURLへHTTPでGETやPOSTをかけること）をフックとしてLINEにメッセージを飛ばす機能をIFTTTで作成します．

1. まず，[IFTTTのレシピを作成するページ](https://ifttt.com/create)へアクセスし，`this` をクリックしてフックを定義する画面へ入ります．
2. `Search services` に "webhooks" と入力して下に出てくるアイコンをクリックし，フックとしてwebhooksを選択します．
3. `Receive a web request` と書いてあるカードをクリックします．
4. `Event Name` に好きな名前を入れます． **後でここで入れた名前をリクエスト先のURLに埋め込まれるので，いい感じの名前をつけましょう．**
5. `that` をクリックしてアクションを定義する画面へ入ります．
6. `Search services` に "LINE" と入力して下に出てくるLINEのアイコンをクリックし，アクションとしてLINEを選択します．
7. `Send message` と書いてあるカードをクリックします．ここらへんでIFTTTにLINEのアカウントを登録するよう促されるかもしれないので，出てきたら登録しましょう．
8. `Recipient` に送信先， `Message` にメッセージを登録します． `Photo URL` の設定は不要．
9. `Receive notifications ...` のチェックを外し， `Create Recipe` をクリックしてレシピを作成します．
10. 完成です．わーい．

レシピを作成したら，リクエスト先のURLを取得します．

1. [IFTTTのwebhooksのページ](https://ifttt.com/maker_webhooks)へ飛んで，右上の `Documentation` をクリック．（ここらへんはIFTTTのページ構成が変更されたら変わる部分なので，変わってたら頑張って自分で探してください）
2. 出て来るページの上の方にある `{event}` と書かれた入力欄に先程定義した `Event Name` を入力します．
3. 入力内容が下の方の `curl -X POST [URL]` コマンドに反映されるので，ターミナルなどにこのコマンドをコピペしてLINEに通知が来ることを確認しましょう．
4. 確認できたらURLを再利用できるようにコピペするなりなんなりして保存しておきましょう．最後に使います．

### サーバ編
サーバ編ではだいたい以下のようなことをします．
1. サーバのセットアップとnode・npmのインストール
2. jsライブラリのインストール
3. Dash ButtonのMACアドレスの取得
4. Dash Buttonのボタン押下を受け取ってリクエストを発射する処理の実装

先人がライブラリを公開してくれるので，それに乗っかるだけでいい感じのものができていい感じですね．

#### 1. サーバのセットアップとnode・npmのインストール
各自ググったりしてがんばってください．OSによって色々差があるよ．ファイト！

#### 2. jsライブラリのインストール
今回の実装では [request](https://www.npmjs.com/package/request) と [dash-button](https://www.npmjs.com/package/dash-button) の2つのライブラリを使います．
それぞれHTTPリクエストとAmazon Dash Buttonをいい感じに使う機能を提供してくれます．

まず，公式に則ってdash-buttonが依存するライブラリを以下のように導入します．

```
# Ubuntu and Debian 
$ sudo apt-get install libpcap-dev
# Fedora and CentOS 
$ sudo yum install libpcap-devel
```

次にnpmを用いてjsのライブラリを導入します．yarnを使いたい人は勝手にして．

```
$ cd /path/to/workspace
$ npm install --save dash-button request
```

### MACアドレスの取得
MACアドレスを取得するスクリプトを動かすため， `package.json` に以下の記述を加えます．~~普段node触らんからここらへんあまりよく分かってない．~~

```json
{
  "scripts": {
    "scan": "dash-button scan"
  }
}
```

次にMACアドレスを動かすためのスクリプトを動かします．
 `sudo` を付ける必要があるので，PATHが通らないとかで怒られたら頑張って `visudo` で設定を変更するなどしてPATHを通すようにしてください．

```
$ sudo npm run scan
```

スクリプトを実行中にAmazon Dash Buttonのボタンを押すとおそらくMACアドレスが表示されるはずなので，控えましょう．

### Dash Buttonのボタン押下を受け取ってリクエストを発射する処理の実装
ようやく出てくるプログラミング要素．
[好きなエディタ](https://www.vim.org/)でスクリプトを組みます．
`console.log()` は適宜削ったりして構いません．

```js
const DashButton = require("dash-button");
const Request = require("request");

const URI = "先程取得したIFTTTのリクエスト先のURL";

let options = {
  uri: URI,
  method: 'POST',
};

const PHY_ADDR = "Amazon Dash ButtonのMACアドレス";

let button = new DashButton(PHY_ADDR);

console.log("Start listening...");

button.addListener(() => {
  Request.post(options, function(error, response, body){});
  console.log("Message sent");
});
```

このスクリプトをサーバ上で動かせばいい感じです．

```
$ sudo node dash_button.js
```

ボタンを押して動くか確認しましょう．

## 結果
さっき作って設置したばかりなので宅配の人が押してくれるかなどに不安は残りますが，まあ一応完成です．

とりあえず設置したときに押したらLINEに通知が届きはしたので，動作は問題ないはずです．

（あとDash Buttonが盗られたり落ちたりして消えないかは不安ですね……）

また何かあったら追記します．

以上！！