Lambda*API Gateway*LINE LIFFでアプリを作ってみる(1)

# はじめに
同窓会の幹事になりまして。
「毎年ある同窓会の出欠フォーム管理が毎年めんどくさいし何年度卒か毎年迷うし当日も受付に時間食うから嫌なんだよなーーー」
「よし、メンバーは皆LINEグループにいるんだから、LINE上で出欠管理から告知から当日受付まで楽に出来るアプリ作れないかな！ LINE LIFFなるもの使ってみたい！」

ということで大分前に取るだけとったAWSアカウント掘り出して遊んでみているのですが、ちょこちょこ詰まって唸っているのでいつもの如く自分用備忘録に記録していきます。

## LINE Developer登録〜LIFFから任意のURLを呼び出すまで
ぽちぽちやっていたらめちゃくちゃ簡単に出来たのですっ飛ばします。非エンジニアでもLINEbot作れますね、これ。
2019春にアカウントの種類が統合されたらしく、従前の`LINE@`のフリープランアカウントでは出来なかったことも`公式アカウント`では出来るようになってます。今LINE Developerからアカウントを作成すると`公式アカウント`のフリープランがデフォルトで適用されます。
[MessagingAPIのリファレンス](https://developers.line.biz/ja/reference/messaging-api/#send-push-message)に以下のような注意書きが記載されているのでビクビクしているのですが、LINE Developerの自分のページに`PUSH_MESSAGE`も使えるよと記載されているからきっと`LINE@アカウント`側の話なんだろう、と思っている...(MessagingAPIまだ触ってないからわからないのですが)
> 注：フリープランまたはベーシックプランのLINE＠アカウントでは使用できません。

アカウント種別統合のまとめはこちらのブログ記事など拝見しました。
- https://frontsupport.jp/blog/blog-1036/

## Lambda*Jinja2でテンプレートレンダリングをする準備
LINE LIFFのエンドポイントURLにAPI GatewayのURLを指定してあげれば、中身をLambdaで書いて返せばサーバーレスにLIFFに表示する画面を作れる！ ということで、LIFFを一旦置いておいて、Lambda(Python)でテンプレートレンダリングをしてみるところから。
基本的にこちらのQiita記事様を参考にさせていただきました。

- [AWS LambdaでHTMLを出力してみた](https://qiita.com/yoshidasts/items/d58c555aed2693e99ae6)
- [AWS Lambda と Python で作る動的な HTML ページ](https://qiita.com/kimihiro_n/items/15cce90ec93625c4445a)

以下、詰まったところのみメモを残しています。
### pipインストール〜Jinja2インストール
公式サイト( https://pip.pypa.io/en/stable/installing/#installing-with-get-pip-py )

``` bash
## pythonインストール
$ brew install python

## pipインストール
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python get-pip.py --user

## Jinja2インストール
$ pip3 install Jinja2
```
<font color="red">! python3以上では `pip` ではなく `pip3` コマンドになる。</font>
従って、 `pip install Jinja2` ではなく `pip3 install Jinja2` が有効なコマンド。(参考： https://teratail.com/questions/71886 )
### apexインストール
公式サイト( http://apex.run/ )

``` bash
### apexインストール
$ curl https://raw.githubusercontent.com/apex/apex/master/install.sh | sh
```

### AWS CLI導入
AWS CLIを入れていないので導入。
(頭からみてたら折角のpip3使わずにインストールしてしまってた;;)

- https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-macos.html

``` bash
### AWS CLI
$ curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-b 
undle.zip"
$ unzip awscli-bundle.zip
$ sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
```

#### メモ
- AWSアクセスキー・シークレットキー発行は `IAM > ユーザー > 認証情報` 内の「アクセスキー」から発行可能。
シークレットキーを表示できるのはその時のみなので、必ずcsvDLするなどして厳重に保管すること。
- `output format`は`json`,`text`,`table`のいずれかから選択する（デフォルトはjson)
- プロファイルの指定をしない場合、`default`として登録される。`$ aws configure --profile produser`のようにprofileを指定すると、後述のapexでのデプロイ時も複数のデプロイ先から選択してデプロイすることができる。

#### 参照先
- https://utano.jp/entry/2015/06/aws-cli-configure-credentials-path/
- https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-configure.html

``` bash
$ aws configure
AWS Access Key ID [None]: xxxxxxxxxxxxx
AWS Secret Access Key [None]: xxxxxxxxxxxx
Default region name [None]: ap-northeast-1
Default output format [None]: text
```

実行すると`~/.aws/`配下に`config`と`credential`が生成される。

### Apexプロジェクト作成
参照： https://dev.classmethod.jp/cloud/aws/how-to-manage-aws-lambda-functions-with-apex/
Project名と説明文の入力を促される。ロール・ポリシーの作成〜アタッチも一気に実行してくれる。

``` bash
bash-3.2$ apex init


             _    ____  _______  __
            / \  |  _ \| ____\ \/ /
           / _ \ | |_) |  _|  \  /
          / ___ \|  __/| |___ /  \
         /_/   \_\_|   |_____/_/\_\



  Enter the name of your project. It should be machine-friendly, as this
  is used to prefix your functions in Lambda.

    Project name: MyLineProject

  Enter an optional description of your project.

    Project description: test

  [+] creating IAM MyLineProject_lambda_function role
  [+] creating IAM MyLineProject_lambda_logs policy
  [+] attaching policy to lambda_function role.
  [+] creating ./project.json
  [+] creating ./functions

  Setup complete, deploy those functions!

    $ apex deploy
```
デフォルトで作成するpolicyはログのものだけなので、DyanamoDBなどへのアクセスをする場合は別途作成してAttachする必要がある。

``` json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "logs:*"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}
```

参照サイト（ https://dev.classmethod.jp/cloud/aws/how-to-manage-aws-lambda-functions-with-apex/ )様の通りにfunction内容を書き換え、`function.json`を作成。

``` json:function.json
{
    "description": "Node.js example function",
    "runtime": "nodejs"
}
```
profileを指定していないため、`apex deploy <function名>`でデプロイ可能。

```
root
　└- function
　　└- hello　　　　　　★これがfunction名になる
　　　└- function.json
　　　└- index.js
```
が、`nodejs`(nodejs6.10)は古くてサポートしてないよと怒られる。

``` bash
$ apex deploy hello
   • creating function         env= function=hello
   ⨯ Error: function hello: InvalidParameterValueException: The runtime parameter of nodejs6.10 is no longer supported for creating or updating AWS Lambda functions. We recommend you use the new runtime (nodejs10.x) while creating or updating functions.
        status code: 400, request id: 6dc9ffe6-4d31-471a-a348-15dfe7b43ca0
```
ので、`"runtime": "nodejs10.x"`に書き換えてリトライ。

``` bash
$ apex deploy hello
   • creating function         env= function=hello
   • created alias current     env= function=hello version=1
   • function created          env= function=hello name=MyLineProject_hello version=1
```
Lambda関数一覧にも無事にデプロイされていることを確認できる。
<img width="1440" alt="スクリーンショット 2019-12-07 21.56.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275513/fbdf8ae6-a31c-81b6-33be-d40c4f1a4596.png">

関数の実行も以下の通り出来ることを確認。

``` bash
$ apex invoke hello < input/event.json 
{"hello":"world"}
```

### ソースを頂いて動作確認
実際のソースをGithubに置いて下さっていたので、ありがたく使わせて頂いて動作確認。
API GWで{proxy+}にする箇所は一旦飛ばしているので後日確認...
作成したURLをLIFFに設定してLINE側からページを閲覧するところまで確認でけたのでとりあえずはゴール！
(2)では{proxy+}のお話とMessagingAPIを触る予定。
閲覧ありがとうございました！