raspi起動時にipをlinebotを使って通知するシステムを作った話

# 概要
* raspiにsshで入るときにIP調べるために毎回ディスプレイにつなぐのダルくなったので、何かで通知するシステムを作ろうと思った。
* 勉強用に全く触ったことないnode.jsとlinebotを使って作った。

# 紹介すること
* linebotアカウントのプラン選択
* linebotアカウントの取り方
* linebotでのreply、pushの仕方
* node.jsでipを取ってlinebotにpushするコード
* raspiの起動時に任意の処理を実行する方法

# linebotアカウントのプラン選択

linebotのプランには、以下の4種があるらしい

![image](https://qiita-image-store.s3.amazonaws.com/0/169947/a7e11b35-e827-703d-5047-7c34b3e7a8f6.png)

* お金がかからんヤツ
* push機能(lineの外からlineに通知とかできる)が使えるヤツ

がいいので`Developer Trial`を取ることにした。

# linebotアカウントの取り方

## どこから取るねん

linebotアカウントの`Developer Trial`は以下の画面の、
`Developer Trialを始める`
から取得できる。

LineBusiness Center:Messaging API
https://business.line.me/ja/companies/1360099/services/bot

![image](https://qiita-image-store.s3.amazonaws.com/0/169947/f4178114-bd8e-57da-0af8-171c9bc5bdc0.png)

押すとLineのアカウント認証を求められる。
普段使いのlineアカウントでログイン
(PCログインを無効にしてる場合は携帯のアプリから有効にする必要がある。)

## 入力するんだ

ログインするとBOTアカウントの情報を入れるフォームへ
![image](https://qiita-image-store.s3.amazonaws.com/0/169947/f9f286fb-94c1-0fa4-ff7c-ec9d73a62438.png)

アカウント名を入れるフォームが若干わかりづらい。
カメラのアイコンの下「アカウント名」と書いてあるところをクリックすると入力できる。
カメラのアイコンをクリックするとBOTアカウントのアイコンをアップロードできる。
業種は自分に合ったものを選ぶ。(個人、個人(IT)とか)

## BOTの設定をいじるんだ

アカウントができたらLineBusinessCenterの「アカウントリスト」から、アカウントが見られるようになる。

* `Line@`:BOTアカウントの管理
* `Messaging API`:BOTのメッセージAPIのパラメータとか細かい設定

の分担
まずはLine@からBOTのMessaging APIを有効にする
スクショを残し忘れたけど、

* Line@Managerから設定開始
* アカウント設定クリック
* アカウント設定の下にBot設定とでるのでクリック
* 「APIを利用する」をクリック(1:1トークできなくなるよ、とかでるけどBotのアカウントだからOK)
* リクエスト設定でwebhook送信を「利用する」にチェック(大事)
* 「LineDeveloppersで設定する」から移動
* BOTアカウントのパラメータが見られるので以下をメモる
    * `Channel Access Token`: (ISSUEボタンを押すと表示される)このBOTアカウントを特定するようなトークンの様子。(BOTで何をするにも使う)
    * `Your userId`: 自分の携帯のLineアカウントを特定するID。このID宛にプッシュすると、自分の携帯のLineにBOTからメッセージが届くようなことができる。(ここハマった。普通のLINEアプリのIDとは違う。他の人のを調べたければ、BOTと友達になってBOTに話しかけたときにとぶjsonの中身を見ればわかる。もっと簡単にわかるといいんだが、、、)
* BOTのQRコードをスマホで読んで、お友達になっておく

ここまででBOTの設定はOK

# linebotでのreply、pushの仕方

Line API Refarenceが優秀なので読む(shell,java,ruby,go,php,perl,pythonのサンプルがある！)
https://devdocs.line.me/ja/

## Pushしようず

ここまでできたら、とりあえずpushして1回満足しよう
ネットにつながってるLinuxで以下を叩く
(###のところは#ごとさっきメモした値に置き換えてください)

```
curl -X POST \
-H 'Content-Type:application/json' \
-H 'Authorization: Bearer {###Channel Access Token###}' \
-d '{
    "to": "###Your userId###",
    "messages":[
        {
            "type":"text",
            "text":"Hello, world1"
        },
        {
            "type":"text",
            "text":"Hello, world2"
        }
    ]
}' https://api.line.me/v2/bot/message/push
```

BOTからHello Worldが2個届けば成功

## Replyの使い方

Replyは読んだまま、BOTに話しかけたときに何かの応答をしてくれる機能
応答の処理はLineDeveloppersのBOTのアカウントのページのWebhookURLの先に仕込んでおく必要がある。
仕込み先には条件があって、

* httpsで受けられること
* ssl証明書が自己署名だとLineのシステムからNGがでる

ので自分でやるのはちょっとめんどくさい
Herokuだったらすんなり動いたので、Herokuとかに置くといいと思う。

参考：Heroku初心者がHello, Herokuをしてみる
http://qiita.com/Arashi/items/b2f2e01259238235e187

HerokuにデプロイしたアプリのアドレスをLineDeveloppersのBOTのアカウントのページのWebhookURL欄に入れると動く

# node.jsでipを取ってlinebotにpushするコード

(参考)：第三回 Raspberry Pi 3に最新のNode.jsをインストールする
http://qiita.com/setouchi/items/437e4b62e4210871496f

上記手順などでraspiでnode.jsが動かせる環境を前提で、
`npm install request`
してrequestパッケージ使えるようにして、以下のコードを`notice_ip.js`とか名前つけて作成

```
const execSync = require('child_process').execSync;
const result =  execSync('ip addr').toString();


var request = require('request');

var headers = {
  'Content-Type': 'application/json',
  'Authorization': 'Bearer {###Channel Access Token###}'
};

// data payload
var data = {
     "to": "###Your userId###",
     "messages":[
        {
            "type":"text",
            "text":result
        }
     ]
};

var options = {
  url: 'https://api.line.me/v2/bot/message/push',
  method: 'POST',
  headers: headers,
  json: data
};

request(options, function (error, response, body){});
```

`node notice_ip.js`
で実行

これでraspiのip addrした結果がlinebot経由で届くでしょう。

# raspiの起動時に任意の処理を実行する方法

`sudo vi /etc/rc.local`
して、exit 0より上にさっきのnodeを実行するコマンドを入れる
rc.localはraspi起動時に実行されるので覚えておくと便利

ファイルはフルパスで指定すること(作った.jsのディレクトリでpwdしてパス確認する)

`node /home/pi/notice_ip.js`とか

これだけだとraspi起動時にIP取得前にjsが実行されてうまくいかないので、
`sudo raspi-config` → `Wait for network at Boot` → `Slow Wait for network connection before completing boot`
を設定しておく。

rc.localはデフォルト無効で、使いたいときは所有者(root)に実行権限をつける必要がある
rc.localをこれまで触ったことがない場合、
`sudo chmod u+x /etc/rc.local`
して所有者(root)に実行権限をつける必要がある

これで`sudo reboot`して、raspiが再起動してlineに通知がくれば完成！

# お疲れ様でした。
これでraspi起動時に毎回ディスプレイにつながなくてよくなりました。
よかったよかった。

# 後から思った
line notifyなるものがあるらしい、固定の宛先へのpushだけならこっちのが楽かも

(参考)LineNotifyのサンプルをLaravelでサクッと試してみた
http://qiita.com/ichikawa_0829/items/fd85cd5f73b3d297a5b1