Google Lighthouseのスコアを定期的にSlackに自動通知する仕組みを作ってみた

Googleが提供している「Lighthouse」というツールの事をご存知だろうか。
端的に言うと、対象となるWebサイトのパフォーマンスを測定しますよ系ツールである。
![lighthouse.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429583/e0fd7157-736a-cb19-56ea-470ef5d52bb1.png)

Chromeの拡張機能として利用されている方も多いだろうが、毎回手動で調べるのが面倒だったので、定期的にSlackに通知するような仕組みを構築した。

■Slack通知内容(複数のWebページのLighthouseスコアの通知が可能)
![lighthouseのslack通知.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429583/62dba23b-1b53-daa7-6833-388cbeb1aaca.png)

## 概要
1. GoogleスプレッドシートにLighthouseでパフォーマンス測定するサイトURLを記載
2. Lighthouseのスコアを取得
3. Slackに通知
4. 定期的に自動通知されるよう設定 (Heroku schedulerを活用)

今回、以下の記事を参考に作ってみたが、第二部の参考記事だと、定期的に自動でSlack通知する際の書き方には合わなかったので別の方法を採用し、定期的に自動通知されるような設定情報は言及されてなかったので、この2点の情報に重点をおいて、以下メモを残しておく。

■参考記事はこちら(３部作になってます)： 
◯第一部：https://qiita.com/wtotw/items/cd24037b8ba5649c323e
　→ GoogleスプレッドシートにLighthouseでパフォーマンス測定するサイトURLを記載する話
◯第二部：https://qiita.com/wtotw/items/651680f47fe6c81ae797
　→ Lighthouseのスコアを取得する話（※ここは別の方法を採用したので以下で説明）
◯第三部：https://qiita.com/wtotw/items/425bcc3833aceea9a4b8
　→ Slackに通知する話

■完成版のソースはこちら： 
 https://github.com/dmiyamoto/lighthouse-slack-notice

#### 完成版ソースの使い方
　1.完成版ソースをzip形式でダウンロードして展開するか、git cloneする。
　2.完成版ソースのディレクトリ上で、ターミナルから、`npm install`と打ち実行する。
　　(※事前に、Node.jsをインストールされてない方はNode.jsのインストール必須)
　3.GoogleスプレッドシートにLighthouseでパフォーマンス測定するサイトURLを記載する。
　　参考記事：https://qiita.com/wtotw/items/cd24037b8ba5649c323e
　　（注意点１：スプレッドシート１行目から対象サイト名(1列目)とURL(2列目)を記載する事）
　　（注意点2：スプレッドシートのシート名は`シート1`のままにする事）
　　（注意点3：Google IAMで作成した秘密鍵は後ほど使うので厳重に保管する）
　4.Slackに自動通知がいくよう、Slack側の設定を実施してください。
　　参考記事：https://qiita.com/wtotw/items/425bcc3833aceea9a4b8
　5.Herokuに専用のアプリを作成してください。
　　参考記事： https://qiita.com/Arashi/items/b2f2e01259238235e187
　　　→参考記事の内、アプリ作成、gitリポジトリ初期化、デプロイは、この段階ではやらない。
　　　　heroku toolbeltインストール、アカウント認証、Heroku上へのアプリ作成は必要。
　6.完成版ソースのディレクトリ上に戻り、ターミナルから、以下コマンドを順番に実行する。
　　・`heroku addons:add scheduler:standard`
　　・`heroku buildpacks:set https://github.com/heroku/heroku-buildpack-nodejs#v83`
　　・`heroku buildpacks:add --index 2 https://github.com/heroku/heroku-buildpack-google-chrome.git`
　　上記コマンドでエラーが出た場合は、heroku上の対象アプリをコマンド内に指定してあげる必要がある。
　　それぞれのコマンドの後ろにスペースを１つ空け、`-a heroku上のアプリ名`を付加してから実行する。
　7.Heroku上の対象アプリのメニュー画面に行き環境変数を設定する。
　　ここでは、Google IAMで作成した秘密鍵の内容、GoogleスプレッドシートのID、Slack通知用URLと通知先チャンネル情報を設定します。
　　＜Herokuの環境変数入力場所＞
　　　`対象アプリ > Settings > Config Vars (Reveal Varsをクリック)`
　　　![heroku環境変数設定場所.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429583/9061c5d6-dfba-bd2b-bff2-935c7e30341b.png)
　　＜Heroku環境変数入力内容 （左側に下記文言を設定して、右側に設定する値を入力）＞
　　　◯Google IAMで作成した秘密鍵の各オブジェクトと対応する値を設定
　　　　TYPE
　　　　PROJECT_ID
　　　　PRIVATE_KEY_ID
　　　　PRIVATE_KEY
　　　　CLIENT_EMAIL
　　　　CLIENT_ID
　　　　AUTH_URI
　　　　TOKEN_URI
　　　　AUTH_PROVIDER_X509_CERT_URL
　　　　CLIENT_X509_CERT_URL
　　　◯GoogleスプレッドシートのIDを設定
　　　　GOOGLESPREADSHEET_ID
　　　　　※IDはこちらの箇所
![スプレッドシートID.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429583/2117c3a1-5f70-c337-a59b-0774065e91a4.png)
　　　◯Slack上でLighthouseスコアを自動投稿して欲しいチャンネル(先頭の＃は除く)を設定
　　　　SLACK_CHANNEL
　　　◯Slack Incoming Webhook URLを設定
　　　　SLACK_PATH
　8.Herokuに完成版ソースをデプロイする。
　9.Heroku schedularにて、定期的に通知したい期間を設定する。
　　＜Heroku schedulerの場所＞
　　　`対象アプリ > Resources > Heroku Scheduler`
![Heroku schedular.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429583/281b2650-8845-36c4-e7a2-15aacfa7040b.png)
　　＜Heroku schedulerの実行コマンド＞
　　　`node bin/script.js`
![Heroku schedulerの実行コマンド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429583/d47395ac-76f0-863f-47bf-d02fd678799e.png)

## メモ：Lighthouseのスコア取得ソースについて

参考記事の第二部では、CLI形式でのLighthouseスコア取得ソースについて言及していたが、Heroku schedulerを使って定期実行するため、GoogleChromeのヘッドレスモードを使い、コマンドラインやNode.jsからChromeを操作できるようにソースを変更する必要があったので以下の通りソースを変更。

■Google Chromeのヘッドレスモードについて
https://developers.google.com/web/updates/2017/04/headless-chrome
■Lighthouseをプログラムで実行する際の書き方
https://github.com/GoogleChrome/lighthouse/blob/master/docs/readme.md
→ こちらを見ると、Lighthouseのソースを介して、csvやスクリーンショットも使えそう


~~~javascript:Lighthouseのスコア取得ソース
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');

launchChromeAndRunLighthouse = (url, opts, config = null) => {
  return chromeLauncher.launch({ chromeFlags: opts.chromeFlags }).then(chrome => {
    opts.port = chrome.port;
    return lighthouse(url, opts, config).then(results => {
      return chrome.kill().then(() => {
        return Object.entries(results.lhr.categories).reduce(
          (acc, [key, a]) => {
            return Object.assign({}, acc, { [a.title]: a.score * 100 });
          },
          {}
        );
      });
    });
  });
}

const opts = {
  port: 0,
  autoSelectChrome: true,
  chromeFlags: ['--headless', '--disable-gpu', '--no-sandbox']
};

module.exports = url => {
  return launchChromeAndRunLighthouse(url, opts);
};
~~~

## メモ：Heroku schedulerでの定期的な実行に向けた設定
最初、Heroku buildpack無しでデプロイしたところ、エラーが発生して実行されなかった。
色々と調べた所、heroku上のプログラムからchromeを操作するためには、専用のbuildpackの導入が必要と判明。
https://github.com/jontewks/puppeteer-heroku-buildpack

今度、buildpackを導入してデプロイして、Heroku schedulerでの定期的な実行を試みたところ、`node: command not found` というエラーメッセージが表示された。。
buildpackを導入したら、nodeコマンドが使えなくなったのか原因は分からなかったが、参考記事に則り、nodeコマンドが実行できるようbuildpackを追加した。
参考記事：https://stackoverflow.com/questions/39237596/deploying-app-on-heroku-node-command-not-found

上記調整をしたところ、正常に動作するようになった。