Lambdaでline-bot-sdk-pythonを使用してオウム返しBOTを作成する

# はじめに
line-bot-sdk-pythonを使用したlambdaでのBOT作成の記事が見当たらなかったので作成。
オウム返しBOTの作成を目標にします。
**AWS超初心者**なのでまずいところはコメントお願いいたします。

# 環境  
 - Windows10
 - Python3.6

# ①作業用ディレクトリ作成
lambdaでライブラリを使用するには、ファイルを一括でzipでまとめてアップロードする必要があるため、lambdaにアップロードしやすいようにフォルダを作成します。
とりあえず`C\:Users\ユーザー名\Documents\aws\parrot` の中に作成することとします。

# ②ライブラリ導入
作業フォルダに移動

```
cd C\:Users\ユーザー名\Documents\aws\parrot
```
-tオプションをつけることでインストール先を指定しライブラリをインストール。

```
python -m pip install line-bot-sdk -t .
```

# ③lambdaで使用する関数を作成
いっぱいファルダが出来上がっていると思いますが、`C\\:Users\ユーザー名\Documents\aws\parrot`の中にlambdaで使う関数を`lambda_function.py`という名前で作成しましょう。
中身はこんなかんじ。

``` lambda_function.py
import os
import sys
from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)
from linebot.exceptions import (
    LineBotApiError, InvalidSignatureError
)
import logging

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

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)

line_bot_api = LineBotApi(channel_access_token)
handler = WebhookHandler(channel_secret)


def lambda_handler(event, context):
    if "x-line-signature" in event["headers"]:
        signature = event["headers"]["x-line-signature"]
    elif "X-Line-Signature" in event["headers"]:
        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
```
注意点として、`@handler.add(MessageEvent, message=TextMessage)`を`handler.handle(body, signature)`より上に書かないとそんな関数みあたらねーってことで失敗するので気をつけましょう。

2/5変更
コメントより @Aki_fujita さんの報告があったので調べてみました。

https://developers.line.biz/ja/news/2021/01/18/reminder-update-webhook-client-and-root-certificate/#header-field-name-2
LINE側でのヘッダーフィールド名に関する取り扱いが少し変更されていたようです。
参考資料を読んでみるとHTTP/2での制約でフィールド名が小文字しか使えなくなったことが原因みたいです。
こちらの昔作ったアプリなどは問題なく動作しているので一律変更が加えられてるわけではなさそうですが、LINE側の発表の通り"X-Line-Signature"でも"x-line-signature"でも対応可能なように書き換えました。
動作確認できていないので動かなかったらすいません...

変更点終了


# ④ZIPにまとめる
作業フォルダ内のファイルを全選択してzipにまとめましょう。
<img width="798" alt="2018-08-16 (1).png" src="https://qiita-image-store.s3.amazonaws.com/0/262314/c58a7f8e-cafb-e5c8-76dc-47d771ee321d.png">
こんな感じで全選択してzipに圧縮してしまいます。

# ⑤awsでlambdaを作成
awsコンソールを開き、lambdaの場所へ移動しましょう。そしてこんな感じでlambdaを作成します。
<img width="1280" alt="2018-08-16.png" src="https://qiita-image-store.s3.amazonaws.com/0/262314/cfc08a13-3d7a-a8ba-1c78-732444e502bb.png">
ロールは特に必要な権限がないため、何も追加しません。

次に進んだらコードをアップロードします。
コードエントリタイプをZIPファイルをアップロードに変更し、さきほど作成したzipファイルをアップロードします。
<img width="1280" alt="2018-08-16 (2).png" src="https://qiita-image-store.s3.amazonaws.com/0/262314/d33c7d13-f7c9-608f-0a38-5c6268a96a4d.png">

つぎに環境変数へアクセストークンなどを設定します。
LINE Developersのサイトでボット用LINEアカウントを作成し、

 - アクセストークン再発行
 - Webhookを利用する
 - 自動応答メッセージを利用しない

このへんをやっちゃいましょう。WebhookURLは次の章で設定します。
そこで表示されているチャンネルシークレットとアクセストークンをlambdaの環境変数へコピペし、保存を押しましょう。
<img width="1280" alt="2018-08-16 (3).png" src="https://qiita-image-store.s3.amazonaws.com/0/262314/71f850c3-1862-d3d7-702d-74267651e75a.png">

lambdaの作業はおしまい。

# ⑥AWS API Gatewayを設定する
LINEからのWebhookを受け取るAPIGatewayを設定します。
AWSのサービスからAPI Gatewayを選択しAPIの作成を選びましょう。

新しいAPIとして作成。
<img width="1127" alt="2018-08-17 (1).png" src="https://qiita-image-store.s3.amazonaws.com/0/262314/79a4d1dd-ff5a-b935-11af-b627c5ede7f8.png">

アクションより新しいリソースの作成
<img width="603" alt="2018-08-17 (3).png" src="https://qiita-image-store.s3.amazonaws.com/0/262314/0351181b-edef-c3f7-c83f-81b0c003a348.png">

こんな感じで作成してみました。
<img width="1090" alt="2018-08-17 (4).png" src="https://qiita-image-store.s3.amazonaws.com/0/262314/39ae58da-0911-8bd1-ec17-854cad8c4983.png">

次はメソッドを作成
<img width="564" alt="2018-08-17 (5).png" src="https://qiita-image-store.s3.amazonaws.com/0/262314/cbd3b829-4b28-3fd6-92bd-27c41cd49263.png">

POSTで来るのでPOSTを選択します。
<img width="419" alt="2018-08-17 (6).png" src="https://qiita-image-store.s3.amazonaws.com/0/262314/0103a541-e888-37c7-521f-d08bb54ef4d3.png">

ヘッダー情報を使用するのでプロキシ統合を選択してください。
<img width="1085" alt="2018-08-17 (7).png" src="https://qiita-image-store.s3.amazonaws.com/0/262314/2cb3f9c7-fa25-f97e-8d66-8c3000fea07f.png">

次に表示される画面で、メソッドリクエストを選択し、以下の画像のように設定しましょう。
<img width="1087" alt="2018-08-17 (12).png" src="https://qiita-image-store.s3.amazonaws.com/0/262314/12f99cfc-9907-eaee-1fee-645f31c592eb.png">

最後にデプロイします。
<img width="448" alt="2018-08-17 (15).png" src="https://qiita-image-store.s3.amazonaws.com/0/262314/259c3d2a-c691-dbe1-79a8-42054b78d323.png">

ステージを適当に作りましょう。
<img width="446" alt="2018-08-17 (16).png" src="https://qiita-image-store.s3.amazonaws.com/0/262314/04b3030a-5612-4304-4e24-21ef3c1d03c6.png">

POSTのところ選んでURLを確認
<img width="1093" alt="2018-08-17 (17).png" src="https://qiita-image-store.s3.amazonaws.com/0/262314/d809047f-69c9-5e39-3d24-93454c1c5e4d.png">

このURLをLINE DevelopersにてWebhook URLとして設定すると完成！:relaxed:

# Demo
![demo.jpg](https://qiita-image-store.s3.amazonaws.com/0/262314/9d55a729-58c0-2d6a-ef8d-7cd73d40ed54.jpeg)


# 参考文献
https://qiita.com/Hironsan/items/0eb5578f3321c72637b4
https://qiita.com/hiyuzawa/items/10e7bf2f6ad5d1c7fc9c
https://qiita.com/_mogaming/items/2bd83204e212e35b2c6c