docker+heroku(container registry)でline botを開発するための環境を構築する

# 概要
　docker、heroku(container registry)を使用して、line botの開発環境を構築したため、その方法を共有する。

# 前提
　[line developers](https://developers.line.me/ja/)にアクセスし、チャンネルを作成し、ラインアクセストークン、ラインシークレットを取得する。ここでは、Message APIを用いる方法で作製すること。

参考記事

https://qiita.com/nkjm/items/38808bbc97d6927837cd

# 全体像
　dockerにて開発環境を構築し、それをそのままherokuへデプロイすることで簡単にlinebotを実現することができる。ローカル上で開発テスト行うのであれば、push通知などであればherokuへデプロイしなくても実施はできる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/717054/d811c7b0-c416-5842-906e-a7b7e815c8de.png)




# 1. Dockerfile, docker-compose.ymlの作成

```docker:Dockerfile
# docker-hubからベースのdocker imageをpull
FROM node:14.5.0-alpine

# コンテナ内で作業するディレクトリを指定
WORKDIR /app
```


```yml:docker-compose.yml
version: "3.0"

services:
  linebot:
    build: .
    restart: always
    tty: true
    ports:
      - 1212:1212
    volumes:
      - .:/app
```

以下のコマンドでイメージ作成しコンテナを起動。そして、コンテナ内に入る

```sh:sehll
$ docker-compose up -d --build       # イメージの作成、コンテナの起動
$ docker-compose exec linebot sh     # コンテナ内に入る
```

# 2. コンテナ内でのインストール作業
 以下のコマンドでパッケージをインストール。できたら`ctrl+d`でコンテナを抜ける。

```sh:shell（コンテナ内）
$ npm init --yes    # package.json作成
$ npm install --save express @line/bot-sdk   # packageのインストール
```

# 3. Dockerfile,docker-compose.ymlの変更

```docker:Dockerfile
FROM node:14.5.0-alpine

# ワークディレクトリ
WORKDIR /app

# コンテナ内で必要なパッケージをインストール
COPY package.json .
RUN npm install

# ホスト側カレントディレクトリ内部をコンテナ側にコピー
COPY . .

# 起動
CMD npm start   
```

```yml:docker-compose.yml
version: "3.0"

services:
  linebot:
    build: .
    restart: always
    tty: true
    ports:
      - 1212:1212
    env_file:
      - .env
    volumes:
      - .:/app
      - /app/node_modules
    entrypoint: >
      sleep 86400
```

# 4. その他のファイル作成

`npm start`で実行するコマンドを`package.json`のscript欄に追加。`index.js`を実行するように設定する。

```diff:package.json
  "scripts": {
-   "test": "echo \"Error: no test specified\" && exit 1"
+   "test": "echo \"Error: no test specified\" && exit 1",
+   "start": "node index.js"
  },
```

.envファイルの追加。

```:.env
LINE_CHANNEL_SECRET=[ラインチャンネルシークレット]
LINE_ACCESS_TOKEN=[ラインアクセストークン]
```

実行するファイル`index.js`の追加。`https://[アプリ名].herokuapp.com/bot/webhook`へアクセスしたら、HTTPレスポンスコード200を返すとしている。応答処理などは、`index.js`に記述する。

```js:index.js
// モジュールのインポート
const server = require("express")();
const line = require("@line/bot-sdk"); // Messaging APIのSDKをインポート

// パラメータ設定
const line_config = {
    channelAccessToken: process.env.LINE_ACCESS_TOKEN, // 環境変数からアクセストークンをセットしています
    channelSecret: process.env.LINE_CHANNEL_SECRET // 環境変数からChannel Secretをセットしています
};

// Webサーバー設定
server.listen(process.env.PORT || 1212);

// ルーター設定
// https://[アプリ名].herokuapp.com/bot/webhookでアクセスすると実行する関数
server.post('/bot/webhook', line.middleware(line_config), (req, res, next) => {
    res.sendStatus(200);
    console.log(req.body);
});

```


# 5. gitで管理
　gitの初期化。

```sh:shell
$ git init
```

`.gitignore`の追加。

```:.gitignore
npm-debug.log
node_modules
.env
```

# 6. herokuへのデプロイ

```sh:shell
# herokuにログイン
$ ​heroku login​

# heroku container registryにログイン
$ heroku container:login

# herokuアプリの作成
$ heroku create
```

　herokuのホームページで作成したアプリにアクセスし、環境変数を設定する。
setting->cofing varsで.envで設定した環境変数を設定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/717054/b65e9b11-50f3-f072-5307-b7cc58dd576e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/717054/12b5527b-5f9e-fc23-915f-4966e8c9ff4c.png)

デプロイは以下のコマンドで行う。`$ heroku open`はなくてもよい。ファイルを編集した際は毎回以下のデプロイ作業を行う事。

```sh:shell
# イメージをビルド(Dockerfileを実行)しcontainer registryにプッシュ
$ heroku container:push web

# herokuサーバー上でコンテナ起動
$ heroku container:release web

# アプリをブラウザで開き、エラーがねければOK
$ heroku open
```

# 7. line developerツールでの確認
　[line developers](https://developers.line.me/ja/)にアクセスし、前提で作成したチャネルのwebhookをオンにして、webhookURLに`https://[アプリ名].herokuapp.com/bot/webhook`を設定し、検証を押して成功と表示されればOK！
アプリ名は、`$ heroku open`を実行した際のURLを見たらわかる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/717054/10da9fe8-75c9-c216-1ad0-2aed45e31378.png)

# 8. line botを追加
　[line developers](https://developers.line.me/ja/)にアクセスし、作成したbotのMessage APIタブのQRでbotを追加する。メッセージの送信に対しての処理は、`index.js`で記述することができるため、以降は`index.js`を編集し、デプロイ作業を実施して開発を進めることができる。
　herokuへデプロイせずに応答を確かめるには、dockerのコンテナ内に入り、`$ node index.js`を実行する。

```sh:shell
$ docker-compose exec linebot sh   # コンテナの中に入る
$ node index.js                    # serverの立ち上げ
```

# さいごに
　間違っている個所があればご指摘おねがいします！

# **参考**
https://devcenter.heroku.com/ja/articles/heroku-cli#download-and-install

https://devcenter.heroku.com/ja/articles/container-registry-and-runtime