Heroku + LINE + node.js (Express.js)でオウム返しボットを作成する

#Heroku + LINE + node.js (Express.js)でオウム返しボットを作成する

　
※本記事は最終的にQ&Aチャットボットを構築するための一部分となります。
[本編はこちら](https://qiita.com/abemaki/items/8c611cc63ec109ab3835)



##何故、オウム返しなのか？

オウム返しはチャットボット構築の基礎中の基礎になります。
オウム返しすることで以下の３点が確認・理解できます。

①単純な疎通確認
　・今回だと、スマホ ←→ LINE ←→ メッセージングAPI ←→ Herokuで稼働するアプリまでの疎通確認になります

②単純な動作確認
　・LINEで発話した内容を正常に受信できることの確認
　・アプリケーションから発話した内容がLINEで正常に受信できることの確認

③疎通に必要な手順の理解、メッセージのやりとりに必要な手順の理解



はじめて使う技術でWebアプリケーション作成するときに最初にやるhello worldと同じですね。
単純なことですがこれらを最初にやるかやらないかでは技術の習得レベルに差が出ると思います。

　
　


##事前準備

###Visual Studio Code(以下、VSCode)をインストールします

**▼インストールはこちら**
https://azure.microsoft.com/ja-jp/products/visual-studio-code/

**何故、VScodeなのか？**
現状、最強の統合開発環境だと思っています。
長くeclipseの時代が続きましたが、以下を理由に最近はVSCodeしか使っていないです。
『とにかく軽い』、『しょぼいスペックのPCでも快適に使える』、『バグや癖がなく安定している』

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/dafb5ffa-242d-abfc-20ff-6492a7da81d2.png)


###Herokuのアカウントを作成しておきましょう
**▼Herokuはこちら**
https://jp.heroku.com/free

**何故、Herokuなのか？**
①クレジットカードの登録が不要
無料のアプリケーションプラットフォームサービスは沢山ありますが
クレジットカードの登録が不要で、制約が最も緩いのがHerokuだと思います。
ちょっとした技術検証や学習に向いたアプリケーションプラットフォームだと思います。

②情報が豊富
間口の広さがあってか、Herokuの利用に際して困ったことがあれば
情報が豊富なので、Google先生に聞けばほぼ解決できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/69896ea5-0b46-ad12-6e50-c37a40d99ce1.png)


###LINE BusinessIDに登録してメッセージングAPIの準備をしましょう

**▼LINE BusinessIDはこちら**
https://account.line.biz/login


↓↓↓ メッセージングAPI開始までの手順を別の記事で公開してます。

**▼LINEメッセージングAPIでLINEのロボットアカウントを作成する手順**
https://qiita.com/abemaki/items/76e240828aee92fbcff7



###ソースコードを格納するための作業フォルダを作成しておきましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/8c3d7932-cda1-e36b-6e01-dc594f42f84c.png)




##herokuで新規アプリを作成

####１．新規アプリ作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/e6a8b983-8638-619c-0120-8bbc8ed4160b.png)


####２．名前だけ決めてアプリ作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/6b98ffc4-f6e8-d298-ca0f-b82a8a8c26f0.png)


####３．herokuの手順に従って、Gitアプリと接続します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/1cfeee44-29a3-c678-d51f-c63a99efed50.png)



herokuの手順に従い事前準備を行います。
コマンドプロンプトを使用します。


```console
heroku login
```

```console
cd /d D:\heroku\qandabot/ ← 事前に作成しておいたフォルダに移動します
git init
heroku git:remote -a qandabotdemo
```
　
　
　

ここまで順調だとおおおそ以下のような表示になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/fdcffa72-bf8c-efc0-bfbd-e5935bbbaf5d.png)





##アプリケーションの土台を作成します


####１．npm init　と　install で土台作り

ベースとなるアプリを作成して、必要なライブラリをアプリいっきにインストールします。

```console
npm init --y
npm install dotenv express xlsx elasticlunr cfenv request body-parser --save
```

　
各ライブラリの用途は以下にまとめてあります。

| リソース     | 説明                                  |
|--------------|--------------------------------------|
| dotenv       | 環境設定ファイルの読み込みに活用       |
| express      | Webサーバとして活用                   |
| xlsx         | エクセルの読み込みに活用              |
| elasticlunr  | JSの全文検索エンジンとして活用        |
| body-parser  | リクエストの解釈を簡易化するために活用 |
| request      | LINEに応答リクエストを返すために活用   |
| cfenv        | 環境情報の取得を簡易化するために活用   |

　
　


####２．作成したリソースベースにVSCode上で開発を進めます

##### VSCodeでリソース（作業用フォルダ）を開きます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/57ad3083-258e-dea9-85f8-e8935c2a128a.png)

　
　

##### .env(環境設定ファイル)ファイルを作成します

LINEメッセージングAPIの設定情報を.envファイルに記述します
最終的にLineメッセージングAPI と LINEシュミレータを切り替えながら開発することになるので
環境設定情報は環境設定ファイルに書いておくと後々とても便利です。

**記述用テンプレート**
事前準備で用意したLineメッセージングAPIの設定情報を.envファイルに書いていきます

```console
# LINEメッセージングAPIの設定情報
Channel_secret=＜チャネルシークレット＞
Channel_user_id=＜チャネルユーザーID＞
Channel_access_token=＜チャネルアクセストークン＞
Channel_endpoint=https://api.line.me/v2/bot/message/reply
```

　
　
　

##### index.jsファイルを作成します

下記を参考(コピペ)にindex.jsファイル内に
オウム返しの為の処理を記述していきます。



```javascript

// ******************************************************************//
// ** 初期設定関連 ここから                                          **//
// ******************************************************************//
var express = require("express");
var app = express();
var cfenv = require("cfenv");
require('dotenv').config();
var request = require("request");
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({
  extended: true
}));
app.use(bodyParser.json());

// ******************************************************************//
// ** 設定情報の取得 ここから                                        **//
// ******************************************************************//
// LINEの設定
var urlLine = process.env.Channel_endpoint

// BOTの標準キー
var botKey = process.env.Channel_access_token

// ******************************************************************//
// ** メッセージ処理 ここから                                      **//
// ******************************************************************//
const asyncwrap = fn => (req, res, next) => fn(req, res, next).catch(next);
app.post("/api", asyncwrap(async (req, res) => {

    // 受信テキスト
    var userMessage = req.body["events"][0]["message"]["text"];

    // とりあえずオウム返し
    options = createAnsMessage(req , userMessage + "って言いましたね？");

    // メッセージを返す
    request(options, function(err, res, body) {
    });
    res.send("OK");
}));

// ******************************************************************//
// **   ファンクション処理 ここから                                  **//
// ******************************************************************//
// ---- ************************ -------
// ---- 一答形式の回答を作成する   -------
// ---- ************************ -------
function createAnsMessage(req,message){
    var options = {
        method: "POST",
        uri: urlLine,
        body: {
            replyToken: req.body.events[0].replyToken,
            messageNotified: 0,
            messages: [
                // 基本情報
                {
                    contentType: 1,
                    type: "text",
                    text: message,
                }
            ]
        },
        auth: {
            bearer : botKey
        },
        json: true
    };
    return options;
}

// サーバ起動
var appEnv = cfenv.getAppEnv();
app.listen(appEnv.port, "0.0.0.0", function() {
  console.log("server starting on " + appEnv.url);
});

```




　
　


##### package.jsonのscripts要素の中を修正します

これによりnpm startコマンドでアプリケーションが起動できるようになります。
node index.jsでも起動できますが、起動ファイルがシステムによって異なるのでどのシステムでも
npm startで起動できようにしておくと便利です。

```javascript
  "scripts": {
    "start": "node index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
```


####３．動作確認の為のここでherokuにコミット＆プッシュします

herokuの公式手順に従います

```console
git add .
git commit -am "動作確認の為のオウム返し"
git push heroku master
```

　
　

####４．herokuのエンドポイントをLINEメッセンジャーAPIに設定する

エンドポイントをherokuで確認 
今回作成するアプリだと最終的なエンドポイントは『エンドポイント/api』になります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/ae056327-58df-d1e8-e157-6af3d2ee41bc.png)
　

　
エンドポイントをLINEメッセンジャー側のWebhookに設定します　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/3a825f1b-0282-7a40-ae60-16ae109639df.png)

　
 
Webhookを設定したら、検証して問題ないことを確認し
Webhookを有効化します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/83524d99-08d6-6442-a49b-ded60a4b08aa.png)


　
####５．LINEからBOTに話しかけて、オウム返しが動作することを確認します

QRコードから友達登録して話しかけてみてテストします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/4bfc7482-e640-e5b9-a9c7-13760b456d6f.png)

　

これで疎通やメッセージのやりとりに必要な作業は一通り完了です。