2020-09-29 23:51

Webページのスクリーンショットを撮るアプリを作った

Webページのスクショ撮影をWeb UIでやりたいなと思って作ってみた。

https://github.com/okonomi/web-screenshot

構成としてはRailsがWeb UIでLambdaがスクショ撮影&保存。
LambdaでPuppeteerを動かしてheadless chromeで撮影したスクショをS3に保存する。
RailsアプリからLambdaの起動とS3の画像参照をやってる。

出来上がってみればそんなに難しいことはやってないけど、結局3日くらいかかった。

LambdaでPuppeteer動かすのにはじめ@serverless-chrome/lambdaを使おうとしてて、ローカルでは動作するのにLambdaにデプロイしたら動かなくてハマった。chrome-aws-lambdaを使ったらすんなり動いた。

Rails側でscreenshotsテーブル作るの無駄かなと思ってフォームオブジェクトにして一覧表示はS3バケットのオブジェクト一覧取得でと思ったけど、付加情報の保存とか拡張性とか考えて普通にテーブル作る形に戻した。

あとはpuppeteer-ruby使えばRailsだけで完結してLambdaいらないのではと思ってやってみたらDockerコンテナ化したときに動かなくて諦めた。イメージサイズも400MB以上増えたのでよくなかった。
でもpuppeteer-rubyは面白いプロダクトなので見守っていきたい。

serverless-plugin-typescriptserverless-layersを試せたのはよかった。
いままでテンプレートで生成されたままserverless-webpackを使ってたけど、TypeScriptオンリーならWebpackいらないよなーと思って切り替えた。余計なスタックがひとつ減ってすっきりした。
serverless-layersはChromeの実行ファイルがでかいのでデプロイごとにアップロードしなくて済むように入れた。node_modulesが別途デプロイされるようになって、package.jsonに更新がなければデプロイをスキップするのでデプロイサイクルが速くなってよかった。

S3の署名付きURLを初めて使った。オブジェクトを公開せずに一時的にアクセスできるURLを発行できる。いったんRailsでリクエスト受けてS3オブジェクト参照、とかしなくていい。便利なので今後も使いそう。

Lambdaを直接起動するのも初めてやった。API Gatewayを前に立てたりS3のCreateObjectイベントで起動しかやったことなかった。余計なものが挟まらないので問題があったときの切り分けが楽。
でもRailsとLambdaが密結合になるのでそこは注意したほうがいいかもしれない。S3のオブジェクト参照もそう。

総じて無駄な試行錯誤が多くて時間がかかってた。スッと方針決めてサッと作れるようになりたい。

このあとは、スクショ撮影時の画面サイズを選べるようにしたり、Lambdaの実行結果をRails側に通知したりするのをやってみたい。

そういえば今回Serverless Frameworkのプロジェクトを新規作成したら設定ファイルがserverless.ymlじゃなくserverless.tsになっててびっくりした。
v1.72.0で入ったらしい。

https://github.com/serverless/serverless/releases/tag/v1.72.0