LoginSignup
0

More than 1 year has passed since last update.

posted at

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

LambdaでS3にある画像をDropbox Businessにアップロードしたときの個人メモ


前提

実行準備

  • チームスペースの共有フォルダにアップロードする場合は
    ルートフォルダを指定する必要がある
  • ルートフォルダのIDは事前に取得が必要

アプリの作成

  • Dropbox Business用にアプリ作成が必要
  • 「Full Dropbox」で作成
    • 「App folder」の場合、自動的にアプリ専用のフォルダが生成されるが、
      アプリを作成した個人のフォルダ内に作成される

028.JPG

root_namespace_idの取得

  • get_current_accountを利用してroot_namespace_idを確認する
  • API実行に必要な「account_info.read」はデフォルトで付与されているため
    アプリの権限変更はここでは不要

029.JPG

  • CloudShellにて実行
curl -X POST https://api.dropboxapi.com/2/users/get_current_account \
    --header "Authorization: Bearer <get access token>"
  • 実行結果から「root_namespace_id」を見つける
    • Dropbox Businessの場合、「home_namespace_id」と
      「root_namespace_id」が一致しない
    • ユーザー版と同様にuploadした場合、ルートフォルダは
      「home_namespace_id」をデフォルト指定することになる
{
     "account_id":"dbid:xxxx"
    ,"name":{
         "given_name":"xxxx"
        ,"surname":"xxxx"
        ,"familiar_name":"xxxx"
        ,"display_name":"xxxx"
        ,"abbreviated_name":"xxxx"
    }
    ,"email":"xxxx@gmail.com"
    ,"email_verified":true
    ,"disabled":false
    ,"country":"JP"
    ,"locale":"ja"
    ,"referral_link":"https://www.dropbox.com/referrals/xxxx"
    ,"team":{
         "id":"dbtid:xxxx"
        ,"name":"xxxx"
        ,"sharing_policies":{
             "shared_folder_member_policy":{
                 ".tag":"anyone"
            }
            ,"shared_folder_join_policy":{
                 ".tag":"from_anyone"
            }
            ,"shared_link_create_policy":{
                 ".tag":"default_public"
            }
        }
        ,"office_addin_policy":{
             ".tag":"enabled"
        }
    }
    ,"team_member_id":"dbmid:xxxx"
    ,"is_paired":true
    ,"account_type":{
         ".tag":"business"
    }
    ,"root_info":{
         ".tag":"team"
        ,"root_namespace_id":"123456789"
        ,"home_namespace_id":"xxxx"
        ,"home_path":"/xxxx@gmail.com"
    }
}

ソース修正

lambda_function.py
import boto3
import base64
import requests
import json

ACCESS_TOKEN = '(取得したアクセストークン)'

#ルートフォルダを指定
NAMESPACE_ID = '123456789'

#ルートフォルダ配下の配置場所
FOLDER_PATH = "/image/"
#ファイル名
FILE_NAME = 'escle.png'

ARG_TMP = '{"path": "' + FOLDER_PATH + FILE_NAME + '","mode": "add","autorename": true,"mute": false,"strict_conflict": false}'
ARG = ARG_TMP.encode("utf_8")

# S3から指定したバケット、フォルダ、ファイル名の画像を取得する
# 取得できる画像サイズはLambdaのメモリーに依存
# return:画像のバイナリデータ
def get_img_from_s3():
    s3 = boto3.client('s3')
    bucket_name = 'xxxx'
    file_path = 'sample/' + FILE_NAME
    response = s3.get_object(Bucket=bucket_name, Key=file_path)
    body = response['Body'].read()
    return body

# 画像をDropboxにアップロードする
# img:画像のバイナリデータ
# return:アップロード結果
def upload_to_dropbox(img):
    headers = {
        'Authorization': 'Bearer ' + ACCESS_TOKEN,
        'Dropbox-API-Arg': ARG,
        '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)
    return json.dumps(response,default=str)


def lambda_handler(event, context):
    img = get_img_from_s3()
    result = upload_to_dropbox(img)

    return result

実行手順

  • ユーザー版と同様に実行できる
  • 以下のルートフォルダ直下のimageフォルダ内に画像ファイルがアップロードされる
    • ルートフォルダを指定しない場合はユーザーフォルダ「xxxx@gmail.com」内に
      imageフォルダが作成され、その中に画像ファイルがアップロードされる
    • 「App folder」のAPIの場合、「xxxx@gmail.com」内にアプリ名のフォルダが
      作成され、その中にimageフォルダが作成され、画像ファイルがアップロードされる

032.png

感想

  • Dropbox Businessだとルートフォルダが異なることに気づくまで時間がかかった
    • 安全な仕様だが、ユーザー版と比較して挙動が変わったように見えるのでとまどった
    • uploadのリファレンスからヘッダー「Dropbox-API-Path-Root」にたどりつけなかった
  • エラー時のレスポンスにステータスコードしか含まれておらず、調査が難航した
    • うまくメッセージを取得する方法はあるかもしれないが
  • 詰まったらリファレンス以外の公式ドキュメントを漁るくせをつけたい

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
What you can do with signing up
0