AWS EventBridge + Lambda + LINE でモーニングコールするBotを作ってみた

## はじめに
「AWSを使って便利なチャットBotを作る」をテーマに掲げ、自分自身の勉強も兼ねて、その成果を記事にしていきます。
まず第１弾としてLINEにモーニングコールメッセージを送信するBotを作ってみました。
この記事が少しでも役に立てば嬉しいです。

## 完成イメージ
完成イメージは下図のような感じです。
毎朝6時にモーニングコールのメッセージを届けてくれます。

![IMG_4A2D169908D7-1 2（中）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24724/f4514f78-7728-2240-0b49-d7e4551fb7ba.png)



## システム構成
下図のようなシステム構成でBotを作成していきます。
![Chatbot-LineMoningCall.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24724/93c48b8e-54ab-420b-a70d-e24577ba04dc.png)

### 処理の流れ
次のような流れで処理が行われます。
1. EventBridgeのスケジューラで毎朝決まった時間にメッセージ送信を行うLambda関数を呼び出す
1. Lambda関数ではEventBridgeから指定されたメッセージをLIME Message APIを使用してLINEに送信する
1. LINEで受信したメッセージが表示される 

### 使用技術
今回のシステムで使用する主要な技術は以下のとおりです。
- AWS Lambda
- AWS EventBridge
- LINE Messaging API
- Node.js (v1.6)

## 作成手順
それではモーニングコールBotを以下のような流れで作成していきます。
1. LINE Message APIの準備
1. LINEにメッセージ送信するLambda関数の作成
1. EventBridgeでLambda関数のcron設定

### LINE Message APIの準備
LINE Botを作成するためにLINE Message APIを使用します。
APIを使用できるようにするためには以下の手順を行います。
（いずれ詳細に書くつもりですが今回は簡単に概要だけ）

1. [LINE Divelopers](https://developers.line.biz/ja/)に個人アカウントを登録
1. アカウント登録後、LINE Developer Console画面に移動し、プロバイダーを作成
1. プロバイダー作成後、Message APIのチャンネルを新規作成

今回作成するBotではユーザーIDとチャネルアクセストークンを使用してメッセージを送信します。
ユーザーIDは「チャネル基本設定」、チャネルアクセストークンは「Message API設定」の画面に表示されます。


### LINEにメッセージを送信するLambda関数の作成

作業用のディレクトリを作成し、その中で`npm init`コマンドで実行します。
色々聞かれますがとりあえず全部デフォルトで進めます。

```
$ npm init
package name: (linemessagesample) 
version: (1.0.0) 
description: 
entry point: (index.js) 
test command: 
git repository: 
keywords: 
author: 
license: (ISC) 
```
`@line/bot-sdk`パッケージを使用するのでインストールします。

```
$ npm install @line/bot-sdk

added 51 packages, and audited 52 packages in 8s

14 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
```

いよいよLambda関数を作っていきます。
index.jsファイルを作成し、以下のコードを記述します。`<LINE_ACCESS_TOKEN>`と`<LINE_USER_ID>`にはLINE Developersで取得したチャネルアクセストークンとユーザーIDを設定します。
（ここではコードに直書きしていますが、環境変数やSSMパラメータストアに設定して呼び出す方が望ましいです。）

```javascript:index.js
// LINE BOT SDKを用意する
const LINE = require('@line/bot-sdk');

/**
 * LINEメッセージ送信Lambda関数
 * @param {*} event
 * @returns
 */
exports.handler = async (event) => {
  // アクセストークンとユーザーIDを設定する
  const LINE_ACCESS_TOKEN = '<LINE_ACCESS_TOKEN>';
  const LINE_USER_ID = '<LINE_USER_ID>';

  // LINEへの送信クライアントを用意する
  const client = new LINE.Client({
    channelAccessToken: LINE_ACCESS_TOKEN
  });

  // 引数eventをmessageに詰めて送信する
  const message = event;
  await client.pushMessage(LINE_USER_ID, message);
};
```

このLambda関数では引数eventをそのままLINEへのメッセージに使用しています。
つまりこの関数の呼び出し側であるEventBridge側でメッセージを設定できるようになっています。
そのためモーニングコールだけでなく、呼び出し側でメッセージを用意してあげればどんなメッセージでも送信できます。

作成したLambda関数はパッケージを含めてZIP圧縮し、AWS Lambdaに登録します。

### EventBridgeでLambda関数のcron設定

最後にLambda関数を定期的に呼び出すために、EventBridge Schedulerでスケジュールを設定します。
1. AWSマネージメントコンソールから「EventBridge」を選択
1. Schedulerの「スケジュール」を選択し、「スケジュール追加」を押下
1. スケジュールを作成（今回は朝6時にモーニングコール）
    - スケジュール名は任意、グループは「default」
    - スケジュールのパターンは「定期的なスケジュール」「cronベースのスケジュール」、cron式は (0, 6, *, *, ?, *)、フレックスタイムは「なし」
    - 時間枠は「Asia/Tokyo」
    - ターゲットは「AWS Lambda Invoke」
    - Lambda 関数は今回作成したLambda関数を選択、入力は後述するJSONフォーマットを参照
    - スケジュールの状態は「有効化」オン
    - 再試行ポリシーとデッドレターキュー (DLQ)は「再試行」なし
    - 暗号化はチェックなし
    - アクセス許可は「このスケジュールの新しいロールを作成」を選択


#### JSONフォーマット
送信するメッセージをJSON形式で記述します。
メッセージの仕様は[公式ドキュメント](https://developers.line.biz/ja/reference/messaging-api/#text-message)で確認できます。


```json
{
  "type": "text",
  "text": "おはようございます！\n今日も頑張っていきましょう！"
}
```

## 最後に
以上でBotの作成は完了です。
成功すれば毎朝６時にモーニングコールが届きます。
時間とメッセージを変更しておやすみコールにしてもいいですし、誕生日にバースデーメッセージを届けてもいいです。
アイデア次第で色々できそうです。
今後も記事を追加していくつもりですので、よかったら見てください。