GASからAWS API Gateway(Lambda)へリクエスト送信、ファイルをS3へアップ

GAS → API Gatewayのリクエストのみ(レスポンスなし)でJSONファイルをS3へアップロードする。
主な手順
- S3バケットを作成
- 権限作成
- 該当バケットへの
s3:PutObjectポリシー作成 - ロールにポリシーをつけて作成
- 該当バケットへの
- Lambda
- 実行ロールに先程作成したロールを付与
- 関数作成
- デプロイ
- テスト
- Execution resultsが200で成功することを確認
- テスト
- デプロイ
- API Gateway
- リソース作成
- REST APIで作成し、
- APIキーを有効化する場合(今回は割愛)
- APIキー > アクション > APIキーの作成
- 使用量プラン > 作成
- リソース > APIキーの必要性 をtrueにしてキー選択
- WAFの設定
- WAFのページからIPセットを作成しておく
- ステージ > 該当ステージ > 設定 > ウェブアプリケーションファイアウォール (WAF) から設定
- デプロイ
- リソース > アクション > APIのデプロイ
- リソース作成
- GAS
- JSONファイルを作成する(今回は割愛)
UrlFetchApp()でリクエストを投げる
コード
ポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ExampleStmt",
"Action": [
"s3:PutObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::MY-BACKET-NAME/*"
]
}
]
}
Lambda
少しハマった点として、object putする際に ContentType=‘application/json’ など明示的に指定をしないと、Lambda側で自動でContentTypeが設定されてしまう。
参考: python - AWS Content Type Settings in S3 Using Boto3 - Stack Overflow
lambda_function.py
import json
import boto3
s3 = boto3.resource('s3')
# バケット名を指定
BUCKET_NAME = "MY-BACKET-NAME"
def lambda_handler(event, context):
# request_idを取得
request_id = context.aws_request_id
# バケット名、オブジェクト名を指定
bucket = s3.Bucket(BUCKET_NAME)
object_key_name = "PATH/MY-JSON-NAME.json"
# オブジェクトを生成
obj = bucket.Object(object_key_name)
# 対象のバケットにjsonデータをアップロード
json_data = event
r = obj.put(Body = json.dumps(json_data), ContentType='application/json')
return {
'request_id': request_id,
'statusCode': 200,
}
GAS
function uploadS3() {
const endpoint = 'MY-API-END-POINT'
const json = JSON.stringify({"key1": "value1"})
const params = {
'method' : 'post',
'contentType': 'application/json',
'payload' : json
};
const req = UrlFetchApp.fetch(endpoint, params)
Logger.log(req.getContentText())
}