Amazon Dashボタンを使ってWebhookを呼び出す

Amazon Dashボタンが押されたことを、Webhookに通知を流したいと思います。

# Wehbookって？
何らかのイベントが起こった時に、WebサービスにHTTPで通知する仕組み。
（個人的に）よく聞くのは、Slackのチャットに何か通知するメッセージを送る類のやつです。

# 今回やること
- Amazon Dashボタンを押したら
- そのイベントをRaspberry piで拾って
- Google Chatにメッセージを送る(→ユーザにブラウザorスマホアプリ経由でユーザに通知する)

## Google Chat
http://www.itmedia.co.jp/news/articles/1703/10/news067.html

[G Suite](https://gsuite.google.co.jp/intl/ja/features/) (Googleのエンタープライズ向けスイート製品)のSlack版みたいな捉え方でよいと思います。
（同様のことは、Slackで十分できるんで、Slackの方にも参考になるかと思います。）

※記事を書いている時点で、Google ChatはEAP(Early Adopter Program:早期参加プログラム)で提供されているもので、GSuiteを導入している企業であっても管理者の設定を必要とします。
※記事を書いている時点で、Google ChatのEAPでは日本語を正式にサポートしていません。

# 使うもの
* Amazon Dashボタン + Wifi
 * セットアップには、スマホ+Amazonアプリが必要
* Raspberry pi
 * Raspberry pi3 Model Bと Raspberry pi2 Model Bでは動作確認してます
* [Dasher](https://github.com/maddox/dasher) 
 * ネットワーク上のDashボタンイベントを拾って処理してくれるNodeモジュール

# Amazon Dashボタンのセットアップ

Amazon Dashボタンを商品注文に使うのと同様に、スマホのAmazonアプリでセットアップ。
たぶん、Amazon Dashボタンが押された時にWifi接続されるよう、Bluetooth経由で設定するようになってるんだろう。
ということで、やっていることは、Wifi設定だと思います。

設定時の注意点としては、**商品選択をするところまで行ったら、商品を選択せずに終了すること！**
商品選択してしまうと、普通に商品を注文するボタンになってしまいます。

設定に関しては、[こちらの記事](https://qiita.com/tokio-takeda/items/02bae474f8f20f35a02c)が参考になりました。

ということで、**指定したWifiがつながる範囲でのみ使えるボタン**になります。(どこでも使えるわけじゃない!）


# Raspberry piに「Dasher」をインストール

Dasher自体はGitHubにあるので、gitを導入。

```
# sudo apt-get install git   ※gitインストール済みの場合は不要
```

GitHubからモジュール取得。

```
# git clone https://github.com/maddox/dasher.git
```

Dasherはnpmで関連モジュールのインストールが可能なので、npmをインストール。

```
# sudo apt-get install npm　 ※npmインストール済みの場合は不要
# npm -v
2.14.7
```

おまじない的設定（よくわかってない）
```
 # sudo apt-get install libpcap-dev
 # wget http://node-arm.herokuapp.com/node_latest_armhf.deb 
 # sudo dpkg -i node_latest_armhf.deb
```

Dasher本体をGitHubから取得

```
 # git clone https://github.com/maddox/dasher.git
```

関連モジュールのインストール。エラーが出て、途中でとまらなければ平和。

```
 # cd dasher
 # npm install
```

成功すればOK。

# DasherでAmazon Dashボタンのイベントを拾ってみる

Dasherには、初めからDashボタンのイベントを拾ってMacアドレスを取るのが入っているので、
これで確認&情報取得します。
（DashボタンのMacアドレスは、Dasherの設定で必要似なる情報)

```
$ script/find_button 
Watching for arp & udp requests on your local network, please try to press your dash now
```

上記が出たら、ボタンを押してみます。
自宅ルータや他のPCの情報が拾えることがありますが、下記のような形で情報が得られます。

```
Dash buttons should appear as manufactured by 'Amazon Technologies Inc.' 
Possible dash hardware address detected: 12:34:56:78:9a:bc Manufacturer: Amazon Technologies Inc. Protocol: udp
Possible dash hardware address detected: 12:34:56:78:9a:bc Manufacturer: Amazon Technologies Inc. Protocol: arp
```

上記が出てこない場合は、下記を疑うといいかと思います。

* Raspberry piが接続しているネットワークとAmazon Dashボタンが接続しているネットワークが異なる
* Amazon DashボタンのWifi設定がそもそもうまくいっていない

なお、写真で使っているボタンは「Amazon Technologies Inc.」で出たんですが、他のボタンでは「Unknown」と出るものもありました。
（ボタンによってそうなるのか、購入時期の問題なのかは不明。）

# Dasherの設定をする

設定ファイルをサンプルから仕込み準備する。

```
 # cp -p config/config.example.json config/config.json
 # vi config/config.json
```
サンプルを見ると、HTTPで通知以外にもコマンド実行とかありそう。

私の場合は、下記のようにしました。

```
{"buttons":[
  {
    "name": "Notify Family Call",
    "address": "12:34:56:78:9a:bc",
    "protocol": "udp",
    "url": "[Incoming WebhookのURL]",
    "method": "POST",
    "json": true,
    "body": {"text": "実家で呼んでます"}
  }
]}
```

- name: 任意の名前。実行時にコンソール or ログなどに出る程度。
- address: ボタンのMACアドレス。前節で「find_button」を実行したときに
- protocol: 「find_button」実行した時のプロトコル。udpかarpを指定。(私の場合、これ指定しないと動かなかった。)
- url: Webhookを送るURL。(通知したいWebアプリに応じて通知先URLを設定)
- method: HTTPリクエスト時のHTTPメソッド。
- json: JSONデータを送りたいときはtrueを指定。単なるpostはHTTPリクエストの送信だけなら不要かも。
- body: 送信したいデータ。（ここでは、JSONデータの内容を指定)

必要に応じて、ネットワークインターフェスしたりするとより細かい感じになります。

# Dasherを動かして、Webhookできるか試す

```
# npm start
```
(必要に応じて```sudo```しちゃえば、とりあえず確認できるはず。)

実行すると、こんな感じ。

```

> dasher@1.4.1 start /home/pi/dasher
> node app.js

[2017-10-ddThh:MM:dd.xxxZ] Debug Dash Button added.
[2017-10-ddThh:MM:dd.xxxZ] Notify Family Call added.
```
上記までいけば、Raspberry piは待ち受け状態のはずです。

ボタンを押すと、下記の行が増えました。
```
[2017-10-ddThh:MM:dd.xxxZ] Notify Family Call pressed. Count: 1
```

押せば、Countは増えていきます。
（ちなみに、連打では増えない。ボタンのランプが消えてから押せばカウントアップする感じでした。)

ラズパイ側も検知できてるし、Webhookもちゃんと出てる。
![動作確認](http://yosi-q.me/images/amazondash.gif)
（わかりづらいけど、「New」って出てるのがこのボタンで送っているメッセージです。)


# (おまけ)Amazon Dashボタンセットアップでのはまったところ

ボタンが同じネットワーク内(同じwifiにアクセスしてる範囲内)で使ってると、まだ設定途中だよ！的な通知が出る。

<img width="375" alt="設定途中通知" src="https://qiita-image-store.s3.amazonaws.com/0/19870/93a599cf-6843-02fb-9681-1839ae242c2d.png">

いや、そうです。その通りなんだけど、注文したいわけじゃないんだ。（ごめんねAmazon）
通知を消したかったわけで、どうすればと思っていろいろ試しましたが、「通知の設定」を変えることで対応できました。

<img width="375" alt="Dashボタン設定画面" src="https://qiita-image-store.s3.amazonaws.com/0/19870/7bd9da6d-b520-2e66-deec-158f3a214574.png">
↑この画面の「通知の設定」を選択

<img width="375" alt="通知の設定画面" src="https://qiita-image-store.s3.amazonaws.com/0/19870/27a60e8b-8c7f-bbcf-f826-1902c28e3450.png">
↑一番下の「Dash Buttonの通知」をOFFにする。

これやっちゃうと、商品注文に使っているButtonが押されても通知が出ません。
（その辺の監視は、注文メールとかで対応するしかないかなと思います。）