Node.jsとLINE Bot SDKで作るLINE Bot開発チュートリアル

# はじめに
この記事では、LINE Botの開発方法について解説します。
具体的には、ユーザーからのメッセージを受け取り、オウム返しで返信するLINE Botを作成する手順を説明します。
![line.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/e980e414-502a-a140-9332-89254c69e143.jpeg)

このチュートリアルでは、Node.jsとLINE Bot SDKを使用してLINE Botを開発します。
[LINE Bot SDK](https://github.com/line/line-bot-sdk-nodejs)は、LINE Messaging APIを利用してLINE Botを作成するための公式SDKであり、開発を簡略化する多くの機能を提供しています。

このチュートリアルを通じて、LINE Botの基本的な開発手法を学び、自分だけのLINE Botを簡単に作成する方法を身につけることができます。

# メッセージの送信から受信まで
スマートフォンから送信されたメッセージが、オウム返しでLINEアプリに返信される流れは以下の通りです。
![req-res.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/85db4c38-a430-4458-3b68-7a31136fd0fc.png)

Expressフレームワークを使用してLINE BotのWebhookエンドポイントを作成します。
Expressは、Node.js用のWebアプリケーションフレームワークであり、簡単にWebサーバーを作成し、ルーティングやミドルウェアを追加できるように設計されています。

また、ngrokを使用してローカル開発環境を公開し、外部からアクセス可能なURLを生成します。
これはLINE BotのWebhookエンドポイントを外部に公開するために使用します。

これらのツールを組み合わせることで、LINE Botの開発を簡単に始めることができます。

# Line Bot の準備
まずは以下の公式サイトにアクセスします。

https://developers.line.biz/ja/

自分のLINEアカウントにログインします。
![login-line-developper.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/257c9ed4-c89e-c4bb-b31a-8b1087da09dc.png)

**作成**をクリックし、任意のプロバイダー名でプロバイダーを作成します。
![create-provider.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/3e98b746-0f06-a7a1-a0f5-1bca9f1ffbb3.png)

**Messaging API**を選択しチャネルを作成します。
チャネル名やアイコンは任意で設定して下さい。
![create-channel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/0c794d0c-e3cf-eac0-b74e-4e6e0cb0893a.png)

チャネルが作成できたら、**チャネル基本設定**から**チャネルシークレット**をメモしておきます。
![channel-secret.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/87687609-93bb-d4dd-6cad-cd164f0c8e5d.png)

次に、**Messaging API設定**から**チャネルアクセストークン**を発行し、メモしておきます。
![channel-access-token.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/d616fc34-d423-d49a-f588-2bdd72256db8.png)

最後に、**Messaging API設定**のQRコードを読み込み、LINE Botを登録しておきます。
![qr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/f6763c49-735f-cb8b-5da7-f18847ebcbb4.png)

LINE Botを登録すると、あいさつメッセージが送信されます。
![LINE.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/f1f782a4-7a95-9290-5475-63cfbd03c90e.jpeg)

# ngrokの設定
次に、ngrokの設定を行います。

ngrokは、ローカル開発環境を公開するためのツールです。
具体的には、ローカルで実行しているウェブサーバーを外部からアクセス可能なURLに公開し、開発中のアプリケーションのテストやデバッグを容易にします。
今回はExpressで作成したアプリケーションをngrokを使用して公開することで、LINE BotのWebhookエンドポイントを外部に公開し、LINEプラットフォームとの連携をすることができます。

まずは以下の公式サイトにアクセスします。

https://ngrok.com/

はじめての人はここからngrokの新規アカウントを作成してください。
![signup-ngrok.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/d34aa3f4-4b10-0628-d44f-cd6e1aecf374.png)

登録が完了したら実行すべきコマンドが表示されます。
![connect-ngrok.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/58ccd054-354b-16fa-3776-4ee192c3b534.png)

表示されたコマンドを実行していきます。
まずはngrokをインストールします。
```bash
$ brew install ngrok
（中略）
==> Installing Cask ngrok
==> Linking Binary 'ngrok' to '/usr/local/bin/ngrok'
🍺  ngrok was successfully installed!
```
インストールが完了したら、次のコマンドを使用してngrokの設定ファイルに認証トークンを追加します。
```bash
$ ngrok config add-authtoken XXXXXXX
Authtoken saved to configuration file: /Users/XXXX/Library/Application Support/ngrok/ngrok.yml
```
以上でngrokの設定が完了しました。

# Node.jsプロジェクトの作成
Node.jsプロジェクトを作成します。
以下のコマンドを実行して、package.jsonファイルを初期化します。
```bash
$ npm init -y
```

次に、ExpressとLINE Bot SDK、dotenv、ngrokをインストールします。
```bash
$ npm install express @line/bot-sdk dotenv ngrok
```

# プログラムの実装
`app.js`を作成し、プログラムを実装します。
```Javascript:app.js
const express = require("express");
const line = require("@line/bot-sdk");
const ngrok = require("ngrok");
require("dotenv").config();

const config = {
  channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN,
  channelSecret: process.env.CHANNEL_SECRET,
};

const app = express();

const client = new line.messagingApi.MessagingApiClient({
  channelAccessToken: config.channelAccessToken,
});

app.use("/webhook", line.middleware(config));
app.post("/webhook", (req, res) => {
  Promise.all(req.body.events.map(handleEvent)).then((result) =>
    res.json(result)
  );
});

function handleEvent(event) {
  if (event.type !== "message" || event.message.type !== "text") {
    return Promise.resolve(null);
  }

  return client.replyMessage({
    replyToken: event.replyToken,
    messages: [
      {
        type: "text",
        text: event.message.text,
      },
    ],
  });
}

const port = process.env.PORT || 3000;
app.listen(port, async () => {
  try {
    const ngrokUrl = await ngrok.connect(port);
    console.log(`Ngrok URL: ${ngrokUrl}/webhook`);
  } catch (error) {
    console.error("Error while connecting with ngrok:", error);
  }
});
```
メモしておいた**チャネルシークレット**と**チャネルアクセストークン**を`.env`ファイルに記載します。
```:.env
CHANNEL_ACCESS_TOKEN="Your LINE Access Token"
CHANNEL_SECRET="Your LINE Channel Secret"
```

# 実装の説明

### Expressと関連パッケージのインポート
```Javascript
const express = require("express");
const line = require("@line/bot-sdk");
const ngrok = require("ngrok");
require("dotenv").config();
```
Expressフレームワークと@line/bot-sdk、ngrok、dotenv（環境変数を読み込むためのツール）をインポートします。

### LINE Botの認証情報設定
```Javascript
const config = {
  channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN,
  channelSecret: process.env.CHANNEL_SECRET,
};
```
LINE Botの認証情報を設定するためのconfigオブジェクトを定義しています。

### Expressアプリケーションの設定
```Javascript
const app = express();

app.use("/webhook", line.middleware(config));
app.post("/webhook", (req, res) => {
  Promise.all(req.body.events.map(handleEvent)).then((result) =>
    res.json(result)
  );
});
```
Expressアプリケーションを作成し、Webhookエンドポイントを設定します。
/webhookエンドポイントにPOSTリクエストが送信されると、LINE Bot SDKのmiddlewareがリクエストを処理します。

### メッセージの処理
```Javascript
function handleEvent(event) {
  if (event.type !== "message" || event.message.type !== "text") {
    return Promise.resolve(null);
  }

  return client.replyMessage({
    replyToken: event.replyToken,
    messages: [
      {
        type: "text",
        text: event.message.text,
      },
    ],
  });
}
```
受信したイベントがメッセージであり、そのタイプがテキストメッセージである場合、オウム返しでメッセージを返信する処理が行われます。

### ローカルサーバーとngrokの設定
```Javascript
const port = process.env.PORT || 3000;
app.listen(port, async () => {
  try {
    const ngrokUrl = await ngrok.connect(port);
    console.log(`Ngrok URL: ${ngrokUrl}/webhook`);
  } catch (error) {
    console.error("Error while connecting with ngrok:", error);
  }
});
```
Expressアプリケーションを指定されたポートで起動し、ngrokを使用してローカルサーバーを公開します。
これにより、LINE BotのWebhookエンドポイントが外部からアクセス可能になります。

以上の手順により、基本的なLINE Botの機能を実装しました。

# ローカルサーバーの起動とngrokのURL取得
```bash
$ node app.js
Express server is listening on port 3000
Ngrok URL: https://XXXX.ngrok-free.app/webhook!
```
上記コマンドを実行すると、Expressサーバーがポート3000で起動します。
ローカルサーバーが公開された後、ngrokのURLが表示されます。
このURLをLINE DevelopersのWebhook URLに設定して、LINE BotのWebhookを有効にします。

# Webhook URL の設定
LINE Developersに再度ログインし、表示されたURLを**Webhook URL**に設定します。
![set-webhook.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/a3a4117c-0eae-3a53-4618-f35abe53ae74.png)
**Webhookの利用**もONに設定します。
![use-webhook.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/66d35ada-04c9-2d75-1d8f-cafb7a20a01d.png)
**検証**ボタンを押すと**成功**と出ます。
![success.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/aeb05823-f0e8-3a0b-e43a-29a4891af92a.png)

以上で設定が完了し、登録済みのLINE Botにメッセージを送信すると、オウム返しが返ってきます。
![line.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/e980e414-502a-a140-9332-89254c69e143.jpeg)

# まとめ
今回は、Node.jsとLINE Bot SDKを使用して、オウム返しするLINE Botを作成しました。
ただし、この実装はローカル環境でのみ動作しており、ボットを常時稼働させるには、AWS Lambdaなどの外部サーバーにデプロイする必要があります。

間違っている箇所や疑問に思ったことがあれば、ぜひコメントをください！
最後まで読んでいただき、ありがとうございました。

詳細なコードは、GitHubのリポジトリで公開しています。
興味のある方は是非チェックしてみてください。

https://github.com/GorillaSwe/line-bot-sdk-tutorial-nodejs