柴犬 API からデータを取得して S3 に保存する Lambda(Node.js v16.x + index.js) をつくるメモ

柴犬 API からデータを取得して S3 に保存する Lambda(Node.js v16.x + index.js) をつくるメモです。

ベースにする記事

柴犬 API からデータを取得して画像 URL から画像を取得する Lambda (Node.js v16.x + index.js)をつくるメモ

こちらの記事をベースに Lambda (Node.js v16.x + index.js)で、柴犬 API からデータを取得できてるので、あとは S3 に保存します。

S3 をつくる

image

バケットを作成で作成をします。

  • 一般的な設定
    • バケット名
      • 今回は blog-sample-shiba-inu-api-s3 にしました。つくるかたは任意で。
    • AWS リージョン
      • 任意のリージョンですが、私の場合 Lambda と合わせて東京にしました

image

ACL は無効で。

image

パブリックアクセスはすべてブロックです。うまくつくれたら、用途に応じて開放しましょう。

残りの設定はデフォルトのままです。バケットを作成ボタンをクリックします。

image

作成できたら、一覧から今回のバケットをクリックして詳細画面に移動します。

Lambda のロール ARN をメモ

image

こちらで作った Lambda の詳細画面に行きます。

image

設定 > アクセス権限 > 実行ロール のところのロール名の横の、別ウィンドウで開くボタンをクリックします。

image

IAM のロールのページにアクセスするので、ARN 名をコピーします。これを使って S3 側でアクセス開放します。

今回の S3 バケットのアクセス許可設定にアクセス

image

今回の S3 バケットの詳細画面から、アクセス許可設定にアクセスします。

バケットポリシーの編集にアクセス

image

バケットポリシーの編集ボタンをクリックします。

今回の S3 バケットの ARN をメモ

image

編集画面でバケット ARN があるのでメモします。これが今回の S3 バケット ARN です。

ポリシーの書き込み

image

このようにポリシーのところに以下を書き込みます。

  • <さきほどコピーした Lambda のロール ARN>
    • さきほどコピーした Lambda のロール ARNに書き換えましょう。
  • <今回の S3 バケット ARN>
    • 今回の S3 バケット ARNに書き換えましょう。
    • 末尾の /* は残しましょう。
{
     "Version": "2012-10-17",
     "Id": "AccessAllowPolicy",
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "AWS": "<さきほどコピーした Lambda のロール ARN>"
         },
         "Action": "s3:*",
         "Resource": "<今回の S3 バケット ARN>/*"
       }
     ]
}

変更出来たら、変更の保存ボタンをクリックします。

Lambda の変更

Lambda のプログラムを以下のように変更します。全文書き換えです。

const AWS = require('aws-sdk');
const axios = require('axios');

// S3 ライブラリの呼び出し
const S3 = new AWS.S3();

exports.handler = async (event) => {
  // 柴犬 API へのアクセス
  const configShibaAPI = {
    url:'https://shibe.online/api/shibes',
    method:'get'
  }
  //// 柴犬 API にアクセス ////
  const responseShibaAPI = await axios.request(configShibaAPI);
  
  // 画像の URL リストの 0 番目から実際の URL を取得
  const urlSAhibaImage = responseShibaAPI.data[0];
  
  console.log('Shiba API Access OK!');
  console.log(urlSAhibaImage);
  
  //// 画像を取得 ////
  const configGetImage = {
    url:urlSAhibaImage,
    responseType:'arraybuffer'
  }
  const responseGetImage = await axios.request(configGetImage);
  
  const data = responseGetImage.data;
  
  console.log('Shiba API GetImage OK!');
  
  let statusCodeS3 = 500;
  let successResultS3 = false;
  
  //// S3 への保存 ////
  
  const currentS3BucketName = 'blog-sample-shiba-inu-api-s3';
  
  // 今回は固定のファイルパス(つど上書き)
  const currentS3FilePath = "shiba_inu_image/latest_saved.jpg"

  var result = await S3.putObject({
    Body: data,
    Bucket: currentS3BucketName,
    ContentType: 'image/jpg',
    Key: currentS3FilePath,
  }).promise()
    .then((_res) => {
      statusCodeS3 = 200;
      successResultS3 = true;
      return _res;
    }).catch((error) => {
      console.error("Error!", error);
      return error;
    });
  
  // 結果
  return {
    statusCode: statusCodeS3,
    body: JSON.stringify({
      result: result
    }),
  };
};

テスト

image

Lambda でテストをしてみます。

image

このような形で無事動いたようです!

保存された画像確認

image

S3 に戻って、今回のバケットを確認します。 shiba_inu_image フォルダができているのでクリックします。

image

latest_saved.jpg をクリックします。

image

開くボタンをクリックします。これであれば AccessDenied なく確認できます。(下部にあるオブジェクト URL だと、いまの設定だと AccessDenied になります。)

image

無事、柴犬の保存が確認できました!もちろん Lambda をまた動かすと、ランダムなので、別の柴犬が保存されます。S3 でファイルを開きっぱなしで見ようとしてもキャッシュがあるかもしれないので、一度 S3 の一覧に戻って、再度ファイルまで掘り下げていってから開くボタンをクリックするとキャッシュが絡みにくく更新が確認しやすかったです。