Serverless FrameworkでLINE Botを作ってみた!


Serverless Frameworkとは

Serverless Framework はFaaS(Function as a Service)やクラウドのDB,Storageでアプリケーションを構成するためのフレームワークです。AWS以外にもGCP, Azureにも対応しています。
導入方法などは、こちらの記事を参考にしてください。

注意事項

・コマンドはMacを想定しているのでWindowsの方は、設定方法が異なると思います。
・AWSのアカウントを持っていないと、できません。
・LambdaやAPI Gatewayの設定を簡単に出来過ぎてしまうため、初めて触る方には、あまり理解できないかと思います。

LINE Botを作成

LINE DvelopersでLINE Botを作成します。
ログインしたら、画面下の作成をクリックします。

そうすると、プロバイダー名を入力する画面が表示されるので、好きな名前を入力します。

これでプロバイダーを作成できました。
次にチャネル(LINE Bot)を作成します。今回はおうむ返しするLINE Botを作成するのでMessaging APIを選択します。

LINE Botのアイコンや名前を入力する画面が出てくるので、入力します。

これでLINE Botの作成は終了です。

システム構成

今回作成するシステムは、ユーザーがLINE Botにメッセージを送信すると、WebhookでLambdaの関数が実行されるという感じです。
赤く囲っているところをServerless Frameworkで実装します。

AWSのアカウントをPCに関連付ける

AWS-CLIを利用してPCにAWSの情報を設定しておきます。
この記事を参考に

Let's Serverless

Serverless FrameworkをPCに導入したら、ターミナルで作業ディレクトリに移動して、以下のコマンドを実行します。
--templateオプションで指定しているのは、Lambdaで使用するプログラミング言語で、--pathオプションで指定しているのは、プロジェクト名とプロジェクトの配置場所です。適宜変更してください。

$ serverless create --template aws-python3 --path line-bot

コマンドを実行すると以下のディレクトリ構成でプロジェクトが作成されると思います。

line-bot
    ├ .gitignore
    ├ handler.py
    └ serverless.yml

serverless.ymlを書き換える

serverless.ymlを以下に書き換えます。

serverless.yml
service: line-bot
frameworkVersion: '2'

provider:
  name: aws
  runtime: python3.8
  region: ap-northeast-1  # 東京リージョンを指定

# Lambda関数の設定
functions:
  callback:
    handler: handler.callback

    # API Gatewayの設定
    events:
      - http:
          path: callback
          method: post

これで、API GatewayとLambdaの設定が終わりです。
簡単すぎますね...

Lambda関数を実装

次にLambdaが実行する関数を実装します。

Pythonの仮想環境を作成

Pythonなので、まず仮想環境を作ります。
自分は、venvで仮想環境を作りますが、conda や virtualenvで作る方もいると思うので、そこは適宜変更してください。

$ python3 -m venv line-bot

これを実行すると、line-botというディレクトリが生成されると思います。

line-bot
    ├ line-bot/  <-- 仮想環境用ディレクトリ
    ├ .gitignore
    ├ handler.py
    └ serverless.yml

生成されたら、以下のコマンドでactivateしてください。

$ source line-bot/bin/activate

LINE Botに使用するライブラリ

LINE Botの操作には、line-bot-sdkというライブラリを使用します。

$ pip3 install line-bot-sdk

handler.pyに実装

これで準備は完了なので、実際にコードを書きます。

handler.py
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage, ImageMessage
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot import (
    LineBotApi, WebhookHandler
)
import os

access_token = os.environ['LINE_CHANNEL_ACCESS_TOKEN']  // Lambdaの環境変数から取得
secret_key = os.environ['LINE_CHANNEL_SECRET']          // Lambdaの環境変数から取得

line_bot_api = LineBotApi(access_token)
handler = WebhookHandler(secret_key)

// LINE BotのWebhookで実行される関数
def callback(event, context):
    try:
        signature = event["headers"]["x-line-signature"]
        event_body = event["body"]
        handler.handle(event_body, signature)
    except InvalidSignatureError as e:
        logger.error(e)
        return {"statusCode": 403, "body": "Invalid signature. Please check your channel access token/channel secret."}
    except Exception as e:
        logger.error(e)
        return {"statusCode": 500, "body": "exception error"}
    return {"statusCode": 200, "body": "request OK"}

// おうむ返しをする関数
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=event.message.text)
    )

これで、Lambda関数の実装は終了です。

requirements.txtを出力

LambdaのPythonで使用するライブラリのリストを出力します。
activateした状態で以下のコマンドを実行します。

$ pip3 freeze > requirements.txt

requirements.txtに記載されているライブラリをデプロイしたときに、LambdaにインストールしてもらうためにServerless Frameworkにpluginを追加します。

$ npm install --save serverless-python-requirements

これでローカルで使用しているライブラリがLambdaでも利用できるようになります。

ひとまずデプロイ

ここまで来たら、一回デプロイをして見ましょう
以下のコマンドでデプロイできます。
slsは、serverlessの短縮形です。

$ sls deploy

これを実行したら、AWSのコンソール画面にいき、東京リージョンのLambdaを見にいきましょう
すると、実際にデプロイされていることが分かると思います。

LINE Botのアクセストークンとシークレットキーを見にいく

実装したLambda関数を実行するためには、LINE Botのアクセストークンとシークレットキーが必要になるので、LINE Developersのコンソール画面で見ます。

アクセストークンは、Messaging API設定の下の方にあります。

シークレットキーは、チャネル基本設定の下の方にあります。

Lambdaに環境変数を設定

上記で見た値をLambdaの環境変数にセットします。
この画面の少し下に、環境変数を設定できるところがあるので、このような形で保存します。

キー
LINE_CHANNEL_ACCESS_TOKEN ✖️✖️✖️✖️✖️✖️
LINE_CHANNEL_SECRET ✖️✖️✖️✖️✖️✖️

API GatewayのURLを見る

以下のところをクリックすると、API Gatewayから発行されているURLを確認できるので、見ておきましょう。

LINE BotのWebhookにLambda関数のURLを設定

LINE BotのMessaging API設定の画面のWebhookにAPI GatewayのURLを入力します。

入力後、検証ボタンをクリックして、成功画面が表示されたら、終了です。
LINE BotのQRコードが上の方に表示されていると思うのうで、そこから友達追加をすれば、おうむ返しBotで遊べると思います。

もしも、詰まったら

上記の検証をクリックして、レスポンスエラーが表示されたら、Lambda関数でエラーが出ていると思うので、以下のモニタリングのところから

この「CloudWatchのログを表示」をクリックすると、Lambda関数のログを見ることができるので、それを見てデバッグをして見てください。