犬の癒し力でやめたい習慣にサヨナラするLINEBotの作り方

## 背景
人間の欲望は際限がなく、コントロールを失った先にあるのは不健康と後悔の念ばかりです。

あなたもそうでしょうか。

過剰な甘味、塩味、アルコール、ニコチン、タール、射倖心、推し、ガチャ、アブラ…

現代社会において、なりたい自分との間に居並ぶハードルは枚挙に遑がありません。

本記事では、こうした欲求への意思決定の間に**LINEBot**をカマすことによって、一旦冷静になるプランをご提案いたします。


<img width="400" alt="dog" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480342/9f2e70f9-f10b-29eb-56a4-46daabf90069.jpeg">

## やりたいこと
・LINEで、犬と相談してる感じになりたい
・欲求（お酒・たばこ）を諫めるランダムな返答が欲しい
・欲求が落ち着くまで時間稼ぎできるBotが欲しい

## 環境
Node-RED v3.0.2
LINE Developers
LINE Messaging API
Dog API （[https://dog.ceo/dog-api](https://dog.ceo/dog-api/ "dog-api")）

## つくりかた
### 0.シナリオの概要
Botとの会話は「開始、相談、終了」の3パターン用意します。

・ 開始
　ユーザーからの問いかけに対して、定型文＋**犬画像**を応答

・ 相談
　ユーザーからの相談（お酒・たばこ）に対して、定型文を**ランダムに**応答

・ 終了
　ユーザーからの問いかけに対して、定型文＋**犬画像**を応答

### 1.LINE Botの準備
[LINEビジネスID](https://manager.line.biz/) にログインし、Bot用のアカウントを作成します。

https://developers.line.biz/ja/docs/messaging-api/building-bot/#line-manager-settings

LINE公式アカウントのセッティングは、こちらのQiita記事に詳しく整理されているので参考にしてください！

https://qiita.com/okinakamasayoshi/items/4597b1534597c20de438

### 2.LINE Botの応答メッセージ作成
会話の開始、終了はLINE Official Account Managerの「応答メッセージ」機能を使用します。
![LINE_bot_reply.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480342/08cce46f-8ff4-b242-7024-1364394cba90.png)

ユーザーへの返信文を「応答メッセージ」の内容に記載することで、Node-RED側では犬画像の返答のみを実行しています。

### 3.LINE Botのリッチメニュー作成
Botへの発話はテキスト入力を使用せず、すべてリッチメニューから実行します。
![LINE_bot_menu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480342/2b07797f-5173-115d-9ce0-ce826f97ae5e.png)


4分割された各パーツに発話テキストを設定することで、後工程の分岐に正しく入れるようコントロールしています。
![LINE_bot_menu_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480342/c92585d6-daf5-03bc-2084-1d4351f615a8.png)

:::note info
LINEのリッチメニューはCanvaのテンプレートを使うと簡単に作れちゃいます。
https://www.canva.com/ja_jp/line-rich-menu/templates/
:::


### 4.犬画像の取得とランダム返答
Node-REDでWebhookを受け取り、メッセージの内容に応じて「ランダム返答」か「dog.apiの呼び出し」に分岐します。
・処理フロー
![LINE_bot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480342/1170c0d8-0005-90ff-bded-761b4622a247.png)
・フローをJSON形式でExportしたもの
```JSON:JSON
[{"id":"fde0f87092ee6138","type":"random","z":"3a35c5e3efe28d3a","name":"","low":1,"high":"3","inte":"true","property":"payload","x":420,"y":100,"wires":[["53dc6345737d043f"]]},{"id":"ac987116ea198203","type":"Webhook","z":"3a35c5e3efe28d3a","name":"","url":"/webhook_dog","x":120,"y":60,"wires":[["dfd37cef9d3f0395"]]},{"id":"76e94b32bc2e2b5c","type":"ReplyMessage","z":"3a35c5e3efe28d3a","name":"","replyMessage":"","x":900,"y":100,"wires":[]},{"id":"771ee275ec3dcc36","type":"change","z":"3a35c5e3efe28d3a","name":"","rules":[{"t":"move","p":"payload.message","pt":"msg","to":"payload2","tot":"msg"},{"t":"delete","p":"payload","pt":"msg"},{"t":"set","p":"payload.type","pt":"msg","to":"image","tot":"str"},{"t":"set","p":"payload.originalContentUrl","pt":"msg","to":"payload2","tot":"msg"},{"t":"set","p":"payload.previewImageUrl","pt":"msg","to":"payload2","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":720,"y":320,"wires":[["45a10102887e3c8d"]]},{"id":"e1d534794ba01b81","type":"http request","z":"3a35c5e3efe28d3a","name":"Random_Dog","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://dog.ceo/api/breeds/image/random","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":480,"y":320,"wires":[["771ee275ec3dcc36"]]},{"id":"d894da80c9392e45","type":"ReplyMessage","z":"3a35c5e3efe28d3a","name":"","replyMessage":"","x":900,"y":220,"wires":[]},{"id":"45a10102887e3c8d","type":"ReplyMessage","z":"3a35c5e3efe28d3a","name":"","replyMessage":"","x":900,"y":320,"wires":[]},{"id":"60c81a58844e6a98","type":"switch","z":"3a35c5e3efe28d3a","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"アルコール","vt":"str"},{"t":"eq","v":"ニコチン","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":3,"x":270,"y":160,"wires":[["fde0f87092ee6138"],["c0c1058463a91d7c"],["e1d534794ba01b81"]]},{"id":"c0c1058463a91d7c","type":"random","z":"3a35c5e3efe28d3a","name":"","low":1,"high":"3","inte":"true","property":"payload","x":420,"y":160,"wires":[["fa4c9f0bd449cf6c"]]},{"id":"53dc6345737d043f","type":"switch","z":"3a35c5e3efe28d3a","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"str"},{"t":"eq","v":"2","vt":"str"},{"t":"eq","v":"3","vt":"str"}],"checkall":"true","repair":false,"outputs":3,"x":550,"y":100,"wires":[["04c0a8503c89516e"],["b6419cd48ee5f7f0"],["540448eaecd4b658"]]},{"id":"fa4c9f0bd449cf6c","type":"switch","z":"3a35c5e3efe28d3a","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"str"},{"t":"eq","v":"2","vt":"str"},{"t":"eq","v":"3","vt":"str"}],"checkall":"true","repair":false,"outputs":3,"x":552,"y":185,"wires":[["30a34abfd867c2b5"],["feb887ea272e1a63"],["1a6f797143131532"]]},{"id":"04c0a8503c89516e","type":"template","z":"3a35c5e3efe28d3a","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"酒は強くない者には勝てぬ。\nその勝負に出ること自体が偉業じゃ。\n一歩踏み出す勇気を持てば、未来は自分で創り出せるのじゃよ！","output":"str","x":720,"y":60,"wires":[["76e94b32bc2e2b5c"]]},{"id":"b6419cd48ee5f7f0","type":"template","z":"3a35c5e3efe28d3a","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"酒は時に人を変え、時に心を壊すものじゃ。\n少しずつでも前進する気持ちを持てば、\n自分自身を変えることができるのじゃよ！","output":"str","x":720,"y":100,"wires":[["76e94b32bc2e2b5c"]]},{"id":"540448eaecd4b658","type":"template","z":"3a35c5e3efe28d3a","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"酒は人生における暴風雨のようなものじゃ。\nじゃが、暴風雨を乗り越えれば、\n美しい虹が見えるものじゃよ。\n\n自分自身に対する思いやりを持ち、\n一歩ずつ前進することを忘れずにの！","output":"str","x":720,"y":140,"wires":[["76e94b32bc2e2b5c"]]},{"id":"30a34abfd867c2b5","type":"template","z":"3a35c5e3efe28d3a","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"自由とは...自分自身を支配することじゃ。\n\nタバコをやめる決意を持ったなら、\n自分自身の支配者になることが大切じゃよ。","output":"str","x":720,"y":180,"wires":[["d894da80c9392e45"]]},{"id":"feb887ea272e1a63","type":"template","z":"3a35c5e3efe28d3a","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"人生はそんなに長くないのじゃ。\n\n健康を取り戻し、人生を全うするために、\nタバコをやめる勇気を持ってみるといいじゃよ。","output":"str","x":720,"y":220,"wires":[["d894da80c9392e45"]]},{"id":"1a6f797143131532","type":"template","z":"3a35c5e3efe28d3a","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"タバコは心と身体に深い傷を残すものじゃ。\n\nじゃが、心と身体は自然治癒力を持っている。\nタバコをやめることで、\nその力を引き出すことができるのじゃよ！","output":"str","x":720,"y":260,"wires":[["d894da80c9392e45"]]},{"id":"dfd37cef9d3f0395","type":"delay","z":"3a35c5e3efe28d3a","name":"","pauseType":"delay","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":140,"y":160,"wires":[["60c81a58844e6a98"]]}]
```
分岐はswitchノードを使用し、LINE側の「応答メニュー」に登録された単語によってどのルートに入るか制御しています。
今回の場合、「B : アルコール」、「C : ニコチン」以外は dog.api を叩きにいくようにしています。
![LINE_bot_switchnode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480342/109e1b7e-6f27-3c43-0756-b0d854be4ba2.png)

:::note info
Node-REDフローのポイント
* delay : **即答させない**（対話の雰囲気を出す）ため、2秒delayを挿入
* random : templateノード内の返信を3パターンずつ作成し、**ランダムに回答**
* change : dog_apiの結果（画像URL）を**LINEのリプライ用**に加工
:::

changeノードの処理は下記のQiita記事を参考にしました。

https://qiita.com/youtoy/items/287a0782fdd185fc2004


犬の画像はDog APIから取得しています。

https://dog.ceo/dog-api/

Dog APIは[Stanford Dogs Dataset](http://vision.stanford.edu/aditya86/ImageNetDogs/ "Stanford Dogs Dataset")を元に作成された無料のデータセットで、APIを叩くとランダムな犬画像を返してくれます。

実行例 : https://dog.ceo/api/breeds/image/random

```JSON:結果
{
    "message": "https://images.dog.ceo/breeds/terrier-silky/n02097658_1356.jpg",
    "status": "success"
}
```
![images.dog.ceo](https://images.dog.ceo/breeds/terrier-silky/n02097658_1356.jpg)

## 実行結果

https://twitter.com/mitoreterusuki/status/1649699562880401410

## おわりに

無料ツールの組み合わせと先人の知恵を集めると、短時間でそれっぽいものが出来上がりました！

今回はBotの返答をNode-REDのtemplateノード内に直書きしていますが、ChatGPTのAPIを組み合わせるとランダム返答bot化できそうです。

あと、Google SpreadsheetsのAPIと繋げて「いつ、どんな欲求が生じて、我慢できたかどうか」を記録するのも面白いかも。

**父の日のプレゼントにLINEBot**、というのもアリかもしれませんね。
（LINEの利用推奨年齢は12歳以上です。開発への影響は各自ご確認ください🐰🐻）

https://line-ja.officialblog.jp/archives/80472765.html


以上！