AWS ProtonでLINE Botを作成してみる

# はじめに

久しぶりにLINE Bot記事を書いてみようと思います。今回は[re:invent2020](https://reinvent.awsevents.com/)で発表された[AWS Proton](https://aws.amazon.com/jp/proton/)が気になったので試しにLINE Botを作って試してみようと思いました。
とりあえずLINE Botの内容にこだわるつもりはないので簡単なオウム返しBotを作ります。

# AWS Protonとは

詳細は[公式のドキュメント](https://docs.aws.amazon.com/proton/latest/adminguide/Welcome.html)を見てもらう方が良いかと思います。今の所、あまりドキュメントが充実していないので機能全体を把握していないというのが本音のところですが、雰囲気としてはコンテナ・サーバーレスのためのCI/CDツールといった感じかと思います。
中身としては[CloudFormation](https://aws.amazon.com/jp/cloudformation/)、[CodePipeline](https://aws.amazon.com/jp/codepipeline/)などのサービスを使っているようです。インフラのプロビジョニングとアプリケーションのデプロイの管理をするためのコンソールがAWS Protonというのが個人的な印象でした。

# とりあえず使ってみる

一応[公式のGet Start](https://docs.aws.amazon.com/proton/latest/adminguide/ag-getting-started.html)がありますが一部不親切なところもあります。ある程度AWSを触っている人向けに書いている感じですかね。。。

まずは[Protonのコンソール](https://console.aws.amazon.com/proton/)から`使用を開始する`を押して公式のガイドに従う方がわかりやすいかと思います。

![sc1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/cf825e22-595d-d8d2-6237-596f44f80c6d.png)

後は↓の1~3の手順も進めてしまいます。

![sc2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/d969b388-7001-9d5d-aa68-94f7c040316d.png)

この`テンプレート`がAWS上でサーバーレスアプリを構築するためのインフラをとなるようです。Protonのドキュメントでは`プラットフォームチーム`が担当する箇所ですね。ここをCloudFormationをつかってテンプレートファイルを記述するみたいですが今回はサンプルテンプレートを使います。
`Use one of our sample template bundles`を選択すると`fargate`か`lambda`のテンプレートが選択できるようになります。環境テンプレートは`lambda-environment`、サービステンプレートは`lambda-service`を選びました。

![sc3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/2c19a5d3-8603-a328-d55d-e203e69f0959.png)

![sc4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/8abdab80-21fb-3d46-b1e9-770497d12c7e.png)

これらのサンプルテンプレートは[ここ](https://github.com/aws-samples/aws-proton-sample-templates)で公開されているみたいです。このLambda用のテンプレートはCRUDのサービスを実装するためのものらしいので、DynamoDBなど今回使う予定のないものも入っていますが別に使わなければ課金の問題はないはずなので無視することにします。LINE Botを作る場合はPOSTリクエストでLambdaが呼び出さればいいので今回はこれで良い気がします。

次がロールの作成ですが、試験用であれば`New service role`を選んで適当な名前でそのまま新しいIAMロールを作成してしまえばOKです。

![sc5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/8852ba9c-9e55-52d0-9be9-6a689389f002.png)

あとは`リポジトリ接続`ですが、`リポジトリ接続を追加`をクリックすると`デベロッパー用ツール`のページが別タブで開かれるのでそこで自分のGitHubなどとアカウント連携しておきます。
最後に環境の作成ですが、これは先程作成した環境テンプレートを選んで適当な名前を設定すれば後はデフォルトの設定で問題ないです。

# サービスを作成する

前項はほぼGet Startと同じ内容ですが、ここからオウム返しBotをデプロイするためのサービスを作成します。とりあえず[こちら](https://github.com/ufoo68/echolalia-bot)でリポジトリを作成しました。アプリケーションはかなり簡素です。

```js
const line = require('@line/bot-sdk')
const client = new line.Client({ channelAccessToken: process.env.ACCESSTOKEN })

exports.handler = function (event, context) {
  let body = JSON.parse(event.body)
  let text = body.events[0].message.text
  const message = {
    'type': 'text',
    'text': text
  }
  client.replyMessage(body.events[0].replyToken, message)
    .then((response) => {
      let lambdaResponse = {
        statusCode: 200,
        headers: { "X-Line-Status": "OK" },
        body: '{"result":"completed"}'
      }
      context.succeed(lambdaResponse)
    }).catch((err) => console.log(err))
}
```

サービスのサンプルテンプレートを見る感じ、CodePipelineでのビルド時にコードと依存関係をzipでまとめているような処理をしていたのでそれにあわせて`package.json`をこんな感じで記述しました。

```json
{
  "name": "echolalia-bot",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "publish": "npm install && zip -r function.zip node_modules index.js"
  },
  "author": "ufoo68",
  "license": "MIT",
  "dependencies": {
    "@line/bot-sdk": "^7.1.0"
  }
}

```

あとはサービステンプレートをもとにサービスを作成してデプロイを実行します。このあたりもGet Startの内容を参考にすると良いと思います。ポジトリの選択については公式ドキュメントでは簡素な説明で記述されているのですが、`リポジトリID`は`ユーザー名/リポジトリ名`の形式で書く必要があります。

![sc6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/319123cf-3df3-3a4b-0ac4-65d769d53472.png)

次にサービスのカスタム設定を構成ですが、クラスターのRuntimeはNode.jsを選択するようにします。あとは`Pipeline packaging command`は`npm run publish`と

![sc8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/b59b3ace-7a93-b837-bc87-6d21179dc827.png)

とりあえずこれでCodePipelineが作成されてLambdaにアプリケーションがデプロイされます。

# 結果

LINE Botのチャンネル作成の手順は今回は省略します。一応こんな風にちゃんとオウム返しをしてくれるBotが作れました。

![20201213_001406.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/97cd4c48-51f6-8e52-214c-80b8859e48b9.png)

# さいごに

とりあえずProtonが気になっていたので使ってみました。ただ今回はCRUD用のサンプルテンプレートを使ってアプリケーションの実装をサンプルの内容に合わせたので色々と手心を加えた形になってしまいました（ハンドラや環境変数の指定は直接Lambdaのコンソールでやりました）。
時間があればLINE Bot用の環境・サービステンプレートを独自に作ってやってみても良いかもですね。