AWSを活用してLINEチャットボットを作ってみた!①

こんにちは、宮内です。
以前にブログで紹介した「到着メール通知サービス」では、Eメールを使用して通知を行っていました。

しかしEメールを使用していると、メールサービスの種類によってメッセージのフォーマットが異なっていたり、添付画像が正しく表示されなかったりと不便な点がありました。
こうした機能の改善と利用者側の使いやすさを考え、多くの方が利用している LINE を通知先として検証することにしました。

今回から3回にかけて、LINEとAWSを組み合わせたチャットボット開発について説明します。
内容としては、以下を予定しています。

 ① LINEボットの作成とLambdaの連携
 ② Amazon Lexによるチャットボットの作成
 ③ チャットボットとLambdaの連携

今回の目標

今回は、LINEボットの作成とLambdaの連携まで説明します。
システム概要図は次のようになります。

LINEボットとAWSの連携 構成図

処理のイメージとしては、
 ① LINEで受け取ったメッセージを、API Gatewayを経由してLambdaに連携
 ② Lambdaでメッセージを認識して、LINEのリプライ(返信)メッセージを作成
となります。

なお、今回の記事で作成するLambdaは、LINEから受け取ったメッセージをそのまま返す処理とします。
通知サービス用のプログラムは、3回目の記事で説明します。

LINEボットの作成

まずはLINEボットを作成するため、LINE Developersへアクセスします。
▼LINE Developers(URL)
https://developers.line.biz/ja/

アクセスすると次のページが開くので、コンソールをクリックします。

LINE Developer トップ画面

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

LINE Developer ログイン画面

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

LINE Developer 個人アカウントでログイン

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

LINE Developer コンソール画面

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

LINE Developer プロバイダ作成

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

LINE Developer チャネル選択

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

LINE Developer チャネル設定

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

LINE Developer チャネル作成確認

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

LINE Developer チャネル作成 情報利用に関する同意

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

LINE Developer チャネル作成完了

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

LINE Developer QRコード

以上で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 LineBotSdkのレイヤー設定

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設定タブの一番下にある、チャネルアクセストークンの発行ボタンをクリックすることで発行されます。

LINE Developer チャネルアクセストークン発行

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

Lambda 環境変数の編集

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

Lambda 環境変数の追加

以下の通りキーと値のフィールドを埋めて保存します。

  • キー : LINE_CHANNEL_ACCESS_TOKEN
  •   : LINE Developersで発行したアクセストークン
Lambda 環境変数の追加内容

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の設定

次に、API GatewayとLINEボットの連携を行います。

Webhookの設定

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

Webhookの仕組み

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

LINE Developer Webhook設定

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

LINE Developer WebhookURLの更新

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

LINE Developer Webhookの検証

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

LINE Developer Webhookの検証成功

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

LINE Developer Webhookの有効化

ようやく全ての設定が完了です…!
早速、LINEからメッセージを送ってみましょう!

機能の検証

先述の通り、Messaging API設定 のタブにはLINEの友達追加用のQRコードが表示されています。
QRコードを読み取り、友達追加しましょう!
友達追加をすると、あいさつメッセージが送られてきます。

LINEボット あいさつメッセージ

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

LINEボット Lambda処理の確認

補足

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

LINE Developer 応答メッセージの設定

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

LINE Developer 応答メッセージの設定変更

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

LINE 応答メッセージ無効化の確認

さいごに

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