AWSを活用してLINEチャットボットを作ってみた!①
こんにちは、宮内です。
以前にブログで紹介した「到着メール通知サービス」では、Eメールを使用して通知を行っていました。
しかしEメールを使用していると、メールサービスの種類によってメッセージのフォーマットが異なっていたり、添付画像が正しく表示されなかったりと不便な点がありました。
こうした機能の改善と利用者側の使いやすさを考え、多くの方が利用している LINE を通知先として検証することにしました。
今回から3回にかけて、LINEとAWSを組み合わせたチャットボット開発について説明します。
内容としては、以下を予定しています。
① LINEボットの作成とLambdaの連携
② Amazon Lexによるチャットボットの作成
③ チャットボットとLambdaの連携
今回の目標
今回は、LINEボットの作成とLambdaの連携まで説明します。
システム概要図は次のようになります。

処理のイメージとしては、
① LINEで受け取ったメッセージを、API Gatewayを経由してLambdaに連携
② Lambdaでメッセージを認識して、LINEのリプライ(返信)メッセージを作成
となります。
なお、今回の記事で作成するLambdaは、LINEから受け取ったメッセージをそのまま返す処理とします。
通知サービス用のプログラムは、3回目の記事で説明します。
LINEボットの作成
まずはLINEボットを作成するため、LINE Developersへアクセスします。
▼LINE Developers(URL)
https://developers.line.biz/ja/
アクセスすると次のページが開くので、コンソールをクリックします。

次に、LINEアカウントを使ってログインします。
ビジネス利用の場合は、会社でビジネスアカウントを発行する必要があるかと思いますが、今回は私の個人アカウントでログインして検証します。
※アカウント作成については割愛します。

メールアドレス、パスワードを入力してログインをクリックします。

ログインすると、LINE Developersのコンソール画面が開きます。
次にプロバイダーの作成を行います(プロバイダーを既に作っている場合は、チャネル作成から対応していただいてOKです)。

プロバイダー名を入力する画面が開くので、任意の名前でプロバイダー名を設定します。
今回はプロバイダー名を「test provider」としています。

プロバイダーが作成できたら、次に作成するチャネルを選択します。
ボットを作る際には「Messaging API」を選択します。

以下を参考にチャネルの設定を行い、作成ボタンをクリックします。

作成ボタンをクリックすると、チャネル作成の確認画面が開くので、OKをクリックします。

次に情報利用に関する同意の画面が開くので、内容を確認して同意するをクリックします。

以上の手順により、チャネルの作成が完了します。

ちなみに、Messaging API設定 のタブにはLINEの友達追加用のQRコードが表示されています。
このQRコードを読み取ることで、作成したLINEボットを友達に追加することが可能です。

以上でLINEボットの作成は完了です。
Lambdaレイヤーの作成
次に、Lambdaの開発を効率的に行うため、line-bot-sdkのLambdaレイヤーを作成しましょう。
今回もPythonを使用してLambdaの開発を行うため、LINE公式から提供されているPython用のSDKを利用します。
レイヤー用のZipファイルを作成する手順は、以下の記事の 3.Zipファイルの作成 を参考にしてください。
インストールするパッケージは line-bot-sdk なので、パッケージのインストールコマンドが次のようになる点は注意してください。
# line-bot-sdkのインストール
pip install line-bot-sdk -t python
Zipファイルを作成してダウンロードができたら、Lambdaレイヤーに設定しましょう。
今回はPython3.9用のレイヤーを作成してみました。

Lambdaの実装
次にLambdaの実装を行います。
実装プログラム
メッセージをオウム返しをするソースは以下のようになります。
import os
import json
from linebot import LineBotApi
from linebot.models import TextSendMessage
# 環境変数からLINE Botのチャネルアクセストークンを取得
LINE_CHANNEL_ACCESS_TOKEN = os.environ['LINE_CHANNEL_ACCESS_TOKEN']
# チャネルアクセストークンを使用して、LineBotApiのインスタンスを作成
LINE_BOT_API = LineBotApi(LINE_CHANNEL_ACCESS_TOKEN)def lambda_handler(event, context):
try:
# LINEからメッセージを受信
if event['events'][0]['type'] == 'message':
# メッセージタイプがテキストの場合
if event['events'][0]['message']['type'] == 'text':
# リプライ用トークン
replyToken = event['events'][0]['replyToken']
# 受信メッセージ
messageText = event['events'][0]['message']['text']
# メッセージを返信(受信メッセージをそのまま返す)
LINE_BOT_API.reply_message(replyToken, TextSendMessage(text=messageText)) # エラーが起きた場合
except Exception as e:
print(e)
return {'statusCode': 500, 'body': json.dumps('Exception occurred.')}
return {'statusCode': 200, 'body': json.dumps('Reply ended normally.')}
プログラムの注意点として2点説明します。
【注意1】チャネルアクセストークンについて
LambdaからLINEへメッセージを送信するためには、送信先のチャネルを特定するためのアクセストークンを使用して、LineBotApiのインスタンスを作成する必要があります。
アクセストークンは、LINE Developersのコンソール画面で発行します。
Messaging API設定タブの一番下にある、チャネルアクセストークンの発行ボタンをクリックすることで発行されます。

今回はトークンをLambdaの環境変数に設定します。
Lambdaの 設定タブ > 環境変数 にある編集ボタンをクリックします。

環境変数の追加をクリックします。

以下の通りキーと値のフィールドを埋めて保存します。
- キー : LINE_CHANNEL_ACCESS_TOKEN
- 値 : LINE Developersで発行したアクセストークン

Lambdaのソースで環境変数に設定した値は、以下の手順によって参照できます。
1.osモジュールをインポートする(import os)。
2.os.environ['環境変数に設定したキー’] で値を参照する。
この手順とLineBotApiのインスタンス作成を行っているのが、以下のソースになります。
import os
~ 中略 ~
# 環境変数からLINE Botのチャネルアクセストークンを取得
LINE_CHANNEL_ACCESS_TOKEN = os.environ['LINE_CHANNEL_ACCESS_TOKEN']
# チャネルアクセストークンを使用して、LINE BotのAPIインスタンスを作成
LINE_BOT_API = LineBotApi(LINE_CHANNEL_ACCESS_TOKEN)
【注意2】LINEから受信するリクエストについて
LINEからメッセージを送った時、Lambdaには以下のようなjson形式のリクエストが送信されます。
{
"destination": "U3ffa107f8c7598f52c05b09220991ed8",
"events": [
{
"type": "message",
"message": {
"type": "text",
"id": "16236704138578",
"text": "★送信したテキストはここに保存されます★"
},
...,
"timestamp": 1654841339064,
"source": {
"type": "user",
"userId": "Ua**********"
},
"replyToken": "f9**********",
"mode": "active"
}
]
}
LINEで入力されたテキストは ['events’][0]['message’]['text’] に入っています。
また、受信したメッセージに対してリプライを行うには、replyTokenの値を使用します。
これらの内容を踏まえて実装したのが以下のコードになります。
# LINEからメッセージを受信
if event['events'][0]['type'] == 'message':
# メッセージタイプがテキストの場合
if event['events'][0]['message']['type'] == 'text':
# リプライ用トークン
replyToken = event['events'][0]['replyToken']
# 受信メッセージ
messageText = event['events'][0]['message']['text']
# メッセージを返信(受信メッセージをそのまま返す)
LINE_BOT_API.reply_message(replyToken, TextSendMessage(text=messageText))
最後に、Lambda実行のトリガーとなるAPI Gatewayを設定しましょう。
API Gatewayの設定
API Gatewayの作成はこれまでのブログ記事でも何度か触れていますので割愛しますが、
・REST APIで作成すること(※リクエストの形式が変わってしまうため)
・POSTメソッドを作成すること(※後述のWebhook設定のため)
の2つに注意してください。
また、今回はLambdaを簡単な実装にするため、Lambdaプロキシ統合は使用しません。
API Gatewayをデプロイした後に発行されるURLは、次の手順で使用するためコピーしておきましょう。

次に、API GatewayとLINEボットの連携を行います。
Webhookの設定
LINEから別のサービス(AWSなど)へリクエストを行う際、Webhookという仕組みを利用します。
Webhookとは簡単に言うと、あるアプリケーションで発生したイベントを、異なるアプリケーションへ通知する仕組みになります。今回のケースだと、LINEで発生したメッセージイベントを、AWS(API Gateway)に通知する必要がありますね。
またWebhookによる通知はPOSTリクエストで行われるため、API GatewayでPOSTメソッドを設定して、POSTリクエストを受信できるようにしています。

Webhookを利用するには、LINE側で通知先のURLを設定する必要があります。
Webhook URLは、Messaging API設定タブにあるWebhook設定から編集します。

先ほどコピーしておいたAPI GatewayのURLを貼り付けして更新します。

設定が完了したら、検証ボタンをクリックしてWebhookの動作に問題が無いことを確認します。

下のように、成功と表示されれば問題ありません。
エラーが起きた場合は、URLの誤りかPOSTメソッドの設定が出来ていない可能性があります。
API Gatewayの設定を確認して、URLを設定し直してみましょう。

最後に、Webhookの利用を有効化します。
今回はあくまで検証なので、Lambdaが何度も呼び出されて課金が発生しないようにするため、Webhookの再送は無効にしています。何かエラーが起きた場合は、API GatewayやLambdaの処理ログをCloudWatchで確認することにします。
また、エラーの統計情報は、Webhookの通知が失敗した時の情報を保存する機能になります。こちらは必要に応じて有効化しましょう。

ようやく全ての設定が完了です…!
早速、LINEからメッセージを送ってみましょう!
機能の検証
先述の通り、Messaging API設定 のタブにはLINEの友達追加用のQRコードが表示されています。
QRコードを読み取り、友達追加しましょう!
友達追加をすると、あいさつメッセージが送られてきます。

メッセージを送ってみると自動返信メッセージの後に、入力したメッセージが返ってくることが確認できます。
改行も含めて、そっくりそのまま返ってきていますね。今回の目標を達成できました!

補足
自動返信メッセージを送らないようにするには、次の設定を行ってください。
始めにMessaging API設定タブにある、LINE公式アカウント機能 > 応答メッセージ の編集リンクをクリックします。

開いたページ内にある 詳細設定 > 応答メッセージ の設定をオフにします。
オフを選択すると自動的に設定が保存されます。
(友達追加時のあいさつメッセージも、この画面から送信設定ができます)

再度、メッセージを送ってみると自動返信のメッセージが送信されないことが確認できました。

さいごに
今回はLINEボットの作成とLambdaとの連携まで説明しました。
メッセージをオウム返しするだけの簡単な作りではありますが、細かい設定が多々ありましたね。
Lambdaから他のAWSサービスへ連携させることで、機能の拡張が自由にできそうです!
次回は、Amazon Lexを利用してチャットボットを作成したいと思います。