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

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

---
# 構成図
![000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242897/24855f5e-5fd6-66ff-560b-e74a2d61535e.png)

# 前提
[LambdaでDropbox APIを実行する](https://qiita.com/nkmk1215/items/573bce8924f42d4d9690)ができていること

# 実行準備
## S3
- Dropboxにアップロードするファイルを配置
![004.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242897/393dc4aa-dcd1-de56-667a-b2ee9d452148.jpeg)

## Lambda
### 作成
- Python3.9にて
![000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242897/a361edec-62d4-7ec5-d320-ea8b1f95b94c.jpeg)
- コードは以下

```lambda_function.py
import boto3
import base64
import requests
import json

ACCESS_TOKEN = '（取得したアクセストークン）'

#ルートフォルダ配下の配置場所
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 = '（バケット名）'
    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',
    }

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

### S3を読み込むための権限を付与
- ロールを選択
![008.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242897/46702c09-a746-c17b-9c20-368c21087104.jpeg)

- ポリシーを編集
![009.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242897/92234564-fa2e-44d7-db6e-5bb6454385eb.jpeg)

- S3の「GetObject」を追加
![010.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242897/d29e700d-7cf8-d43b-984d-344c16cdcc31.jpeg)

- リソースは当該バケットに限定する
![012.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242897/5794ab19-de14-c706-d3bd-58c60714fe9b.jpeg)

※ARNはS3の画面から取得する
![011.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242897/fc84813b-5af0-9854-2596-d81f34687e44.jpeg)

### HTTPリクエストのためにレイヤーの追加
- CloudShellにて以下を実行

[【Lambda】import requests が使えるようにする【python】](https://qiita.com/afukuma/items/b7191025700a7829967c)

- レイヤーが追加されたことを確認
![023.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242897/5fcc31cd-15df-634e-32d1-dca5c95006bd.jpeg)

## Dropbox
- [uploadのリファレンス](https://www.dropbox.com/developers/documentation/http/documentation#files-upload)を確認し、「files.content.write」が必要なことを確認
![026.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242897/f4d56060-f086-33d6-07b6-8b94e1ec1135.jpeg)
- アプリに権限を追加　※[LambdaでDropbox APIを実行する](https://qiita.com/nkmk1215/items/573bce8924f42d4d9690)で利用したアプリを利用
![027.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242897/f9309fe1-19e1-351b-0f19-00fa0f1a4607.jpeg)


# 実行手順
- Lambdaを実行
![024.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242897/0e24e49d-be37-47a1-accd-4a9b9060f5a3.jpeg)

- Dropboxにアップロードされていることを確認
![025.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242897/7423ea7a-2957-345c-7cd2-52c78c635808.jpeg)

# 感想
- レイヤーの追加が面倒だったが、それ以外は簡単だった
- 現状だとファイル名は固定なので動的設定できるようにしたい