🗻

Azure FunctionsのLINE botをPythonで実装してみた

2021/04/18に公開

以前、Live Coding Show でライブコーディングに挑戦した時に Azure Functions を使った LINE bot を実装しました。

その時は Python を使って実装したのですが、調べてみるとあまり Python と Azure Functions の事例があまりなかったので、今回は Python と Azure Functions を使った LINE bot を SDK を駆使して実装してみたので紹介します。

本番ではこれを実装できればよかったのですが、やり方を完全にど忘れしてしまって Json からコンテンツを取得するというベタ書きをしたので、ここでは罪滅ぼしも兼ねてますw。

なお、今回はコードの紹介のみなので、動作確認などの作業手順は以下の動画をご覧ください。(高評価よろしくおねがいしますw)

https://www.youtube.com/watch?v=a77CwhBsjm4&t=4242s

先に完成品

ソースコード
__init__.py
import os
import json
import logging

import azure.functions as func
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)

# 環境変数を取得
access_token = os.getenv('ACCESS_TOKEN')
channel_secret = os.getenv('CHANNEL_SECRET')

# インスタンスを定義
line_bot = LineBotApi(access_token)
handler = WebhookHandler(channel_secret)


def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    # Handlerから署名情報を取得
    signature = req.headers.get('X-Line-Signature')

    # リクエストボディを取得
    body = req.get_body().decode()
    logging.info(body)

    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        logging.info('invalid signature error')
        func.HttpResponse(status_code=400)

    return func.HttpResponse('ok', status_code=200)


@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    line_bot.reply_message(
        event.reply_token,
        TextSendMessage(text=event.message.text))

実装のポイント

ヘッダーの取得

req.headers.get('ヘッダーパラメータ名')でヘッダーのパラメータ名を取得することができます。

これで handler の呼び出しに必要な署名情報を与えることができます。

signature = req.headers.get('X-Line-Signature')

リクエストパラメータの取得

req.get_body()でリクエストボディを文字列で取得できます。

ここで取得できる文字列はバイト文字列なので、以下のようにデコードして handler の呼び出しに使える形式に変換します。

body = req.get_body().decode()

まとめ

Azure Fuctions で LINE bot を実装するときにはこれらのポイントを頭に入れれば後は SDK を使って bot の実装はできると思います。

Azure のドキュメントにはヘッダーの取得やリクエストボディの取得があまり詳しく書いてなくて、なんでここまで実装できたのか自分でも不思議ですw。

ライブコーディングのときにはこれを実装できればスマートだったかもしれませんね…

Discussion