LoginSignup
0
0

More than 1 year has passed since last update.

S3アップロードをトリガーに画像をLambdaでDropbox Businessにアップロードする

Posted at

LambdaでS3にある画像をDropbox Businessにアップロードするを改修し、
トリガーをS3アップロードに変更したときの個人メモ

(参考)チュートリアル: Amazon S3 トリガーを使用して Lambda 関数を呼び出す


ソース修正

  • 以下のようにソースを改修
lambda_function.py
import os
import logging
import boto3
import urllib.parse
import base64
import requests
import json

# ログ設定
logger = logging.getLogger(__name__)
logger.setLevel(os.environ['LOG_LEVEL'])

# Dropbox設定
# ルートフォルダを指定
NAMESPACE_ID = os.environ['NAMESPACE_ID']
APP_KEY = os.environ['APP_KEY']
APP_SECRET = os.environ['APP_SECRET']
REFRESH_TOKEN = os.environ['REFRESH_TOKEN']



# S3から指定したバケット、フォルダ、ファイル名の画像を取得する
# 取得できる画像サイズはLambdaのメモリーに依存
# return:画像のバイナリデータ
def get_img_from_s3(bucket_name, file_path):
    logger.debug('start get_img_from_s3()')

    s3 = boto3.client('s3')
    response = s3.get_object(Bucket=bucket_name, Key=file_path)
    body = response['Body'].read()

    logger.debug('end get_img_from_s3()')

    return body


# リフレッシュトークンからアクセストークンを取得する
# return:アクセストークン
def get_token():
    logger.debug('start get_token()')

    data = {
      'grant_type': 'refresh_token',
      'refresh_token': REFRESH_TOKEN
    }

    response = requests.post('https://api.dropbox.com/oauth2/token', data=data, auth=(APP_KEY, APP_SECRET))
    logger.info('response:' + json.dumps(response.json(),default=str))

    access_token = response.json()['access_token']
    logger.debug('access_token:' + access_token)

    logger.debug('end get_token()')

    return access_token


# 画像をDropboxにアップロードする
# img:画像のバイナリデータ
# return:アップロード結果
def upload_to_dropbox(access_token, img, file_path):
    logger.debug('start upload_to_dropbox()')

    arg = '{"path": "' + '/' + file_path + '","mode": "add","autorename": true,"mute": false,"strict_conflict": false}'

    headers = {
        'Authorization': 'Bearer ' + access_token,
        'Dropbox-API-Arg': arg.encode("utf_8"),
        'Content-Type': 'application/octet-stream',
        'Dropbox-API-Path-Root': '{".tag": "namespace_id", "namespace_id": "' + NAMESPACE_ID + '"}',
    }

    response = requests.post('https://content.dropboxapi.com/2/files/upload', headers=headers, data=img)
    logger.info('response:' + json.dumps(response.json(),default=str))

    logger.debug('end upload_to_dropbox()')

    return json.dumps(response,default=str)


def lambda_handler(event, context):
    logger.debug('start lambda_handler()')

    # S3設定
    bucket_name = event['Records'][0]['s3']['bucket']['name']
    logger.info('bucket_name:' + bucket_name)

    # 画像ファイル情報
    file_path = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    logger.info('file_path:' + file_path)

    img = get_img_from_s3(bucket_name, file_path)
    access_token = get_token()
    result = upload_to_dropbox(access_token, img, file_path)

    logger.debug('end lambda_handler()')

    return result

テストイベントJSON設定

  • 以下のようにテストイベントJSONを設定
    • バケット名とオブジェクトキー以外はテンプレートのまま利用
{
  "Records": [
    {
      "eventVersion": "2.0",
      "eventSource": "aws:s3",
      "awsRegion": "us-west-2",
      "eventTime": "1970-01-01T00:00:00.000Z",
      "eventName": "ObjectCreated:Put",
      "userIdentity": {
        "principalId": "EXAMPLE"
      },
      "requestParameters": {
        "sourceIPAddress": "127.0.0.1"
      },
      "responseElements": {
        "x-amz-request-id": "EXAMPLE123456789",
        "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH"
      },
      "s3": {
        "s3SchemaVersion": "1.0",
        "configurationId": "testConfigRule",
        "bucket": {
          "name": "(バケット名)",
          "ownerIdentity": {
            "principalId": "EXAMPLE"
          },
          "arn": "arn:aws:s3:::example-bucket"
        },
        "object": {
          "key": "image/escle.png",
          "size": 1024,
          "eTag": "0123456789abcdef0123456789abcdef",
          "sequencer": "0A1B2C3D4E5F678901"
        }
      }
    }
  ]
}
  • Testを実行し、動作が改修前後で差異がないことを確認

トリガー設定

  • 「トリガーを追加」を押下

000.JPG

  • S3バケットを指定し、「追加」を押下

001.JPG

  • 追加されたことを確認

002.JPG

動作確認

  • 任意のフォルダにアップロード

003.JPG
004.JPG

  • アップロードされたことを確認

005.JPG

  • Lambdaのログを確認

006.JPG

  • Lambdaが実行されたことを確認

007.JPG

  • Dropboxにアップロードされたことを確認

008.JPG

感想

  • テストイベントJSONを利用することで問題を切り分けながら改修できた
  • 大量の画像がアップロードされたときの性能まわりは気になる
  • エラー処理等も運用含めて考えていきたい
0
0
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
0
0