24
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AWSで自分用のLINE Botを作った①

Last updated at Posted at 2022-08-06

はじめに

傘を持たずに出掛けて、午後から雨が降ってしまって困ることありますよね。
天気予報を朝見れば良いのでしょうが、少し面倒です。

というわけで、AWSの無料枠を使って自分への通知用のLINE Botを作ろうと思いました。
朝、天気予報サイトのデータを自動でスクレイピングして、予報が雨なら「今日は傘が必要です」というようなメッセージが配信されるようなイメージです。他にも電車の遅延状況の通知もできたら便利そうです。(既にこのようなサービスはありそうですが。。)

今回の内容

AWSもLine APIもそこまで触ったことがないので、まずは簡単な部分から実装を目指します。
今回の記事では図のようなAWS環境を構築しました。
2つあるLambdaの機能はそれぞれ以下のとおりです。使用言語はPythonです。

  • 返信用(reply_message関数):単純なオウム返しの機能
  • 配信用(push_message関数):定型文の配信

system_conf-aws.drawio.png

実装編

LINE Botを作るには、まずLINE Developersコンソールにログインして、チャネルを作る必要があります。チャネルの作り方は以下の公式ドキュメントに書かれています。

今回はMessaging APIを利用する方式にしています。そうするとWebhook URL(LINEプラットフォームからボットにイベントを送信する際の送信先URL)を設定できるようになります。
このWebhook URLに、reply_message関数呼び出し用のAPI GatewayのURLを指定することで、登録ユーザーのチャットに返信できるようになります。

AWS Lambdaの実装

Python SDK

LINE Botの作成用には、以下のようなMessaging APIのSDKがあります。

今回はPythonを使用するため、こちらの公式Python SDKを利用します。

Lambdaで外部パッケージを利用する方法はいくつかあるようですが、今回はLambdaレイヤーを利用する方法を採用しました。レイヤーにzip化したパッケージをアップロードすることで、複数のLambdaで共通してパッケージを利用できるようになります。
Lambdaはレイヤーのpythonディレクトリにあるパッケージを読み込みます。そのため、以下のようなコマンドでzipファイルを作成し、用意したレイヤーにアップロードします。

#pythonディレクトリにパッケージをインストール
$ pip install line-bot-sdk -t ./python

#pythonディレクトリごとzip化(ファイル名は何でも良い)
$ zip -r extra_package.zip ./python/

(補足)開発環境

  • Ubuntu 20.04.4 LTS
  • Python 3.10.4
  • line-bot-sdkパッケージ 2.3.0
  • Lambdaランタイム python3.9

reply_message関数

まずは単純なオウム返しの機能を持つreply_message関数を実装します。
事前の準備として、上で用意したレイヤーを参照するようにしておきます。また、以下の環境変数を追加します。どちらもLINE Developersコンソールから値を取得できます。

  • CHANNEL_ACCESS_TOKEN:チャネルのアクセストークン(今回はlong-lived版を使用)
  • CHANNEL_SECRET:チャネルのシークレット

reply_message関数に登録したソースコードは以下のようになります。テキストメッセージを受信したら、同じテキストを返信する処理を実装しています。

lambda_function.py
import os

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

# LINE BotのAPI
line_bot_api = LineBotApi(os.environ['CHANNEL_ACCESS_TOKEN'])
# Webhook(メッセージ等のイベント)のハンドラー
handler = WebhookHandler(os.environ['CHANNEL_SECRET'])


def lambda_handler(event, context):
    # LINE Platformから送信されるリクエストの署名とボデイ
    signature = event['headers']['x-line-signature']
    body = event['body']

    # ハンドラーにより署名を検証してWebhookを処理する
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        print("Invalid signature. Please check your channel access token/channel secret.")
        return {
            'statusCode': 400
        }

    return {
        'statusCode': 200,
    }


# ハンドラーにテキスト型メッセージを受信した場合の処理を追加
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    # 受信したメッセージに対して同じテキストを返信
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=event.message.text))

(補足)Webhookについて

Webhookというのは、LINE Platformで発生したイベントを他システムに送信する仕組みのことです。今回は、Webhook URLとして指定したreply_message関数(API Gateway経由)にイベントが送信されます。イベントにはLINE Botのフォローや、メッセージ送信などがあります。使用したLINE Bot SDKでは、Webhookハンドラーに対して、デコレータを使ってWebhookイベントに対する処理を実装していきます。

push_message関数

次に定型文を配信する機能を持つpush_message関数を実装します。
reply_message関数と同様に、事前の準備としてレイヤーの参照と、環境変数の登録を行います。

push_message関数に登録したソースコードは以下のようになります。このLambda関数が実行されると"Hello World"というメッセージが自分に対して送信されます。ちなみに、自分のLINEユーザIDはreply_message関数の実行ログなどから確認できます(print関数などでbodyを出力しておくとCloudWatchログから見えます)。

lambda_function.py
import os

from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import LineBotApiError
from linebot.models import TextSendMessage

# LINE BotのAPI
line_bot_api = LineBotApi(os.environ['CHANNEL_ACCESS_TOKEN'])


def lambda_handler(event, context):
    # 送信先のLINEユーザーID
    user_id = {自分のLINEユーザID}
    try:
        # メッセージの送信
        line_bot_api.push_message(
            user_id, TextSendMessage(text='Hello World!'))
    except LineBotApiError as e:
        # error handle
        print("Failure push message.")
        return {
            'statusCode': 400
        }

    return {
        'statusCode': 200
    }

動作の確認

実際に作成したLINE Botを友達登録して動作確認してみました。
送信したテキストメッセージと同じメッセージが返信されています。また、push_message関数を起動すると定型メッセージが配信されています。正しく動いているようです(よかった!)。

line bot動作確認

おわりに

今回はAWS LambdaとPythonを使って簡単な機能のLINE Botを作ってみました。
今後はもともとの目的だった天気情報のスクレイピングや、DynamoDBを使ってユーザ情報の管理などを試してみたいです。

(続く)

24
26
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?