FFFT

webプロダクト開発に関する話をつらつらと

cloud functions × puppeteer × Google Apps Scriptで超低コスト定期実行クローラを作って金曜ロードショーを毎週slackに通知させる

f:id:keyama4:20181116001657p:plain

cloud functions × puppeteer × Google Apps Scriptで定期実行されるクローラを作ってみます。
今回は毎週月曜に今週の金曜ロードショーをslackで通知させるようにしてみます。

cloud functionsはGCPで利用できるAWSのlumbdaのようなもので、サーバーやランタイム環境を管理することなく、簡単に単一目的のスタンドアロン関数を作成することができます。
実務でも使っていますが、サーバレスでのAPI提供がcloud functionsならすぐに、且つ、簡単にできるのでオススメです。

そのcloud functionsですが8月にpuppeteerのサポートが行われました。

cloud.google.com

puppeteerはheadless chromeを操作するchrome公式のnodeライブラリです。

github.com

クローリングで必要な様々な処理を提供していてシンプルな記述でheadless chromeの操作ができます。

それでは早速やっていきます。

まずはGCPにログインしてメニューからCloud Functionsを選択し、新規に作成画面に進みます。

下記のように情報を入力しましょう。

f:id:keyama4:20181115213100p:plain

名前はなんでもいいですがここでは friday-roadshow としました。
割り当てられるメモリはデフォルトだと256MBになってますが小さ過ぎてクローラが動かないので512MBにしてください。
ランタイムはNode.jsの8系を選択。

ソースは下記。

まずはpackage.jsonにpuppeteerを追加します。

次にindex.jsです。

リクエストはGETのみ受け付けるようにしています。
誰でも叩けないようにinternal keyを設定していてヘッダに同じkeyが含まれていないと403を返却するようにしています。
本当は環境変数から引っ張ってくるなり、datastoreから引っ張ってくるなりして直接定義しないほうがいいです。ご認識を。
実際のクローリング箇所は自分でいじってみてもらったほうがわかると思うのでいじってもらえればと。
基本はブラウザを起動して該当ページにアクセスし、セレクタを指定してそのセレクタの中身を取得してレスポンスとして返却してあげる、という流れです。
ソースコードはたったこれだけでOKです。

残りの設定に進みます。

f:id:keyama4:20181115214356p:plain

実行する関数は exec で。

次にその他をクリックして詳細オプションを下記のように変更します。

f:id:keyama4:20181115214458p:plain

リージョンをasiaにしてタイムアウトを上限値まで上げておきましょう。
実際は今回のようなシンプルなクローリングであれば数秒で処理は完了します。

これでAPIの準備はOK。
保存しましょう。
保存からAPIを叩けるようになるまで数分かかるのでしばらく待ちます。

APIが叩けるようになったら実際に叩いてみましょう。

f:id:keyama4:20181115214741p:plain

トリガーからURLを確認して叩きます。

こんな感じで取得できました。

f:id:keyama4:20181115215026p:plain

次にslackのbotの設定をします。
今回はincoming webhookを使います。

下記にアクセスして新規にincoming webhookを追加します。

https://slack.com/apps

f:id:keyama4:20181115232001p:plain

「Add Configuration」をクリック。

f:id:keyama4:20181115232016p:plain

次に通知先のチャネルを選択します。

f:id:keyama4:20181115232105p:plain

これでこのurlにpostリクエストを投げると対象のチャネルでbotが投稿してくれるようになりました。

f:id:keyama4:20181116122455p:plain

botはデフォルトの設定だと味気ないので画像と名前を設定しましょう。

f:id:keyama4:20181115233258p:plain

saveしてAPIを叩いてみましょう。

f:id:keyama4:20181115233434p:plain

無事通知がきました。

f:id:keyama4:20181115233454p:plain

これでbotの設定はOK。

最後にGoogle Apps Scriptの設定です。

Google Apps Scriptが先ほど作った金曜ロードショーのデータを取得するAPIをコールし、返却された結果を使ってbotapiを叩きます。

google driveを開いて、右クリックからその他を選択し、Google Apps Scriptを選択。選択肢になければ「アプリを追加」から追加してください。

f:id:keyama4:20181115234406p:plainf:id:keyama4:20181115234413p:plain

ソースは下記です。

実行しようとすると外部サービスへの接続を作成したアプリケーションに許可するかどうかのポップアップが表示されるので許可します。

下記のように通知がきたらOKです。

f:id:keyama4:20181116000304p:plain

最後に毎週月曜にこのスクリプトが実行されるように設定しましょう。

f:id:keyama4:20181116000629p:plain

編集から現在のプロジェクトのトリガーを選択。

新規にトリガーを作成しましょう。

下記のように設定します。

f:id:keyama4:20181116000714p:plain
f:id:keyama4:20181116000737p:plain

これで毎週月曜に金曜ロードショーが通知されるようになりました。

このようにcloud functions × puppeteer × Google Apps Scriptを組み合わせると非常に簡単に定期実行するクローラを作成できます。
今回のようにslackや、他にはlineのapiと組み合わせたりしてもいろいろ便利なものができそうです。
また、cloud functionsでクローリングするAPIを作成することでクローリングのために常時起動させるサーバを用意しておく必要がなく、コストを大幅に削減できます。

ぜひ使ってみてください。