LINE BotサーバーをNestJSで開発する その1

# はじめに

[NestJS](https://nestjs.com/)はNode.jsのサーバーサイドアプリケーションを効率よく開発するためのフレームワークです。標準で[Express](https://expressjs.com/)、[Fastify](https://www.fastify.io/)をプラットフォームとしたサーバーが開発可能で、各プラットフォームに対して依存度の低い開発が可能です。生成されるプロジェクトがTypeScriptなのも大きいですね。

NestJSで開発用のプロジェクトを生成するには以下のようにします

```shell
$ npm i -g @nestjs/cli
$ nest new project-name
```

これだけで開発に必要な環境、サンプルコードが自動的に生成されます。NestJSの始め方については[本家のFirst Step](https://docs.nestjs.com/first-steps)などを参照してください。

今回は、このNestJSを使って簡単なLINE Botエコーサーバーを作ってみようと思います。[以前公開したLINE Botサーバーの作り方](https://qiita.com/bathtimefish/items/34e128cb2578c4db0845)はFastifyで開発しましたが、だいぶ古くなっているので、現在の技術で再開発してみます。

# 使ってみる

完成品はこちらです
https://github.com/bathtimefish/line-botserver-example-nestjs/tree/v1

送信したメッセージをオウム返しする単純なエコーサーバーです
![sc-line-bot-nestjs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/9a9ca565-2b68-939b-bb18-c5d7f6f5f1bc.png)

# セットアップする

まず、[こちら](https://qiita.com/bathtimefish/items/34e128cb2578c4db0845#messaging-api%E3%83%81%E3%83%A3%E3%83%8D%E3%83%AB%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B)を参考にLINE Developers ConsoleからMessaging APIチャンネルを作成してください。



次に、[こちら](https://qiita.com/bathtimefish/items/34e128cb2578c4db0845#ec2-%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%82%92%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E3%81%99%E3%82%8B)のようにAWS EC2等でVMインスタンスを立ち上げ、node.jsをセットアップします。

[こちら](https://qiita.com/bathtimefish/items/34e128cb2578c4db0845#lets-encrypt%E3%82%92%E5%B0%8E%E5%85%A5%E3%81%99%E3%82%8B)を参考にLet's Encriptでサーバー証明書を作成してください。Bot ServerがLINE PlatformからのWebhookリクエストを受信するためにはSSL証明書を持ったWebサーバーである必要があります。

以上で、下準備ができました。

以下でNestJS Bot Serverのレポジトリをcloneします

```shell
git clone -b v1 https://github.com/bathtimefish/line-botserver-example-nestjs
```

依存モジュールをインストールします

```shell
cd line-botserver-example-nestjs
npm i
```

.envファイルを作成します。`SSL_KEY_PATH`にはLet's Encriptで生成した`privkey.pem`のパス、`SSL_CERT_PATH`には`fullchain.pem`のパスを設定します。

`CHANNEL_ACCESS_TOKEN`にはMessaging APIチャンネルのCHANNEL ACCESS TOKEN、`CHANNEL_SECRET`にはCHANNEL SECRETをそれぞれ設定してください。

```.env
SSL_KEY_PATH=[YOUR SSL KEY FILE PATH]
SSL_CERT_PATH=[YOUR SSL CERT FILE PATH]
CHANNEL_ACCESS_TOKEN=[YOUR CHANNEL ACCESS TOKEN]
CHANNEL_SECRET=[YOUR CHANNEL SECRET]
```

設定できたら以下のコマンドでBotサーバーを起動します。

```shell
npm run start
```

以下のようにサーバーが起動します。

```shell
npm run start

> line-botserver-example-nestjs@0.0.1 start
> nest start

[Nest] 2825  - 10/29/2023, 6:41:32 AM     LOG [NestFactory] Starting Nest application...
[Nest] 2825  - 10/29/2023, 6:41:33 AM     LOG [InstanceLoader] AppModule dependencies initialized +17ms
[Nest] 2825  - 10/29/2023, 6:41:33 AM     LOG [InstanceLoader] MessagingModule dependencies initialized +0ms
[Nest] 2825  - 10/29/2023, 6:41:33 AM     LOG [RoutesResolver] AppController {/}: +14ms
[Nest] 2825  - 10/29/2023, 6:41:33 AM     LOG [RouterExplorer] Mapped {/, GET} route +4ms
[Nest] 2825  - 10/29/2023, 6:41:33 AM     LOG [RoutesResolver] MessagingController {/messaging}: +0ms
[Nest] 2825  - 10/29/2023, 6:41:33 AM     LOG [RouterExplorer] Mapped {/messaging, GET} route +0ms
[Nest] 2825  - 10/29/2023, 6:41:33 AM     LOG [RouterExplorer] Mapped {/messaging, POST} route +1ms
[Nest] 2825  - 10/29/2023, 6:41:33 AM     LOG [NestApplication] Nest application successfully started +3ms
```

最後に[こちら](https://qiita.com/bathtimefish/items/34e128cb2578c4db0845#messaging-api%E3%83%81%E3%83%A3%E3%83%8D%E3%83%AB%E3%81%AEwebhook%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B)を参考にMessaging APIチャンネルのWebhook URLを設定してリクエストの検証をします。今回のWebhook URLは以下のような感じで `https://[YOUR_DOMAIN]:3000/messaging` のように設定してください。

![スクリーンショット 2023-10-29 15.08.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/8072058b-8a62-d769-bdab-6e4de7989e30.png)

`Verify`ボタンをクリックすると、以下のようなエラーが発生し、サーバーサイドでも例外`Cannot read properties of undefined (reading 'message')`がスローされます。

![スクリーンショット 2023-10-29 15.49.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61995/c6fe89dc-3783-91eb-bbf4-738141fccb70.png)

これはエラーですが、正常に送信されている証拠です。このBot ServerのPostハンドラはWebhookでPostされるリクエストボティがLINE Messaging APIのリクエストボティ構造体かどうかを検証しています。一方で、`Verify`ボタンをクリックしたときにPostされるリクエストボディは`{}`なので、Bot Server側でLINE Messaging APIのリクエストボティに必須の`message`プロパティが存在しないという例外が発生しています。

この状態でWebhook URLが妥当だという検証はできているので、LINE ChatでBotに対しメッセージを送るとオウム返しが返ってくるので安心してください。

Botサーバーを開発するたびにそもそも`Verify`ボタンで送信されるのが`{}`ってどうなのよ。。と思ってるんですが、わかってればクレーム出すほどのもんじゃないのでずっと放置されてるんでしょうか。ダミーのText Message Eventでも送ったほうが親切だと思うんですけどね。

# おわりに

NestJSベースのLINE Botサーバーを立ち上げて使ってみました。次回はこのサーバーのコードの要点などを解説していこうと思います。