LINE Botの通知イベントをAWS Lambdaで受け取る

[前回](https://qiita.com/yuppejp/items/ff64f488a78f8c2bc595)はローカル環境でBotアプリからの通知イベントを受け取りましたが、今回はAWS Lambdaで実装してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77444/c0e4af4c-a63a-f91c-fbb7-1c85eaaf7f91.png)

大まかな作業の流れ：
1. botコードを作成
2. Lambda関数を作成
3. API Gatewayを設定
4. LINEアプリで動作確認
5. CloudWatchでLOGを見てみる

LINE Bot APIの初期設定などは[Serveoを使ってLINE botサンプルをローカル環境で試す](https://qiita.com/yuppejp/items/ff64f488a78f8c2bc595)を参考にしてください。

#botコードを作成
LINE bot SDKのecho-botサンプルを参考に作成していきます。ここでは、ローカル環境でテキストエディタを使って作業します。

```JavaScript:index.js
'use strict';
const line = require('@line/bot-sdk');
const AWS = require("aws-sdk");

// create LINE SDK config from env variables
const config = {
    channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN,
    channelSecret: process.env.CHANNEL_SECRET,
};

// event handler
exports.handler = function handleEvent(event, context) {
    const body = JSON.parse(event.body);
    const eventType = body.events[0].type;
    
    console.log(body);

    if (eventType === 'message') {
        const messageType = body.events[0].message.type;

        // テキストメッセージではない場合は無視
        if (messageType != 'text') {
            const lambdaResponse = {
                statusCode: 200,
                headers: { "X-Line-Status": "OK" },
                body: '{"result":"connect check"}'
            };
            return context.succeed(lambdaResponse);
        }

        const messageText = body.events[0].message.text;
        const replyToken = body.events[0].replyToken;

        // 接続テストの場合は無視
        if (replyToken == '00000000000000000000000000000000') {
            const lambdaResponse = {
                statusCode: 200,
                headers: { "X-Line-Status": "OK" },
                body: '{"result":"connect check"}'
            };
            return context.succeed(lambdaResponse);
        }

        // create a echoing text message
        const echo = { type: 'text', text: messageText };

        // create LINE SDK client
        const client = new line.Client(config);

        // use reply API
        return client.replyMessage(replyToken, echo);
    }
};
```

依存パッケージをインストールします。

```bash
$ npm install @line/bot-sdk
```

zipに圧縮します。このzipは後ほど、Lambda環境にアップロードするときに使用します。

```bash
$ zip -r echo-bot.zip index.js node_modules
```

#Lambda関数の作成
ここからは、AWSマネジメントコンソールを使ってLambda関数を一から作成していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77444/fa64a585-cdb3-4da3-4de9-4107481fa2a4.png)

ローカルで作成したzipファイルをアップロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77444/b5b62785-45ae-c2b3-5a95-c1b7622d9cae.png)

アップロードしたindex.jsが開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77444/fc0a9aa5-4ef0-0b0b-c2e0-0680d1e0b533.png)
メモ：Loadingのままで表示されない場合は、ぐるぐる回っているアイコンにマウスを重ねると、中止することができるので、index.jsをダブルクリックして手動で開きます。

環境変数を指定します。LINEチャネルのChannel Secretとアクセストークンをそれぞれ環境変数に指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77444/d7de1cd1-140f-2755-cbad-e259a9b0e552.png)


#API Gatewayを設定
セキュリティは「オープン」を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77444/5c8c1547-9801-13bc-84ec-00b008dfb8e3.png)

API Gatewayのエンドポイントを確認しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77444/45adcb36-7ab2-e9b8-6340-20c6477d27be.png)

LINE DevelopersコンソールでAPI GatewayのURLを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77444/48acff4f-1eb6-38be-af7a-4a77f2ba43cb.png)

Webhookの接続確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77444/b396af26-7e04-61f1-2cb4-a43d0afd7754.png)

#LINEアプリで動作確認
LINEアプリにbotを友達に登録して、botにメッセージを送ってみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77444/5ae8537f-c3a6-1d4e-bf6e-34cb96c5f36f.png)
メッセージがおうむ返しでかえってくれば成功です。

#ログを確認してみる
参考までに、Webhookでどのようなメッセージが流れているか、Lambdaのモニタリング機能を使って、挙動を確認してみます。

```JavaScript:index.js
:
// event handler
exports.handler = function handleEvent(event, context) {
    const body = JSON.parse(event.body);
    const eventType = body.events[0].type;
    
    // 追加
    console.log(body);
:
```

Lambdaダッシュボードのモニタリングを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77444/6cf61455-4538-b31e-d89f-c4b768821040.png)

CloudWatch Logs Insightsの「Recent invocations」にLogStreamが新しい順に並んでいるはずなので、先頭の#1のLogStreamをクリックします。console.logで出力したjsonデータを確認することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77444/6d7f16ea-da36-40d6-dda2-6b93892eaff8.png)

例外が発生した場合もここに記録されているので、警告や異常が発生してないか確認することができます。

[次回](https://qiita.com/yuppejp/items/4dc97e1692332509600b)は、LINE botイベントをDyanamoDBに記録するようにしてみたいと思います。

- [LINE Botの通知イベントをAWS DynamoDBに保存する](https://qiita.com/yuppejp/items/4dc97e1692332509600b)

#参考
- [Serveoを使ってLINE botサンプルをローカル環境で試す - Qiita](https://qiita.com/yuppejp/items/ff64f488a78f8c2bc595)