【Python】Line Botで画像を扱う方法(line-bot-sdk-python)

Line Botを使ったアプリ開発では、テキストメッセージのやり取りだけでなく、画像を取り扱いたい場合もあると思います。

この記事では、PythonでLine Botを実装する場合に、画像を取り扱う方法を紹介します。

想定している状況

下図のように、用意したLine Botチャネルに画像を送信して、何らかの処理を行うことを想定しています。


例えば、以前の記事で紹介した名刺管理アプリでは、名刺画像を送信すると読み取り処理を実行する仕組みを構築しています。もしよければこちらもご参照ください!

line-bot-sdk-pythonの利用

PythonでのLine Bot開発はline-bot-sdk-pythonを使用すると、格段に楽になります。
SDKのソースは以下から見れます。

様々な実装例も載っているので、これを見れば大体のことはわかると思います。

もし、このSDKを使用しないのであれば、Line Developers Messaging API記載の通りにHTTPS通信を直接操作することになります。
ただ、これはかなり面倒なので、その辺りを意識しなくて良いSDKを使う方がいいですね。

以下コマンドでインストールします。

$ pip install line-bot-sdk

若干紛らわしいのですが、コンテンツ取得用メソッドは二つあります。
画像取得には、MessagingApiBlobを用います。

  • MessagingAPI ・・・テキスト取得用
  • MessagingApiBlob・・・画像、動画、音声取得用

BLOBとは、Binary Large Objectの略です。
データ型の一つで、テキストや整数などの既存のデータ型に属さない任意のバイナリデータを格納するためのものです。

以下に実装例を記載します。(Web APIフレームワークはFastAPIを使用しています)

from fastapi import Request, FastAPI, HTTPException
from linebot.v3 import WebhookHandler
from linebot.v3.messaging import (
    ApiClient,
    MessagingApiBlob,
    Configuration
)
from linebot.v3.exceptions import (
    InvalidSignatureError
)
from linebot.v3.webhooks import (
    ImageMessageContent,
    MessageEvent
)

channel_secret = os.getenv('LINE_CHANNEL_SECRET', None)
channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None)
if channel_secret is None:
    print('Specify LINE_CHANNEL_SECRET as environment variable.')
    sys.exit(1)
if channel_access_token is None:
    print('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
    sys.exit(1)

configuration = Configuration(
    access_token=channel_access_token
)
api_client = ApiClient(configuration)
line_bot_api_blob = MessagingApiBlob(api_client)
handler = WebhookHandler(channel_secret)

@app.post("/callback")
async def handle_callback(request: Request):
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = await request.body()
    body = body.decode('utf-8')

    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        raise HTTPException(status_code=400, detail="Invalid signature")

    return 'OK'

@handler.add(MessageEvent, message=ImageMessageContent)
def handle_image(event):
    message_id = event.message.id    
    image_content = line_bot_api_blob.get_message_content(message_id) #バイナリデータ
    
    #これで画像のバイナリデータを取得できたので、このあとは任意の処理を行えばOKです。

上記はあくまで実装例ですが、MessagingAPIBlobを利用することで、画像のバイナリデータを取得することができます。

さいごに

当初line-bot-sdk-pythonの実装例で使用されていたMessaginAPIを利用しても画像を取得できず。
画像取得する方法をネットで調べてもヒットしなかったので、Gitのソースを調べたところ見つけることができました。

同じことで困っている人の参考になれば幸いです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする