1
1

LINEボットで投稿した画像をAWS S3に保存する

Last updated at Posted at 2023-12-03

多くの人が、同じことをブログに書かれてますが、自分用の備忘録として残します。

コードはほとんどChatGPT、
AWSの設定はこちらの方のブログを見ながらやりました。
https://cloud5.jp/lambda-linebot-s3/
ありがとうございました。


準備

LINE Messaging API の設定
こちらの 「2-2.LINEチャットボット開発前の設定」をご覧ください。


作業ディレクトリを作成

mkdir line-s3
cd line-s3

必要なライブラリをインストールする

pip install line-bot-sdk 
pip install bot3
pip install requests

私は「pip install bot3」で
こんなエラーがでた、

ERROR: Could not find a version that satisfies the requirement bot3 (from versions: none)
ERROR: No matching distribution found for bot3

これだと通った。

pip3 install boto3 --upgrade

コード作成

「lambda_function.py」を作成する
※このファイル名以外だと読み込まれないので注意

lambda_function.py
import json
import os
import urllib.request
import logging
import boto3

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

LINE_CHANNEL_ACCESS_TOKEN = os.environ['LINE_CHANNEL_ACCESS_TOKEN']
S3_BUCKET_NAME = os.environ['S3_BUCKET_NAME']  # S3バケット名を環境変数から取得

REQUEST_URL = 'https://api.line.me/v2/bot/message/reply'
DOWNLOAD_URL = 'https://api-data.line.me/v2/bot/message/{messageId}/content'
REQUEST_METHOD = 'POST'
REQUEST_HEADERS = {
    'Authorization': 'Bearer ' + LINE_CHANNEL_ACCESS_TOKEN,
    'Content-Type': 'application/json'
}

s3_client = boto3.client('s3')  # S3クライアントの初期化

def lambda_handler(event, context):
    logger.info(event)
    body = json.loads(event['body'])
    events = body['events']
    if events[0]['message']['type'] == 'image':
        message_id = events[0]['message']['id']
        reply_token = events[0]['replyToken']
        save_image_to_s3(message_id)
        reply_to_line(reply_token, '画像を保存しました!')
            
    return 0

def save_image_to_s3(message_id):
    download_url = DOWNLOAD_URL.format(messageId=message_id)
    download_headers = {'Authorization': 'Bearer ' + LINE_CHANNEL_ACCESS_TOKEN}

    # LINEから画像をダウンロード
    request = urllib.request.Request(download_url, headers=download_headers)
    response = urllib.request.urlopen(request)
    image_data = response.read()

    # S3に画像をアップロード
    file_path = 'line_images/' + message_id + '.jpg'
    s3_client.put_object(Bucket=S3_BUCKET_NAME, Key=file_path, Body=image_data)

def reply_to_line(reply_token, message_text):
    reply_message = [
        {
            'type': 'text',
            'text': message_text
        }
    ]
    params = {
        'replyToken': reply_token,
        'messages': reply_message
    }
    request = urllib.request.Request(
        REQUEST_URL, 
        json.dumps(params).encode('utf-8'), 
        method=REQUEST_METHOD, 
        headers=REQUEST_HEADERS
    )
    urllib.request.urlopen(request, timeout=10)

これをzipファイルにする。

AWS

S3

S3の設定はこちらをご覧ください。


Lambda

新しい関数を作成し、
さきほど作成したzipファイルをアップロードする。

Pythonhのバージョンは「lambda_function.py」と同じにする。

アップロードされた。
Image from Gyazo


環境変数

Image from Gyazo

Image from Gyazo

トリガー設定

Lambda画面からトリガーを追加を押下する

Image from Gyazo

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

API Gateway

アクション > メソッドの作成
Image from Gyazo

「POST」を選択
Image from Gyazo

以下のように設定
Image from Gyazo

ANYを削除
Image from Gyazo

デプロイ
Image from Gyazo


デプロイされるステージは「default」を選択



さっき作ったAPI Gateway を削除
Image from Gyazo


アクセス権限の設定

ここは毎回忘れるので、自分用に作って良かった。

アクセス権限 
ロール名をクリック
Image from Gyazo

許可を追加 > ポリシーをアタッチ
Image from Gyazo

[AmazonAPIGatewayInvokeFullAccess]を追加

Image from Gyazo

もう1つ「AmazonS3FullAccess」を追加
Image from Gyazo

エンドポイントURLを LINE Developer のwebhookに登録する
Image from Gyazo

これで、LINEボットに画像を投稿すると、AWS S3に保存されます。


1
1
0

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
1
1