はじめに

今回はLINEを利用した「おうむ返し」botの作成をしていきます。

動きとしてはLINEのMessaging APIを利用してAWS API Gatewayにメッセージを送信します。Lambdaを起動させてコードの動作を行い処理をおこないます(今回は送信されたメッセージをそのまま返すという処理)

構成図

スクリーンショット 2021-11-06 11.55.17.png

実装

1.LINE Developersでプロバイダーの登録

1.1 LINE Developersにログイン

URL:https://developers.line.biz/ja/ にアクセスしてログインをする
この際LINEに登録していない方はLINEのアカウントを取得する

スクリーンショット 2021-11-06 12.17.08.png

1.2 プロバイダーを新規作成する

ハンズオン用にプロバイダー名を__Project_20211106__にして新規作成
スクリーンショット 2021-11-06 12.18.31.png

1.3 Messaging APIを選択(チャンネル登録)

今回利用するMessaging API(チャンネル)を選択する
スクリーンショット 2021-11-06 13.30.37.png

1.4 Messaging APIの設定内容

チャンネル名がLINEで表示される名前となります
そのほかの項目も埋めていきます

スクリーンショット 2021-11-06 13.39.09.png

1.5 設定の確認

スクリーンショット 2021-11-06 8.14.56.png

1.6 作成完了画面

次に登録したチャンネルに設定があるので画面を開いたままにしておく
スクリーンショット 2021-11-06 15.47.42.png

2.作業ディレクトリ作成(ローカル環境)

LINE公式ドキュメントより、LINE APIのSDK(ソフトウェア開発キット)のPythonをダウンロードする
※注意書きにもあるようにダウンロードは必須ではありませんが、構築が容易になるので、このQiita記事ではダウンロードしています

スクリーンショット 2021-11-06 8.45.52.png

2.1 作業ディレクトリ作成とSDKインストール
tetutetu214@mbp projects % mkdir 20211106_parrot
tetutetu214@mbp projects % cd 20211106_parrot 
tetutetu214@mbp 20211106_parrot % python -m pip install line-bot-sdk -t .

インストール後のフォルダの一覧

tetutetu214@mbp 20211106_parrot % ls
__pycache__             future-0.18.2-py3.9.egg-info
aiohttp                 idna
aiohttp-3.8.0.dist-info         idna-3.3.dist-info
aiosignal               libfuturize
aiosignal-1.2.0.dist-info       libpasteurize
async_timeout               line_bot_sdk-2.0.1.dist-info
async_timeout-4.0.0.dist-info       linebot
attr                    multidict
attrs-21.2.0.dist-info          multidict-5.2.0.dist-info
bin                 past
certifi                 requests
certifi-2021.10.8.dist-info     requests-2.26.0.dist-info
charset_normalizer          typing_extensions-3.10.0.2.dist-info
charset_normalizer-2.0.7.dist-info  typing_extensions.py
examples                urllib3
frozenlist              urllib3-1.26.7.dist-info
frozenlist-1.2.0.dist-info      yarl
future                  yarl-1.7.2.dist-info
2.2 「lambda_function.py」ファイルを作成する

フォルダのなかに下記ファイル「lambda_function.py」を作成する
※このファイル名以外だと読み込まれないので注意する
スクリーンショット 2021-11-06 13.51.59.png

import os
import sys
import logging

from linebot import (LineBotApi, WebhookHandler)
from linebot.models import (MessageEvent, TextMessage, TextSendMessage)
from linebot.exceptions import (LineBotApiError, InvalidSignatureError)

logger = logging.getLogger()
logger.setLevel(logging.ERROR)

#LINEBOTと接続するための記述
#環境変数からLINEBotのチャンネルアクセストークンとシークレットを読み込む
channel_secret = os.getenv('LINE_CHANNEL_SECRET', None)
channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None)

#無いならエラー
if channel_secret is None:
    logger.error('Specify LINE_CHANNEL_SECRET as environment variable.')
    sys.exit(1)
if channel_access_token is None:
    logger.error('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
    sys.exit(1)

#apiとhandlerの生成(チャンネルアクセストークンとシークレットを渡す)
line_bot_api = LineBotApi(channel_access_token)
handler = WebhookHandler(channel_secret)

#Lambdaのメインの動作
def lambda_handler(event, context):

#認証用のx-line-signatureヘッダー
    signature = event["headers"]["x-line-signature"]
    body = event["body"]

#リターン値の設定
    ok_json = {"isBase64Encoded": False,
               "statusCode": 200,
               "headers": {},
               "body": ""}
    error_json = {"isBase64Encoded": False,
                  "statusCode": 500,
                  "headers": {},
                  "body": "Error"}

#メッセージを受け取る・受け取ったら受け取ったテキストを返信する
    @handler.add(MessageEvent, message=TextMessage)
    def message(line_event):
        text = line_event.message.text
        line_bot_api.reply_message(line_event.reply_token, TextSendMessage(text=text))

#例外処理としての動作
    try:
        handler.handle(body, signature)
    except LineBotApiError as e:
        logger.error("Got exception from LINE Messaging API: %s\n" % e.message)
        for m in e.error.details:
            logger.error("  %s: %s" % (m.property, m.message))
        return error_json
    except InvalidSignatureError:
        return error_json

    return ok_json
2.3 ファイルをzip化する

上述したファイルも含めて圧縮していく
スクリーンショット 2021-11-06 13.59.02.png

名前は自分で管理しやすいようにネーミングして構いません
スクリーンショット 2021-11-06 9.58.14.png

3.Lambdaの設定(AWSコンソール)

3.1 AWSマネジメントコンソールからLambdaを設定していく

マネジメントコンソールから「Lambda」と検索する
スクリーンショット 2021-11-06 14.02.55.png

3.2 Lambdaで「関数の作成」を押下して関数を作成していく

スクリーンショット 2021-11-06 14.06.13.png

「関数の作成」を押下後の遷移画面
関数名を記入、ランタイムはPython 3.8を選択します
実行ロールなどの設定は今回は不要のため手を加えてません
スクリーンショット 2021-11-06 14.12.30.png

3.3 Lambda関数の設定をする

「コード」「アップロード元」で「.zip ファイル」を選択します
スクリーンショット 2021-11-06 14.15.32.png
先ほど自分が作成したzipファイルを選択する
これが正常にアップロードされることで、ローカルで構築した内容が反映されます
スクリーンショット 2021-11-06 14.24.18.png

3.4 環境変数へアクセストークンを設定する

スクリーンショット 2021-11-06 14.20.20.png
環境変数として記述する内容(値は次章から確認をする)
スクリーンショット 2021-11-06 14.30.11.png

3.5 環境変数の値を確認する

開いたままにしていたLINE Developersを開いて、チャンネル基本設定Messaging API設定ページから確認して値の入力をする

__LINE_CHANNEL_ACCESS_TOKEN__該当箇所
スクリーンショット 2021-11-06 15.59.00.png

LINE_CHANNEL_SECRET該当箇所
スクリーンショット 2021-11-06 15.53.33.png

4 AWS API Gatewayを設定する

LINEからのWebhook(イベント発生時、指定したURLにPOSTリクエストを送信する仕組み)を受け取るためにAPI Gatewayを設定する

 4.1 トリガーを作成する

Lambda画面からトリガーを追加を押下する
スクリーンショット 2021-11-06 15.55.29.png

トリガーの設定「API Gateway」を選択する
APIタイプはHTTP APIで、セキュリティはオープンを選択する

スクリーンショット 2021-11-06 14.51.49.png

4.2 構築が完了したことを確認する

スクリーンショット 2021-11-06 15.13.49.png

5 LINE DevelopersにAWSの設定を登録する

5.1 作成されたAPIエンドポイントへのURLをLINE Developersに登録をする

スクリーンショット 2021-11-06 15.14.01.png

5.2 WebhookにURLをCOPYする

LINE Developersの「Messaging API設定」の「Webhook設定」にAPI Gatewayの「APIエンドポイント」のURLをCOPYする
COPYして更新後に表示される、Webhookの利用をON(緑色)にする
スクリーンショット 2021-11-06 16.02.16.png

5.3「あいさつメッセージ」の「編集」を押下して、詳細設定の__

「応答メッセージ」「オフ」にして、「Webhook」「オン」__にする

スクリーンショット 2021-11-06 16.02.29.png

6 LINE画面の確認

6.1 QRコードから友達登録の遷移

QRコードを読み取ると、お友達登録の画面へ遷移して登録することができる
スクリーンショット 2021-11-06 16.02.40.png

6.2 画面挙動の確認

LINE画面でメッセージを送信すると、メッセージがおうむ返しされる

スクリーンショット 2021-11-06 15.35.29.png

最後に

次回は「鸚鵡返し」をベースにして、LINEで写真を送信するとS3へ画像を保存される方法をハンズオンしていきたいと思います。

参照

Lambdaでline-bot-sdk-pythonを使用してオウム返しBOTを作成する
AWS Cloud9でオウム返しLINE Botを作る
Amazon API Gatewayは「HTTP API」と「REST API」のどちらを選択すれば良いのか?

Last modified: 2021-11-06

Author