ChaliceでLINE chatbotを実装するまで

#前提
なんでもいいからAWS上に乗せて動かしてみたかった。
LINE chatbotをHeroku上にデプロイしたことはあったので、
とりあえずこれを乗せてみることにしました。

#Chaliceとは
>Chalice は、 Amazon API Gateway と AWS Lambda for Python による API 環境を実現してくれる、 AWS 製のアプリケーションフレームワークです。（AWS公式より）

コマンドラインでアプリケーションの構築やデプロイができるほか、
Lambdaに付与するIAMロールのポリシーを自動で付与してくれたり、
APIを自動で払い出してくれたりと、かなり便利でした。

#Chalice導入まで
前準備
・AWSアカウントの取得
・AWS CLIのインストール
AWS CLIを始めてインストールする場合は、インストール後に

```
aws configure
```

コマンドをたたいて、アカウントのアクセスキーやシークレットアクセスキー、
リージョンや出力形式を登録しておきましょう。
認証情報はホームディレクトリ配下の.awsフォルダに格納されます。
ルートユーザーのアクセスキーの発行は推奨されないので、IAMユーザーを作成してその認証情報を登録しておきます。

Chaliceは

```bash

pip install chalice
```

でインストールできます。

#プロジェクトの作成からデプロイまで
 ```
chalice new-project hello-world
```

コマンドでプロジェクトファイルが生成されます。
ディレクトリ構造はこちら。

```
│  .gitignore
│  app.py
│  requirements.txt
│
└─.chalice
        config.json
```

app.pyを編集していきます。
デフォルトではこうなっています。

```python:app.py
from chalice import Chalice

app = Chalice(app_name='hello-world')


@app.route('/')
def index():
    return {'hello': 'world'}


# The view function above will return {"hello": "world"}
# whenever you make an HTTP GET request to '/'.
#
# Here are a few more examples:
#
# @app.route('/hello/{name}')
# def hello_name(name):
#    # '/hello/james' -> {"hello": "james"}
#    return {'hello': name}
#
# @app.route('/users', methods=['POST'])
# def create_user():
#     # This is the JSON body the user sent in their POST request.
#     user_as_json = app.current_request.json_body
#     # We'll echo the json body back to the user in a 'user' key.
#     return {'user': user_as_json}
#
# See the README documentation for more examples.
#
```

以下コマンドで、ローカルでの動作確認ができます。

```
chalice local
```
![WS000008.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/745530/6a7d370a-00fe-2352-c8e8-cef57d8a828b.jpeg)

デプロイはこちら。

```
chalice deploy
```
![WS000009.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/745530/4086d9da-87b6-b815-24ed-03922e9032b3.jpeg)

払い出されたAPI URLにアクセスして{'hello': 'world'}が返ってきているのを確認しましょう。
お片づけはこちらです。

```
chalice delete
```


#LINE chatbotを実装する
##[LINE developers](https://developers.line.biz/ja/)に登録する
適当にアプリ名等を設定し、オウム返し用のチャネルを作ります。
Messaging API設定からWebhookの利用をオンにし、
Messaging API設定の**チャネルアクセストークン（長期）**、
チャネル基本設定の**チャネルシークレット**を控えておきます。

##line-bot-sdkをインストールする
ローカルでは

```
pip install line-bot-sdk
```

でOK。
Lambdaにデプロイするとき用に、[PyPI](https://pypi.org/project/line-bot-sdk/)からwhl形式のファイルを落としておきます。
Lambdaで外部ライブラリを使うときはプロジェクト名のフォルダにvendorフォルダを作り、そこにwhl形式で格納します。さらにrequirements.txtを作成し、使用するバージョンを指定します。

```:requirements.txt
line-bot-sdk==1.17.0
```

##環境変数を登録する
環境変数は.chaliceディレクトリ内のconfig.jsonに書き加えます。
先ほど控えたチャネルシークレットとチャネルアクセストークンを以下のように登録しましょう。

```json:config.json
{
  "version": "2.0",
  "app_name": "line-bot",
  "stages": {
    "dev": {
      "api_gateway_stage": "api",
      "environment_variables": {
      "LINE_CHANNEL_SECRET": "チャネルシークレット",
      "LINE_CHANNEL_ACCESS_TOKEN": "チャネルアクセストークン"
      }
    }
  }
}
```

##app.pyの編集
[Chalice を使って AWS Lambda 上に LINE Bot 用の Webhook を作成する](https://qiita.com/t-kigi/items/21073df2bfc27e2b4999)
こちらを参考にしました。

##デプロイ～結果
デプロイします。
コンソールを確認すると、LambdaとAPI gatewayが作成されています。
![WS000001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/745530/638b270c-3bf8-7314-9b50-8f6360120728.jpeg)
![WS000003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/745530/6e8a240a-cdf5-cd3a-4faa-691fd4ffc9fb.jpeg)

払い出されたAPI URLに/callbackを足したものをLINE developersのWebhookに登録します。検証を押して問題なければOKです。
![WS000004.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/745530/83a1fe26-b0bf-aed7-0f5a-35e8f40ac01b.jpeg)

あとはbotに話しかけて、オウム返しが作動するか確認しましょう。
![WS000007.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/745530/eee34158-f8de-7196-cf2b-887e506ed1da.jpeg)

##実装までのトラブルシューティング
最初、オウムがうんともすんとも言わないのでLambdaをテストしに行きました。
![WS000000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/745530/3fc48668-570a-1fbb-0482-d72d4e2aaf26.jpeg)
テスト関数はここでは空のjsonで十分です。
失敗が確認されたので、CloudWatchを見に行きました。
エラーログはCloudWatch>CloudWatch Logs>Log groupsに格納されます。line-botのログストリームを開けていくと……
![WS000005.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/745530/21eff163-8761-0c41-94d8-cf1402a27323.jpeg)
line-botモジュールがないよと言われています。
確認したところ、vendorにライブラリを格納したまでは良いものの、requirements.txtファイルを編集するのを忘れていました。

##注意点・未解決事項
・deploy後に数分コンソールが動かなくて慌てましたが、line-bot-sdkをインストールするのに時間がかかっていただけのようです。気長に待ちましょう。
・ブラウザでapi/callbackに接続すると、{"message":"Missing Authentication Token"}になってしまいます。オウム返し自体は機能しているのですが……
・ChaliceはLambdaに付与するIAMロールのポリシーは自動でいい感じに付与してくれますが、AWSにアクセスするアクセスキーを持ったIAMユーザーのポリシーはこちらで与えないといけません。
それらしいポリシーを与えても権限がありませんよエラーではじかれてしまい、今回は結局AdministratorAccessポリシーを当ててごり押ししてしまいました（IAMユーザーを作った意味がない……）。