Google Cloud と Puppeteer を使った RPA で定型業務を自動化した話
こんにちは。UltraImpression の技術担当です。
UltraImpression のプラットフォーム開発チームでは、UltraImpression Ad Manager のような自社サービスだけではなく、社内のセールス運用チームをサポートするためのシステム開発も行っています。
その活動の一環として、今回は定期的に発生している高負荷な作業を自動化することにしました。その作業とは、とある Web サービス(以下、サービス A とします)にて提供されるレポート画面を、月に一度スクリーンショットで保存するというものです。
この作業は頻度こそ低めですが、月の取引によっては保存するレポートが数百件にのぼることもあります。また、サービス A 自体のレスポンスが遅く、かつ PC の CPU やメモリを大量に消費するために、担当者には時間的・精神的な負担がかかっていました。
![](https://assets.st-note.com/img/1705989114417-jadyoSHsKr.png?width=800)
取引ごとに各担当者が サービス A のレポート画面を開く。
対象の取引の情報をいくつか入力する。この数ステップの操作が重く、時間を浪費する。
表示された画面のスクリーンショットを保存する。
自動化に際しヒアリングを行ったところ、以下の制約があることがわかりました。
サービス A は社外製品なので API などを開発することは不可能
保存する対象の取引は毎月変わるため、その対象を絞り込む ID は作業開始時に手動で指定する必要がある
ID 以外の情報はデータベースから API を介して取得できる
つまり、レポートを表示するためには Web ブラウザの操作の自動化をしなければなりません。また、作業の開始時に対象の ID を指定するインターフェースが必要となります。
これらを踏まえた自動化後のワークフローがこちらです。
![1. 担当者は対象の ID をチャットボットに伝える
2. チャットボットが ID を元にその他の情報をデータベースから取得し、それらの情報を元に Web ブラウザを操作し、スクリーンショットを取得する
3. 取得したスクリーンショットをチャットボットが返信する](https://assets.st-note.com/img/1705989150996-2lK3oka4U3.png?width=800)
担当者は対象の ID をチャットボットに伝える
チャットボットが ID を元にその他の情報をデータベースから取得し、それらの情報を元に Web ブラウザを操作し、スクリーンショットを取得する
取得したスクリーンショットをチャットボットが返信する
普段の業務では Slack をチャットツールとして使っているので、チャットボットも Slack アプリとして実装することにしました。こちらは自社サービスの開発でも使い慣れた Go で実装しています。
Web ブラウザの操作には Puppeteer を採用しました。Puppeteer は Chrome DevTools Protocol を使ってヘッドレス Chrome の操作を行う Node.js のライブラリです。Chrome 以外のブラウザには正式対応していませんが、今回の作業には運用上も Chrome を利用しているため問題ありません。
また、当社ではサービスのインフラはすべて Google Cloud 上で運用しているので、今回のシステムも Google Cloud のマネージドサービスを使って構築しました。
![](https://assets.st-note.com/img/1705990649859-6NHL9VlLxm.png?width=800)
Slack アプリ: Cloud Run Services
Puppeteer による Web ブラウザ操作: Cloud Run Jobs
Web サーバーとして実装する Cloud Run Services とは違って、Cloud Run Jobs はコマンドラインツールとして実装する必要があります。その実行時の引数にユーザーが入力した ID やデータベースから取得した情報を渡せるようにしておきます。
ただし、現時点の Cloud Run Jobs では、実行したジョブの標準出力・標準エラー出力はログに出力されるのみです。通常のコマンドラインツールを実装する場合と同様に、実行結果を出力する実装にしても、ジョブの起動元はそれを受け取れないことに注意する必要があります。
$ ./capture-report -id 1337 -foo bar
https://example.com/captured-image.png // これは Slack アプリで受け取れない
幸い、今回はスクリーンショットの保存先が Google Cloud Storage であったため、保存先のファイル名まで引数指定することにしました。
$ ./capture-report -id 1337 -foo bar -dest gcs://example/captured/1337.png
$ echo $?
0
ジョブが正常終了した場合は、その保存先にスクリーンショットが存在することを前提に処理を進めることになります。
このシステムにより、従来は担当者が一件一件処理していた作業を、チャットボットにまとめて依頼できるようになりました。あとは結果を返信してくれるまで、担当者の時間も PC のリソースも浪費することはありません。旧来の作業に比べて 3 〜 4 割ほどの時間を削減できました。
ただし、行っていることはあくまで社外の Web サービスの操作であるため、サービス A のシステムに変更がないか、想定外の挙動がないかは、社内システム以上に気を遣う必要があります。
開発チームでは、それらに注視するとともに、新たに効率化できる業務はないかサポートを続けていきます。
この記事が気に入ったらサポートをしてみませんか?