Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8835

Puppteerでキャプチャ画像を取得 part2

$
0
0

概要

エンジニアもどき2年目に入りました。色々あって以下を行うLambda関数を作成することになりました。
色々学びがあったので備忘録がわり兼アウトプットのために書くことにしました。

  1. 特定のページのキャプチャ取得
  2. 取得したキャプチャをS3に保存
  3. S3に保存したURLをDyanmoに記録

part2では2. 取得したキャプチャをS3に保存の実装とデプロイまで行います。
part2での実装内容はこちら

前提

前回(part1)の続きです。part1に引き続き以下の準備は完了している前提です。
前回(part1)の実装内容はこちら

  • nodejs
  • ServerlessFramework
  • yarn
  • webpack
  • iamのユーザ作成済み

実装作業

1. 準備

ローカルでの動作確認のためにローカルにS3のバケットを作成できるserverless-s3-localを使用します。

# 追加
yarn add -D serverless-s3-local

続いてserveress.ymlにS3の設定を追加します。

serverless.yml
service:puppeteer-captureprovider:# ・・・ 省略 ・・・# テーブル名やバケット名など環境変数environment:# ・・・ 省略 ・・・# 追加1 : バケット名CAPTURE_BUCKET:${self:provider.environment.PREFIX}-capture-bucketiamRoleStatements:# 追加2 : S3の設定-Effect:AllowAction:-'s3:PutObject'-'s3:PutObjectAcl'Resource:'arn:aws:s3:::${self:provider.environment.S3_BUCKET}*'# 追加3 : ローカルでの動作用設定custom:defaultStage:devs3:port:8081directory:.s3cors:false# 追加3 : プラグインplugins:-serverless-webpack-serverless-s3-local# ・・・ 省略 ・・・# 追加4 : リソースの設定resources:Resources:CaptureBucket:Type:AWS::S3::BucketProperties:BucketName:${self:provider.environment.CAPTURE_BUCKET}

ローカルで起動できるか確認します。

sls s3 start -c ./serverless.yml

以下のように起動していれば完了です。
image.png

ローカルにS3のバケットが作成されています。
image.png

また、AWSのリソース(S3やDynamoDB)を操作する必要があるので、aws-sdkを使用します。

# 追加
yarn add -D aws-sdk

Lambdaの実行環境には AWS SDK for JavaScriptが含まれているためdevDependenciesにのみ追加しています。
webpack.config.jsの外部依存にaws-sdkを追加して準備は完了です。

webpack.config.js
// ・・・ 省略 ・・・target:'node',// 追加externals:['chrome-aws-lambda','aws-sdk'],// ・・・ 省略 ・・・};

2. 実装

前回は取得したキャプチャ画像をローカルに書き出して保存していましたが、Lambdaは実行後、使用されたすべてのリソース(が破棄されてしまうので、S3に保存するように修正します。

handler.js
// ・・・ 省略 ・・・// 追加1 : S3のインポートimport{config,S3}from'aws-sdk';// 追加2 : S3の設定とオプション(LOCALで実行した際の設定)config.update({region:process.env.AWS_REGION});consts3Options=process.env.LOCAL?{s3ForcePathStyle:true,accessKeyId:'S3RVER',secretAccessKey:'S3RVER',endpoint:newAWS.Endpoint('http://localhost:8081'),}:{};// 追加3 : s3のクライアント/バケット名/アップロード関数consts3=newS3(options);constbucket=process.env.CAPTURE_BUCKET;constputObject=({key,body,contentType,acl})=>{constparams={Bucket:bucket,Key:key,Body:body,ContentType:contentType,ACL:acl,};console.log(params);returns3.putObject(params).promise();};constgetCapture=async(url)=>{// ・・・ 省略 ・・・};exportconstcaptureFunction=asyncevent=>{// ・・・ 省略 ・・・// 修正 : ファイルに書き出しからS3へアップロードするように変更// Before : ファイル書き出し// writeFileSync('/tmp/hoge.jpg', jpgBuf);// After : S3へアップロードtry{awaitputObject({key:'hoge.txt',body:jpgBuf,contentType:'image/jpeg',acl:'public-read',});}catch(error){console.log(error);return{statusCode:500,body:error.message};}return{statusCode:200,body:'キャプチャの取得に成功しました。'};};

注意する点はacl、つまりアクセスコントロールリストにpublic-readの設定を忘れるとS3にアップロードはできるもののAccess Deniedとなりリソースにアクセスができなくなってしまいます。

3. 動作の確認

まずはローカル環境での動作の確認です。

LOCAL=true sls invoke local--function captureFunction -c ./serverless.yml
LOCAL=true sls invoke local--function captureFunction --data'{"url":"https://qiita.com/"}'-c ./serverless.yml

実行して 200でレスポンスが帰ってくること、ローカルのバケットにキャプチャ画像が保存されていることを確認します。

image.png

バケットに保存されているhode.jpg._S3rver_objecthoge.jpgにリネームして開くと確認することができます。

image.png

4. デプロイと動作確認

デプロイします。

serverless deploy

実行し200でレスポンスが返ってくることを確認します。
また、AWSのコンソールからS3にアクセスしてバケットの中を確認します。

sls invoke --function captureFunction -c ./serverless.yml
sls invoke --function captureFunction --data'{"url":"https://qiita.com/"}'-c ./serverless.yml

image.png

以上でpart2の作業は完了です。
次はS3に保存した画像のURLをDynamoDBに書き出す処理までの実装を行います。

おわりに

  • ACLのところで結構引っかかった(Bucketに保存できるもののアクセスできない)
  • ローカルでのS3の使い方、ServerlessFrameworkでS3のバケットの作成など色々勉強になった
  • 今回は日本語のページのキャプチャは必要なかったので対応していませんが、Lambdaのインスタンスに日本語フォントが含まれておらず、日本語を含むページのキャプチャした際に文字化けが発生します。(フォントを用意して設定する必要がある)

参考


Viewing all articles
Browse latest Browse all 8835

Trending Articles