S3の画像URLをLabdaで取得したいだけ
やりがいことはAWSのS3に保存した画像URLをAWSのLambdaで取得してきて、そのURLをSNSやメールで投げたいだけ。なお筆者はS3の画像URLがどれなのかで一番つまずいた。
Amazon S3>バケット>localstable(任意の名前)>mumumu.png(任意の名前)の中にある【オブジェクトURL】がまさにそれである。
恐らくそれだろうという目星は筆者もすぐについた。
だがクリックしても下記のようなよく分からないエラーが出る。
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>M9DEV</RequestId>
<HostId>1ltHaEH/kZp5nol7r77C4xdwg0qt+Giq0quVh1HYsuJQvA==</HostId>
</Error>
S3+lambda+画像+取得などで検索すると署名付きURLの取得方法が書かれたものが大量にでてくるが、求めているのはそれではない。
単純に画像URLをLambdaで使いたいだけである。
オブジェクトURLを公開(有効)にする
【パケット】を選択
S3でパケットを選択し、自分で作ったパケットを選択:Amazon S3>バケット>localstable(任意)
【アクセス許可】を選択
オブジェクトやプロパティなどと書かれたタブのなかから
【ブロックパブリックアクセス (バケット設定)】を編集
【パブリックアクセスをすべてブロック】からチェックを外す
すべてチェックされていないことを確認し【変更を保存】する → 少し心配だか気にしたら負け
【パケットポリシー】(はじめは空欄)を編集
下記項目加筆する。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::localstable(任意)/*"
}
]
}
Verionが古いと思ったが、2023年アマゾンが指定しているで不安かもしれないが問題なし。違うものは使えないらしい。
これで先程のAmazon S3>バケット>localstable(任意)>mumumu.png(任意)の中にあるオブジェクトURLが見れるようになったはずだ。
LambdaでのURLの記載方法
TextSendMessage(text='ht★tps://localstable.s3.ap-northeast-1.amazonaws.com/mumumu.png')
何に送るかで記載方法は変わってくるが、オブジェクトURLは丸ッとコピペして使えばいい。
ちなみに、パケットの中にURLが色々あって全てを表示したい場合などがあると思う。
その場合は下記のような記述でいいと思う。
まずファイル名(オブジェクト名)を取得する。
import boto3
s3 = boto3.client('s3')
def lambda_handler(event, context):
response = s3.list_objects_v2(Bucket="バケット名を書く)")
for object in response['Contents']:
print(object['Key'])
Contents,Keyは変更しないでバケット名だけ自分のものを使用
momomo.png
00009-190568967.png
00010-912531737.png
00014-912531741.png
00015-3060597289.png
00016-3060597290.png
こんな感じで返ってきているのでfor分の中をこんな感じ
for object in response['Contents']:
print('ht★tps://localstable(任意).s3.ap-northeast-1.amazonaws.com/'+object['Key'])
で指定すればすべての値を受け取ることが可能
なお必要に応じてパケット名を取得する場合もあると思うので書いておく。参考にしてもらえればと思う
import boto3
s3 = boto3.client('s3')
def lambda_handler(event, context):
response = s3.list_buckets()
for bucket in response['Buckets']:
print(bucket['Name'])
ファイルの内容を取得したい場合は
import boto3
s3 = boto3.client('s3')
body = s3.get_object(Bucket="バケット名を書く",Key="Objectの階層を書く")['Body'].read()
# バケット名がfruitsでバケットの直下にapple.jsonを置いている場合
# body = s3.get_object(Bucket="fruits",Key="apple.json")['Body'].read()
print(body.decode('utf-8'))
以上。
AWSのLambdaを使っていて思うのがLambda式で書こうものなら、説明が本当にややこしくなるな、なんてことをWeb開発未熟者の筆者は思うばかりである。