Amazon Dash Buttonを押すだけでLINEにメッセージを送信するbotを作る

今更感が凄いですが、Amazon Dash Buttonを押すだけでLINEのメッセージを送信するbotをPythonで作成したいと思います。
Pythonで書きたかったので。curlで直接POSTしたほうが簡単だとか言わないで...


# 環境

 - Ubuntu 18.04 LTS
 - Python 3.6.4
 - pip 10.0.1
 - Node.js 8.11.2
 - npm 6.1.0
 - Dasher 1.4.1
 - line-bot-sdk 1.5.0
 - Heroku CLI 7.0.86


# 前準備

[Dasher](https://github.com/maddox/dasher)と[line-bot-sdk-python](https://github.com/line/line-bot-sdk-python)、[Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli)が必要になるので、それぞれをインストールしておいてください。

また、[LINE@](https://at.line.me/jp)と[Heroku](https://jp.heroku.com)のアカウントも作成しておいてください。
今回はプッシュメッセージを送信することが目的なので、LINE@のプランは<font color="Red">__必ずDeveloper Trialで作成__</font>してください。いくつか制限がかかりますが、個人での利用であればおそらく問題ないかと思います。


# Amazon Dash Buttonのセットアップ

セットアップ通りに進めていくだけですが、<font color="Red">__必ず商品を選択する画面でセットアップを終了__</font>してください。セットアップを完了させてしまうと、ただのAmazon Dash Buttonになってしまうので。以下のようにエラーが表示されていればOKです。

<img src="https://qiita-image-store.s3.amazonaws.com/0/154116/1c64972c-67f3-260f-f923-7d0641486492.png" width=50%>

ちなみに、AmazonからAmazon Dash Buttonのセットアップを完了させるよう催促するメールが送られてきますが、無視して構いません。


# Amazon Dash ButtonのMACアドレスを特定する

`dasher/`内で、

```bash
$ ./script/find_button
```

を実行し、Amazon Dash Buttonを押すと

```
Watching for arp & udp requests on your local network, please try to press your dash now
Dash buttons should appear as manufactured by 'Amazon Technologies Inc.' 
Possible dash hardware address detected: [Amazon Dash ButtonのMACアドレス] Manufacturer: unknown Protocol: udp
Possible dash hardware address detected: [Amazon Dash ButtonのMACアドレス] Manufacturer: unknown Protocol: arp
```

のようにMACアドレスが表示されますのでメモしておいてください。


# userIDを特定する

## 1.Herokuでデプロイする
[チュートリアル](https://developers.line.me/ja/docs/messaging-api/building-sample-bot-with-heroku)に沿ってデプロイしてください。
Herokuのチュートリアルには、Messaging API SDK for Javaを使用と書いてありますが、今回はuserIDを特定するためだけに使用するので、特に問題ありません。

## 2.Herokuのログを確認する

送信先のuserIDは、ユーザからbotにメッセージを送信してもらい、

```bash
$ heroku login
$ heroku logs --tail --app {HEROKU_APP_NAME}
```

でログから特定します。送信してもらうと、ログの中に`event: MessageEvent`という項目があるのでその中の`source=UserSource`の`userID`が送信先となるuserIDになります。


# プログラムをセットアップ

## 1.プログラムを作業ディレクトリ内に配置する
[GitHub](https://github.com/lightning5x5/linebot_with_amazon_dash_button)にプログラムを用意したので、linebot-push.pyを`作業ディレクトリ直下`に、config.jsonを`dasher/config/`に配置してください。

```
linebot(作業ディレクトリ)
  └─ linebot-push.py

dasher
  ├─ app.js
  ├─ config
  |   ├─ config.example.json
  |   ├─ config.json
  |   └─ org.dasher.plist
  └─ 以下略
```

## 2.先程配置したプログラムに書き加える
linebot-push.pyに、`LINEのアクセストークン`と`送信先(userID)`を、config.jsonに`Amazon Dash ButtonのMACアドレス`と`linebot-push.pyの絶対パス`を書き加えてください。
この時に、linebot-push.pyに実行権限を付与するのを忘れないでください。


# 実行してみる
`dasher/`内で、

```bash
$ sudo npm run start
```

を実行し、Amazon Dash Buttonを押すと、

<img src="https://qiita-image-store.s3.amazonaws.com/0/154116/07d78f98-0538-185c-d9a5-7d82614c0898.png" width=50%>

メッセージが無事送信されました！

ちなみに、Amazon Dash Buttonを押してしばらくするとLEDが赤く点滅すると思いますが、これはセットアップが完了していない時などに発生するエラーなので気にしなくていいです。


# つまづいたところ
・アクセストークン、送信先(userID)が正しいにもかかわらず、「Failed to send messages」エラーが発生していました。
原因は特定できませんでしたが、プロバイダを新規で作成し直したら治りました。

・Node.jsをバージョンアップしてから実行すると、

```
internal/modules/cjs/loader.js:731
  return process.dlopen(module, path.toNamespacedPath(filename));
                 ^

Error: The module '/home/user/linebot-push/dasher/node_modules/pcap/build/Release/pcap_binding.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 57. This version of Node.js requires
NODE_MODULE_VERSION 64. Please try re-compiling or re-installing
the module (for instance, using `npm rebuild` or `npm install`).
    at Object.Module._extensions..node (internal/modules/cjs/loader.js:731:18)
    at Module.load (internal/modules/cjs/loader.js:612:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:551:12)
    at Function.Module._load (internal/modules/cjs/loader.js:543:3)
    at Module.require (internal/modules/cjs/loader.js:650:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at Object.<anonymous> (/home/user/linebot-push/dasher/node_modules/pcap/pcap.js:3:21)
    at Module._compile (internal/modules/cjs/loader.js:702:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:713:10)
    at Module.load (internal/modules/cjs/loader.js:612:32)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! dasher@1.4.1 start: `node app.js`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the dasher@1.4.1 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/user/.npm/_logs/2018-06-12T15_28_58_242Z-debug.log
```

というエラーが発生しました。
私の環境であれば、NODE_MODULE_VERSIONが57のバージョン(Node.js 8.x)のNode.jsを使用するか、リビルドをすれば解決しました。


# あとがき

config.jsonの記述内容を変更するだけで様々な動作をさせることができるので、今後も色々と遊んでみたいと思います。
Amazon Dash Button素晴らしい！
Dasher素晴らしい！！


# 参考

https://developers.line.me/ja/docs/messaging-api/reference