Node-REDでLINE Chat Botを作る（連携 編）#2

#はじめに
この記事では Node-Red を用いて LINE Chat Bot を簡単に作ることを解説する記事のパート2です
前回の記事は[こちら](https://qiita.com/TatsuyaOkazaki/items/326d1f8e556d606065df)になります
用いるサービスのUIは本記事の作成時のものになりますのでご注意ください
#実装（連携）
それでは LINE Chat Bot 実装のツール連携を初めて行きます
##Node-Redの準備
###1. Node-REDフローエディターを開く
###2. フローを作成する
フローエディターを表示した状態で画面右上にカーソルを合わせて「**読み込み**」をクリックする
![スクリーンショット 2020-09-16 0.40.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518214/ad71a431-90a8-0a1e-ecac-05c96c565577.png)
出現した画面に下記の**flow.json**をコピー&ペーストして「**読み込み**」をクリックする
![スクリーンショット 2020-09-16 0.53.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518214/f84925cd-2068-d736-4f34-0d21fd88b734.png)

```json:flow.json
[
    {
        "id": "c7617f8f.a6007",
        "type": "inject",
        "z": "368b7b38.6190c4",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "true",
        "payloadType": "bool",
        "x": 370,
        "y": 440,
        "wires": [
            [
                "35c03a55.ee2fe6"
            ]
        ]
    },
    {
        "id": "d830b253.dd6ba",
        "type": "http request",
        "z": "368b7b38.6190c4",
        "name": "Reply Message",
        "method": "POST",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "https://api.line.me/v2/bot/message/broadcast",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "x": 540,
        "y": 500,
        "wires": [
            [
                "5e157368.6d05ac"
            ]
        ]
    },
    {
        "id": "35c03a55.ee2fe6",
        "type": "function",
        "z": "368b7b38.6190c4",
        "name": "createBroadcastMessage",
        "func": "\n\nvar post_request = {\n    \"headers\": {\n        \"content-type\": \"application/json; charset=UTF-8\",\n        \"Authorization\": \" Bearer \" + \"{LINE アクセストークン}\"\n    },\n    \"payload\": {\n        \"messages\": [\n            {\n                \"type\": \"text\",\n                \"text\": \"テストブロードキャスト配信\"\n            }\n        ]\n    }\n};\n\nreturn post_request;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 570,
        "y": 440,
        "wires": [
            [
                "d830b253.dd6ba"
            ]
        ]
    },
    {
        "id": "5e157368.6d05ac",
        "type": "debug",
        "z": "368b7b38.6190c4",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "complete": "true",
        "x": 730,
        "y": 500,
        "wires": []
    },
    {
        "id": "b7db538e.f2273",
        "type": "http in",
        "z": "368b7b38.6190c4",
        "name": "Webhooks",
        "url": "/line_hook",
        "method": "post",
        "upload": false,
        "swaggerDoc": "",
        "x": 240,
        "y": 160,
        "wires": [
            [
                "3f9f1fa8.9631b"
            ]
        ]
    },
    {
        "id": "3f9f1fa8.9631b",
        "type": "function",
        "z": "368b7b38.6190c4",
        "name": "getText",
        "func": "//flowへ格納\nflow.set(\"replyToken\",msg.payload.events[0].replyToken);\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 400,
        "y": 160,
        "wires": [
            [
                "765403fc.a9c3ec",
                "910773b2.078eb",
                "63ef745e.e9f4ec"
            ]
        ]
    },
    {
        "id": "765403fc.a9c3ec",
        "type": "debug",
        "z": "368b7b38.6190c4",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 630,
        "y": 200,
        "wires": []
    },
    {
        "id": "910773b2.078eb",
        "type": "http response",
        "z": "368b7b38.6190c4",
        "name": "",
        "statusCode": "",
        "headers": {},
        "x": 610,
        "y": 160,
        "wires": []
    },
    {
        "id": "460d5d43.76afa4",
        "type": "http request",
        "z": "368b7b38.6190c4",
        "name": "Reply Message",
        "method": "POST",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "https://api.line.me/v2/bot/message/reply",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "x": 880,
        "y": 320,
        "wires": [
            [
                "8888c28d.962be"
            ]
        ]
    },
    {
        "id": "880aa2be.79c51",
        "type": "function",
        "z": "368b7b38.6190c4",
        "name": "createReplyMessage",
        "func": "var post_request = {\n    \"headers\": {\n        \"content-type\": \"application/json; charset=UTF-8\",\n        \"Authorization\": \" Bearer \" + \"{LINE アクセストークン}\"\n    },\n    \"payload\": {\n        //\"replyToken\": msg.payload.events[0].replyToken,\n        \"replyToken\": flow.get(\"replyToken\"),\n        \"messages\": [\n            {\n                \"type\": \"text\",\n                \"text\": msg.payload.optext\n            }\n        ]\n    }\n};\n\nreturn post_request;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 660,
        "y": 320,
        "wires": [
            [
                "460d5d43.76afa4"
            ]
        ]
    },
    {
        "id": "8888c28d.962be",
        "type": "debug",
        "z": "368b7b38.6190c4",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "complete": "true",
        "x": 1050,
        "y": 320,
        "wires": []
    },
    {
        "id": "c50dd18b.5a55e",
        "type": "watson-conversation-v1",
        "z": "368b7b38.6190c4",
        "name": "",
        "workspaceid": "",
        "multiuser": false,
        "context": true,
        "empty-payload": false,
        "service-endpoint": "https://gateway.watsonplatform.net/assistant/api",
        "timeout": "",
        "optout-learning": false,
        "x": 620,
        "y": 240,
        "wires": [
            [
                "9da5f913.eb5148"
            ]
        ]
    },
    {
        "id": "d16c593a.016d38",
        "type": "debug",
        "z": "368b7b38.6190c4",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 630,
        "y": 360,
        "wires": []
    },
    {
        "id": "9da5f913.eb5148",
        "type": "change",
        "z": "368b7b38.6190c4",
        "name": "Watsonの戻り値から変数に格納",
        "rules": [
            {
                "t": "set",
                "p": "payload.optext",
                "pt": "msg",
                "to": "payload.output.text.0",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 370,
        "y": 320,
        "wires": [
            [
                "d16c593a.016d38",
                "880aa2be.79c51"
            ]
        ]
    },
    {
        "id": "63ef745e.e9f4ec",
        "type": "change",
        "z": "368b7b38.6190c4",
        "name": "Watson向けにパラメータ入替え",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload.events.0.message.text",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 370,
        "y": 240,
        "wires": [
            [
                "c50dd18b.5a55e"
            ]
        ]
    },
    {
        "id": "42424978.cf33c8",
        "type": "comment",
        "z": "368b7b38.6190c4",
        "name": "IBM Watson Asistant 自動応答",
        "info": "",
        "x": 930,
        "y": 220,
        "wires": []
    },
    {
        "id": "affc262d.1d6bd8",
        "type": "comment",
        "z": "368b7b38.6190c4",
        "name": " Broadcast 配信部分",
        "info": "",
        "x": 830,
        "y": 440,
        "wires": []
    }
]
```

出現したノードを貼り付けて「**デプロイ**」をクリックする
![スクリーンショット 2020-09-16 0.57.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518214/c7eda8d2-85c4-0a56-ce34-539483ace980.png)

##LINE チャンネルへNode-REDをつなげる ＋ 設定
###1. LINE Developers[コンソール](https://developers.line.biz/console/)を開く
###2. 前回作成したプロバイダーをクリックする
###3. 前回作成したチャンネルをクリックする
「**Messaging API 設定**」をクリックする
![スクリーンショット 2020-09-16 1.33.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518214/76830c04-f77c-9e8a-f6b2-f4954c63d1e8.png)

各項目の説明と設定を次に示します

- QRコード
    - このQRコードを読み取ることでチャットボットを友達登録できます
- Webhook設定
    - 「**編集**」をクリックしてURLを入力して更新を押し設定します
    - URLはNode-REDのフローエディターのURLをコピーして**red/#flow**より後ろを消して後ろに**line_hook**を加えたものです
    - **https://ココはNode-REDを設定したときに変化します.mybluemix.net/line_hook**
- グループ・複数人チャットへの参加を許可する
    - 今回はそのままで良いです
- 応答メッセージ
    - 無効に変更します
- あいさつメッセージ
    - 無効に変更します
- チャンネルアクセストークン
    - 発行をクリックします
    - **出現したコードをコピーしてください**　※後ほどNode-REDで使用します

![スクリーンショット 2020-09-16 1.42.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518214/840c9034-c27f-2bb0-6c11-c1201ae03c68.png)

以上で設定はおわりです

##Node-RED へLINE チャンネルをつなげる
###1. Node-RED フローエディターを開く
###2. ノードのコードを編集する
「**create Reply Message**」と「**create Broadcast Message**」をダブルクリックしてノードのソースコードを編集します
編集する箇所は```{LINE アクセストークン}```です
中かっこは残して中身を先ほど発行したLINEのチャンネルアクセストークンに貼り替えてください
![スクリーンショット 2020-09-16 20.01.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518214/01e55f81-51bb-960d-9df4-be9ede6168f3.png)
###3. 変更を反映する（デプロイ）
ノードのコード編集が完了したら「**デプロイ**」をクリックして編集したコードをNode-REDに反映させます
![スクリーンショット 2020-09-16 20.06.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518214/931a4f0b-9968-171a-b880-e95c686d231c.png)
以上で設定はおわりです

##動作確認
###1. チャットボットを友達登録させる
**Node-RED へLINE チャンネルをつなげる** の項目で表示したQRコードを読み取ってチャットボットを友達登録します．
###2. Node-REDからチャットボットに向けてテストメッセージを送信する
Node-REDフローエディターにて下の画像の**trueノード**の左側の四角をクリックしてください
![スクリーンショット 2020-09-16 20.15.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518214/bb31cdfb-00af-bbdd-2b65-89158020e556.png)
LINEチャットボットから「**テストブロードキャスト配信**」というメッセージが届くと思います
Node-REDとLINEチャットボットの連携が完了しました
###3. 配信される文を変更する
今回の配信は ブロードキャスト配信（一斉送信）を用いておりその内容を簡単に変更することができます
「**create Broadcast Message**」をダブルクリックしてノードのソースコードを編集します
ソースコード内の「**テストブロードキャスト配信**」を適当な文字に編集することで配信させる文を変更できます
![スクリーンショット 2020-09-16 20.25.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518214/2352ff59-4b7c-9667-6206-2d083b26f5fb.png)
編集が完了したらデプロイをクリックして編集を反映させます
![スクリーンショット 2020-09-16 20.06.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518214/e7d5ca89-c039-dbf5-aa57-bc7067de51b0.png)
Node-REDフローエディターにて下の画像の**trueノード**の左側の四角をクリックしてください
![スクリーンショット 2020-09-16 20.15.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518214/bb31cdfb-00af-bbdd-2b65-89158020e556.png)
配信される文字が変化したことが確認できたと思います
ここの文字をプログラムによって様々な形に変化させることでよりフレキシブルな配信が可能になります

#おわり
今回はここまでで終了です
LINE チャットボットとNode-REDを連携して動作確認までを行いました
次回ではIBM Cloud Watson Assistant を用いて入力された文字に対する応答を生成するAIを連携・実装していきます

#注意事項
用いたサービスのUIは本記事の作成時のものになりますのでご注意ください．
またミスなどがあればご指摘いただけると有り難いです

#参考資料
- [LINEチャットボットとWatsonを連携する (2020/09/16 現在)](https://medium.com/@taiponrock/line%E3%83%81%E3%83%A3%E3%83%83%E3%83%88%E3%83%9C%E3%83%83%E3%83%88%E3%81%A8watson%E3%82%92%E9%80%A3%E6%90%BA%E3%81%99%E3%82%8B-8a7d89a49e57)