AWS Lambdaを利用したLINEbotハンズオン〜鸚鵡返し〜

# はじめに
今回はLINEを利用した「おうむ返し」botの作成をしていきます。

動きとしてはLINEのMessaging APIを利用してAWS　API Gatewayにメッセージを送信します。Lambdaを起動させてコードの動作を行い処理をおこないます（今回は送信されたメッセージをそのまま返すという処理）

# 構成図
![スクリーンショット 2021-11-06 11.55.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/8221948d-e560-3e80-e151-8feac1eea970.png)

## 実装
#### 1.[LINE Developers](https://developers.line.biz/ja/)でプロバイダーの登録
##### 1.1 LINE Developersにログイン
URL：https://developers.line.biz/ja/ にアクセスしてログインをする
この際LINEに登録していない方はLINEのアカウントを取得する

![スクリーンショット 2021-11-06 12.17.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/e59373a0-37a5-56de-d47b-67eb607a01e0.png)

##### 1.2 プロバイダーを新規作成する
ハンズオン用にプロバイダー名を__Project_20211106__にして新規作成
![スクリーンショット 2021-11-06 12.18.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/5d456143-3290-a04a-89ec-46590b8a3e93.png)

##### 1.3 Messaging APIを選択（チャンネル登録）
今回利用する__Messaging API__（チャンネル）を選択する
![スクリーンショット 2021-11-06 13.30.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/89545a80-4d63-3b7e-ab40-38d5663db6e1.png)

##### 1.4 Messaging APIの設定内容
チャンネル名がLINEで表示される名前となります
そのほかの項目も埋めていきます

![スクリーンショット 2021-11-06 13.39.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/9766a1e6-bcd3-7daf-f49c-65adf65ec29c.png)

##### 1.5 設定の確認
![スクリーンショット 2021-11-06 8.14.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/b6624cd2-9bf3-0907-8d8d-677d769c531d.png)

##### 1.6 作成完了画面
次に登録したチャンネルに設定があるので画面を開いたままにしておく
![スクリーンショット 2021-11-06 15.47.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/e3885b8e-5edb-6c91-7498-b42df4e3bc71.png)


#### 2.作業ディレクトリ作成（ローカル環境）
[LINE公式ドキュメント](https://developers.line.biz/ja/docs/downloads/)より、LINE APIのSDK（ソフトウェア開発キット）のPythonをダウンロードする
※注意書きにもあるようにダウンロードは必須ではありませんが、構築が容易になるので、このQiita記事ではダウンロードしています

![スクリーンショット 2021-11-06 8.45.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/c9166620-e47c-ac80-5d25-f6717fcf0ebf.png)

##### 2.1 作業ディレクトリ作成とSDKインストール

```
tetutetu214@mbp projects % mkdir 20211106_parrot
tetutetu214@mbp projects % cd 20211106_parrot 
tetutetu214@mbp 20211106_parrot % python -m pip install line-bot-sdk -t .
```
インストール後のフォルダの一覧

```
tetutetu214@mbp 20211106_parrot % ls
__pycache__				future-0.18.2-py3.9.egg-info
aiohttp					idna
aiohttp-3.8.0.dist-info			idna-3.3.dist-info
aiosignal				libfuturize
aiosignal-1.2.0.dist-info		libpasteurize
async_timeout				line_bot_sdk-2.0.1.dist-info
async_timeout-4.0.0.dist-info		linebot
attr					multidict
attrs-21.2.0.dist-info			multidict-5.2.0.dist-info
bin					past
certifi					requests
certifi-2021.10.8.dist-info		requests-2.26.0.dist-info
charset_normalizer			typing_extensions-3.10.0.2.dist-info
charset_normalizer-2.0.7.dist-info	typing_extensions.py
examples				urllib3
frozenlist				urllib3-1.26.7.dist-info
frozenlist-1.2.0.dist-info		yarl
future					yarl-1.7.2.dist-info
```
##### 2.2 「lambda_function.py」ファイルを作成する
フォルダのなかに下記ファイル「lambda_function.py」を作成する
※このファイル名以外だと読み込まれないので注意する
![スクリーンショット 2021-11-06 13.51.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/3e735e03-c5c6-ffe0-a786-49dbbe1ecc69.png)

```lambda_function.py
import os
import sys
import logging

from linebot import (LineBotApi, WebhookHandler)
from linebot.models import (MessageEvent, TextMessage, TextSendMessage)
from linebot.exceptions import (LineBotApiError, InvalidSignatureError)

logger = logging.getLogger()
logger.setLevel(logging.ERROR)

#LINEBOTと接続するための記述
#環境変数からLINEBotのチャンネルアクセストークンとシークレットを読み込む
channel_secret = os.getenv('LINE_CHANNEL_SECRET', None)
channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None)

#無いならエラー
if channel_secret is None:
    logger.error('Specify LINE_CHANNEL_SECRET as environment variable.')
    sys.exit(1)
if channel_access_token is None:
    logger.error('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
    sys.exit(1)

#apiとhandlerの生成（チャンネルアクセストークンとシークレットを渡す）
line_bot_api = LineBotApi(channel_access_token)
handler = WebhookHandler(channel_secret)

#Lambdaのメインの動作
def lambda_handler(event, context):

#認証用のx-line-signatureヘッダー
    signature = event["headers"]["x-line-signature"]
    body = event["body"]

#リターン値の設定
    ok_json = {"isBase64Encoded": False,
               "statusCode": 200,
               "headers": {},
               "body": ""}
    error_json = {"isBase64Encoded": False,
                  "statusCode": 500,
                  "headers": {},
                  "body": "Error"}

#メッセージを受け取る・受け取ったら受け取ったテキストを返信する
    @handler.add(MessageEvent, message=TextMessage)
    def message(line_event):
        text = line_event.message.text
        line_bot_api.reply_message(line_event.reply_token, TextSendMessage(text=text))

#例外処理としての動作
    try:
        handler.handle(body, signature)
    except LineBotApiError as e:
        logger.error("Got exception from LINE Messaging API: %s\n" % e.message)
        for m in e.error.details:
            logger.error("  %s: %s" % (m.property, m.message))
        return error_json
    except InvalidSignatureError:
        return error_json

    return ok_json
```
##### 2.3 ファイルをzip化する
上述したファイルも含めて圧縮していく
![スクリーンショット 2021-11-06 13.59.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/30297590-11a0-79cd-bef6-38f0ce38cdb8.png)

名前は自分で管理しやすいようにネーミングして構いません
![スクリーンショット 2021-11-06 9.58.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/da1668d5-4d07-7658-7e90-6a77eaefe201.png)

#### 3.Lambdaの設定（AWSコンソール）
##### 3.1 AWSマネジメントコンソールからLambdaを設定していく
マネジメントコンソールから「Lambda」と検索する
![スクリーンショット 2021-11-06 14.02.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/69040fc1-ae2e-c64e-2e0f-32a07aa2d7d8.png)

##### 3.2 Lambdaで「関数の作成」を押下して関数を作成していく
![スクリーンショット 2021-11-06 14.06.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/0ded391c-cd18-4161-15f8-ecd08a4ced73.png)

__「関数の作成」__を押下後の遷移画面
関数名を記入、ランタイムはPython　3.8を選択します
実行ロールなどの設定は今回は不要のため手を加えてません
![スクリーンショット 2021-11-06 14.12.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/c32109ef-4aee-0ccd-e190-2a9fd0bb4c39.png)

##### 3.3 Lambda関数の設定をする
__「コード」__の__「アップロード元」で「.zip　ファイル」__を選択します
![スクリーンショット 2021-11-06 14.15.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/86f557a9-9667-98eb-189b-301c0ed800e8.png)
先ほど自分が作成したzipファイルを選択する
これが正常にアップロードされることで、ローカルで構築した内容が反映されます
![スクリーンショット 2021-11-06 14.24.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/0733e1a0-8fe2-8dab-2fd1-d2b290bb1e1b.png)

##### 3.4　環境変数へアクセストークンを設定する
![スクリーンショット 2021-11-06 14.20.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/3ea2d4b6-415c-cd31-6121-a1fc848ff747.png)
環境変数として記述する内容（値は次章から確認をする）
![スクリーンショット 2021-11-06 14.30.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/0b3bde40-1258-3f23-698e-a9fccbde8e47.png)

##### 3.5　環境変数の値を確認する
開いたままにしていた[LINE Developers](https://developers.line.biz/ja/)を開いて、__チャンネル基本設定__と__Messaging API設定__ページから確認して値の入力をする

__LINE_CHANNEL_ACCESS_TOKEN__該当箇所
![スクリーンショット 2021-11-06 15.59.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/4214bdc0-93e4-7348-b89b-cbdef2af5947.png)

__LINE_CHANNEL_SECRET__該当箇所
![スクリーンショット 2021-11-06 15.53.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/add11b23-ee94-00cf-3e73-c5a255fd12a0.png)


#### 4　AWS API Gatewayを設定する
LINEからの[Webhook](https://qiita.com/soarflat/items/ed970f6dc59b2ab76169)（イベント発生時、指定したURLにPOSTリクエストを送信する仕組み）を受け取るためにAPI Gatewayを設定する

#####　4.1　トリガーを作成する
Lambda画面から__トリガーを追加__を押下する
![スクリーンショット 2021-11-06 15.55.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/62f93405-8a49-58d9-b5c2-4b3cf4ed2121.png)


__トリガーの設定__で__「API Gateway」__を選択する
APIタイプは__HTTP API__で、セキュリティは__オープン__を選択する

![スクリーンショット 2021-11-06 14.51.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/79ddb074-3cec-90f0-1999-12d1c45cbfb3.png)

##### 4.2 構築が完了したことを確認する
![スクリーンショット 2021-11-06 15.13.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/064e6cf1-4690-1227-a161-4c17dd26929b.png)


#### 5　LINE DevelopersにAWSの設定を登録する
##### 5.1 作成されたAPIエンドポイントへのURLを[LINE Developers](https://developers.line.biz/ja/)に登録をする

![スクリーンショット 2021-11-06 15.14.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/c470f9f0-45ea-e5e5-43e6-f4b86897de80.png)

##### 5.2　WebhookにURLをCOPYする
LINE Developersの「Messaging API設定」の「Webhook設定」にAPI Gatewayの「APIエンドポイント」のURLをCOPYする
COPYして__更新__後に表示される、__Webhookの利用__をON（緑色）にする
![スクリーンショット 2021-11-06 16.02.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/63086923-c4c1-5231-89e6-90c0665acb71.png)


##### 5.3「あいさつメッセージ」の「編集」を押下して、詳細設定の__
「応答メッセージ」__を__「オフ」__にして、__「Webhook」__を__「オン」__にする

![スクリーンショット 2021-11-06 16.02.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/395e83f9-95a6-baa6-6d94-d6c36612bea5.png)


#### 6 LINE画面の確認
##### 6.1　QRコードから友達登録の遷移
QRコードを読み取ると、お友達登録の画面へ遷移して登録することができる
![スクリーンショット 2021-11-06 16.02.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/f8fefe5d-6602-1851-c4df-aecc29688849.png)


##### 6.2　画面挙動の確認
LINE画面でメッセージを送信すると、メッセージがおうむ返しされる

![スクリーンショット 2021-11-06 15.35.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/23807821-979c-9516-d725-2b42e35a0e5a.png)


#### 最後に
次回は「鸚鵡返し」をベースにして、LINEで写真を送信するとS3へ画像を保存される方法をハンズオンしていきたいと思います。

#### 参照
[Lambdaでline-bot-sdk-pythonを使用してオウム返しBOTを作成する](https://qiita.com/konikoni428/items/fd1ab5993bc5526726bb#aws%E3%81%A7lambda%E3%82%92%E4%BD%9C%E6%88%90)
[AWS Cloud9でオウム返しLINE Botを作る](https://qiita.com/suo-takefumi/items/65128ba82081b8fc6b51)
[Amazon API Gatewayは「HTTP API」と「REST API」のどちらを選択すれば良いのか？](https://dev.classmethod.jp/articles/amazon-api-gateway-http-or-rest/)