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

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

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

ベースにする記事

https://www.1ft-seabass.jp/memo/2023/04/07/getting-shiba-inu-api-with-lambda-node-v16-index-js/

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

S3 をつくる

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

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

ACL は無効で。

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

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

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

Lambda のロール ARN をメモ

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

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

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

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

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

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

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

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

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

ポリシーの書き込み

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

  • <さきほどコピーした 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
    }),
  };
};

テスト

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

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

保存された画像確認

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

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

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

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