AWSでLINEのレストラン予約デモをデプロイした

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3117889/b235e5a8-4277-d3fb-1ba0-294315da16e5.png)


たまたまLINE予約システムを見つけたので、試しにデモをデプロイしてみました。
予約システムに関しては、以下のサイトに説明があります。

https://lineapiusecase.com/ja/usecase/reservation.html

サンプルは、以下のGitHubにあります。
AWS環境を前提としたサンプルで、AWS SAMでデプロイできます。

https://github.com/line/line-api-use-case-reservation-Restaurant

# 目次

- [LINEチャネルの作成](#lineチャネルの作成)
- [バックエンドの構築](#バックエンドの構築)
- [フロントエンド環境構築](#フロントエンド環境構築)
- [テストデータ投入](#テストデータ投入)
- [動作確認](#動作確認)

# LINEチャネルの作成

以下の手順通りできました。

https://github.com/line/line-api-use-case-reservation-Restaurant/blob/main/docs/jp/liff-channel-create.md

:::note warn
LINEチャンネルの作成リンクがありますが、下にスクロールして、「1.LINEアカウントの作成」から順番通り進めてください。
チャネル作成のリンクからたどって内容を確認していましたが、すぐ下にわかりやすい手順がありました。。。
:::

# バックエンドの構築

Cloud9を使って以下の手順通り実施しました。

https://github.com/line/line-api-use-case-reservation-Restaurant/blob/main/docs/jp/back-end-construction.md

まずは、GitHubからクローンします。

```bash:Gitクローン
git clone https://github.com/line/line-api-use-case-reservation-Restaurant
```

次に、Layerをデプロイします。
値はすべてデフォルトでデプロイできました。

```bash:Layerのデプロイ
cd line-api-use-case-reservation-Restaurant/backend/Layer
sam build --use-container
sam deploy --guided
```

次に、Batchをデプロイします。
こちらは、以下の値を変更しないとエラーになりました。

```text:変更が必要な個所
LayerVersion: Layer Version
LoggerLevel: DEBUG or INFO
TTL: False or True
TTLDay: Set day to delete data
```

とりあえず、一括置換しました。

```bash:一括置換
cd ../batch
sed -i \
-e "s/Layer Version/1/g" \
-e "s/DEBUG or INFO/DEBUG/g" \
-e "s/False or True/True/g" \
-e "s/Set day to delete data/1/g" \
template.yaml
```

置換後は以下のようになりました。
後で考えると、devのパラメータだけなので、手で変えてもそんなに多くなかったです。

```yaml
Mappings:
  EnvironmentMap:
    dev:
      MessageTableName: RemindMessageTableRestaurantDev
      LINEChannelAccessTokenDBName: LINEChannelAccessTokenRestaurantDev
      EventBridgeName: RestaurantEventDev
      LayerVersion: 1
      LoggerLevel: DEBUG
      # TTL is True:Reservation Data will be deleted at the specified date, False:Data will not be deleted
      TTL: False
      # 1
      # If you set TTL: True, data will be deleted in the period specified below.
      TTLDay: 10
```

batchをデプロイします。

```bash:batchのデプロイ
sam build --use-container
sam deploy --guided
```

:::note warn
デプロイに失敗した場合は、以下のように、一度削除してから再ビルド、再デプロイを実施します。
2回目以降のデプロイは、--guidedを省略できます。
```bash:再デプロイ
sam delete
sam build --use-container
sam deploy
```
:::

DynamoDBのLINEChannelAccessTokenRestaurantDevテーブルに以下のレコードを登録しました。
※channelIdとchannelSecretは、最初に作成したMessaging APIのチャネル基本設定から確認した値です。

```JSON
{
  "channelId": "0000000000"
  "channelSecret": "0000000000000000000000000"
}
```

次にAPPをデプロイします。
例によって、変更が必要な個所は、以下の通りです。

```
LINEOAChannelId: LINEOAChannelId
LIFFChannelId: LIFFChannelId
FrontS3BucketName: S3 Bucket Name for Frontend
LayerVersion: Layer Version
LoggerLevel: DEBUG or INFO
LambdaMemorySize: 128 to 3008
```

以下のように修正しました。
S3バケットは事前に作成「しない」でください。
※チャネルIDは、確認して記入してください。

```yaml
Mappings:
  EnvironmentMap:
    dev:
      LINEOAChannelId: LINEOAChannelId
      LIFFChannelId: LIFFChannelId
      ShopMasterTable: RestaurantShopMaster
      ShopReservationTable: RestaurantShopReservation
      CustomerReservationTable: RestaurantReservationInfo
      LINEChannelAccessTokenDBName: LINEChannelAccessTokenRestaurantDev
      MessageTable: RemindMessageTableRestaurantDev
      # RemindDateDifference -> Negative value if the day before the day of the reservation(ex: A day ago -> -1)
      RemindDateDifference: -1
      FrontS3BucketName: S3 Bucket Name for Frontend
      LayerVersion: 1
      LoggerLevel: DEBUG
      LambdaMemorySize: 128
      # TTL is True:Reservation Data will be deleted at the specified date, False:Data will not be deleted
      TTL: False
      # Set day to delete data
      # If you set TTL: True, data will be deleted in the period specified below.
      # Even if you set TTL: False, please set int value.
      TTLDay: 10
      # ### ACCESS LOG SETTING ###
      # LogS3Bucket: S3BucketName for AccessLog
      # LogFilePrefix: restaurant-sample/
      # ### ACCESS LOG SETTING ###
```

例によって、APPをデプロイします。

```bash:APPのデプロイ
cd ../APP
sam build --use-container
sam deploy --guided
```

手順にない以下の質問がありました。
yと回答しないと先に進めないので、以下のようにyと回答しました。

```bash
ShopListGet may not have authorization defined, Is this okay? [y/N]: y
ShopCalendarGet may not have authorization defined, Is this okay? [y/N]: y
ReservationTimeGet may not have authorization defined, Is this okay? [y/N]: y
CourseListGet may not have authorization defined, Is this okay? [y/N]: y
ReservationPut may not have authorization defined, Is this okay? [y/N]: y
```

RestaurantApiのURLとCloudFrontDomainNameの値はメモしておきます。

# フロントエンド環境構築

line-api-use-case-reservation-Restaurant/frontに移動し、以下の.envファイルを新規作成します。

```bash:line-api-use-case-reservation-Restaurant/front/.env
# LIFF ID
LIFF_ID=9999999999-xxxxxxxx

# AXIOS BASE URL
BASE_URL=https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com

# API Gateway Stage
APIGATEWAY_STAGE=dev

# Ajax Module (axios or amplify)
AJAX_MODULE=amplify
```

npm installを実行します。

```bash
npm install
```

以下のエラーが発生しました。

```bash
npm ERR! code 1
npm ERR! path /home/ec2-user/environment/line-api-use-case-reservation-Restaurant/front/node_modules/node-sass
npm ERR! command failed
npm ERR! command sh -c -- node scripts/build.js
```

エラーが発生したnode-sassを見ると、node.jsのバージョンによってサポートしているnode-sassのバージョンが決まっているようです。

https://www.npmjs.com/package/node-sass

node.jsのバージョンは、16.19.0で、

```bash
$ node -v
v16.19.0
```

package.jsonに記載のあるnode-sassのバージョンは以下の通りです。

"node-sass": "4.14.1"

今回はテスト目的なので、node.jsをv14にします。
nvmで対応しているバージョンを確認します。

```bash
$ nvm ls
->     v16.19.0
         system
default -> 16 (-> v16.19.0)
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v16.19.0) (default)
stable -> 16.19 (-> v16.19.0) (default)
lts/* -> lts/hydrogen (-> N/A)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.12 (-> N/A)
lts/fermium -> v14.21.2 (-> N/A)
lts/gallium -> v16.19.0
lts/hydrogen -> v18.12.1 (-> N/A)
```

v14に対応するlts/fermiumをインストールして設定します。

```bash
$ nvm install lts/fermium
Downloading and installing node v14.21.2...
Downloading https://nodejs.org/dist/v14.21.2/node-v14.21.2-linux-x64.tar.xz...
################################################################################################################# 100.0%
Computing checksum with sha256sum
Checksums matched!
Now using node v14.21.2 (npm v6.14.17)
$ nvm use lts/fermium
Now using node v14.21.2 (npm v6.14.17)
```

再度、npm installを実行すると成功しました。

```bash
npm install
```

続いて、ビルドします。

```bash
npm run build
```

ビルドした資材をS3バケットにアップロードします。

```bash
aws s3 cp --recursive dist s3://<バケット名>
```

# テストデータ投入

https://github.com/line/line-api-use-case-reservation-Restaurant/blob/main/docs/jp/test-data-charge.md

手順には、ShopMasterTableにdynamodb_data/restaurant_1.json ~ restaurant_6.jsonを投入してくださいと書いてありますが、DynamoDBのJSONビューにして登録する必要があります。

:::note warn
JSONビューに切り替えた後、「DynamoDB JSONの表示」をオフにしてから貼り付ける必要があります。
そうしないとエラーが表示され、更新できなくなります。
[Ln 2、Col 13	Expected '{' instead of '1']のようなエラーが発生します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3117889/6163b8a0-ecf5-1e99-8749-d25adfa71745.png)
:::

# 動作確認

以下の手順通り、LIFFの登録をします。

https://github.com/line/line-api-use-case-reservation-Restaurant/blob/main/docs/jp/validation.md

LIFF URLにブラウザでアクセスすると、LINEログインを求められるのでログインします。すると、LINEに登録できます。

:::note warn
以下のようなCORSエラーが発生している場合は、CORSの有効化を行います。
>Access to XMLHttpRequest at 'https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/dev/shop_list_get?locale=ja' from origin 'https://xxxxxxxx.cloudfront.net' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Access-Control-Allow-Originには、CloudFrontを指定してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3117889/260bc9ad-42c5-35b5-f54f-bf8847e08699.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3117889/2e2ccef7-bfa2-16a1-d302-87f70cf81405.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3117889/2181cb85-625c-e03e-c65b-1e78a735f814.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3117889/26990b32-3ebd-79ff-6d79-4bfbdc4ec2aa.png)

:::

正常に動作すると、以下のように予約情報が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3117889/f4fbb8c3-eb35-094c-282c-aaf986fe8194.png)

カレンダーから予約したい日を選択して、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3117889/091197a8-0581-cff2-0c32-2c2bace8d8e6.png)

時間を指定することで予約できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3117889/86191def-baaa-037e-edc4-2d75b0d9f0b2.png)

内容を確認して予約します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3117889/f6ad5772-c4ef-8b8e-a141-c0575cdd0387.png)

受付が完了すると以下のような画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3117889/caf3e70d-ed11-1937-d00c-8c38686608e1.png)