見出し画像

PageSpeedInsightsとGASを使ってWebサイトの表示速度をモニタリングするBot

1. なぜ作った?

僕は社内ではWebマーケティングの担当者として日々、リスティング広告の運用と同時にサイトのSEO対策も行っています。
そこで、近年重要になっているのが、Webサイトの表示速度。
ようは、Webページの表示速度があまりに遅いと、サイトとしてGoogleからマイナス評価をもらうよという話です。

Googleがスピードアップデート(Speed Update)を導入、2018年7月からページ表示速度をランキング要因に

サイトの改修を続けていくうちに、ページの表示速度がすごいことになっていたというのはよくある話。
実は、弊社もその一つになっていました…

このようなこともあり、ある程度重要度の高いページは常にモニタリングしておきたいなと考えたのが事の発端です。

ちなみに、Webページの表示速度を知りたい方はいかにURLをいれて検索することで測定できます。

参考:PageSpeedInsights

2. 完成品

都合のいいモニタリングツールが見当たらなかったことから、入社して少したった秋頃の僕は、以下のようなものを作りました。

こちらでは、スプレッドシートに登録したURLのページ表示速度を毎日モニタリングしてくれます。
ちなみに、SP/PCどちらも可能です。
また、指定の閾値を決めて、それを下回った場合は別シートで集計し、Chatoworkで通知するようにしました。

※僕が作ったとありますが、ググればいい記事は多いので、ソースをほぼ切り貼りしています。
気になる方はいろいろと調べてみましょう

続けて、内容を確認していきましょう。

3. 表示速度を測定するリストを作成

今回準備するシートは3つあります。
・気になるURLを登録する「list」
・速度結果を蓄積する「reslut」
・通知用集計シート「check」

listシートはこんなかんじ。

まずは、listシートに登録した内容をresultシートへ転記する処理を記載しておきます。

// リスト更新
function listUpdate() {
  var lastRow = listSheet.getLastRow();
  var getList = listSheet.getRange(2,1, lastRow, 1).getValues();
  
  for (var i=2; i <= lastRow; i++) {
    var print = sheet.getRange(i*2-2,1).setValue(getList[i-2]);
  }
  //"check"部分の更新
  var lR = sheet.getRange('A:A').getLastRow();
  var copyToCheck = sheet.getRange(2,1,lR,2).copyTo(checkSheet.getRange(2,1))
}

ここでは配列として取得したURL群を別のシートに1行ごとに転記しています。
なぜ、1行ごとなのかというと、SP/PCで取得しているためです。
最初の完成品の写真を見ればわかるかと思いますが、SP/PC/SP/PCという順番で数値が書かれているため、このような転記の仕方になっています。

また、合わせてcheckシートの列もコピペで更新をしており、都度測定するサイトを更新できるようにしました。

4. APIへリクエスト

続いては、実際の表示速度を測定して、データとして残す部分です。
resultシートはこんな感じ。

スコアとサイト名は適当なので、こんな感じに蓄積されるのだなと思ってください。

ちなみに、前段階の準備としてAPIkeyが必要になるので、まだない方はこちらを見て作成しておきましょう

A列にサイト名がでているのは、さきほどの処理で完成しています。
ここからは、具体的に日付とそのスコアを記録するところです。

  var Today = new Date();
  var date_format = Utilities.formatDate(Today,"JST","yyyy/MM/dd");
  var roomId = "fugafuga";
  
  // アクティブなスプレッドシートのアクティブなシートを使用する
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("result");
  var listSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("list");
  var checkSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("check");

  var lastcolumn = sheet.getLastColumn();

function runPageSpeed() {
  
  // APIを変数に格納
  var APIkey = 'hogehoge';
  
  
  // 2行目〜内容のある最終行目に対して処理
  var lastRow = listSheet.getLastRow();
  var processTimes = listSheet.getLastRow()/10 + 1;
  

    for (var i=1; i <= listSheet.getLastRow(); i++) {
      // A列のURLを取得し空の場合はスキップ
      var url = listSheet.getRange(i+1,2).getValue();
      if (!url) { continue; }
      // デスクトップとモバイルそれぞれの際のURLを配列に入れる
      var request = 'https://www.googleapis.com/pagespeedonline/v2/runPagespeed?url=' + url + '&key=' + APIkey + '&strategy=';
      var url = [request + 'desktop', request + 'mobile'];
      // URLをAPIに投げてみてエラーが返ってくる場合はログに残す
      try {
        var response = [
          UrlFetchApp.fetch(url[0], {muteHttpExceptions: true }),
          UrlFetchApp.fetch(url[1], {muteHttpExceptions: true })
        ];
      }
      catch (err)
      {
        Logger.log(err);
        return(err);
      }
      
      // 帰ってきたjsonをパースする
      var parsedResult = [
        JSON.parse(response[0].getContentText()),
        JSON.parse(response[1].getContentText())
      ];
      
      
      // ログを残す。jsでのconsole.logみたいなもの
      Logger.log(parsedResult[0].ruleGroups.SPEED.score);
      Logger.log(parsedResult[1].ruleGroups.SPEED.score);
      if (i == 1) {
        // B列にPCのスコア、C列にSPのスコアを書き込む
        sheet.getRange(i+1,lastcolumn+1).setValue(parsedResult[0].ruleGroups.SPEED.score);
        sheet.getRange(i+2,lastcolumn+1).setValue(parsedResult[1].ruleGroups.SPEED.score);
      } else {
        sheet.getRange(i*2,lastcolumn+1).setValue(parsedResult[0].ruleGroups.SPEED.score);
        sheet.getRange(i*2+1,lastcolumn+1).setValue(parsedResult[1].ruleGroups.SPEED.score);
      }
    }
  var date = sheet.getRange(1,lastcolumn+1).setValue(date_format);
 
}

"function runPageSpeed"までの記述は、GAS特有の対象のスプレッドシートを指定する作業です。

やっている内容を簡単に説明すると、以下のとおりです。
①resultシートA列にあるURLをPageSpeedInsightsAPIへとリクエスト
②返ってきたデータからスコアのみ抽出してメモ

重要なのはtry{ }に囲まれているこれ↓。
UrlFetchApp.fetch(url[0], {muteHttpExceptions: true })
APIに対してGETリクエストを投げつけています。

そのあとは、jsonデータで受け取ったものをGAS上で処理しやすくするためにパースし、あとはひとつずつシートへメモ!

5. まとめ

あとは、当日のカラムを抽出して、スコアを下回ったらチャットへ連絡という流れになっています。

ここは、エクセルの関数と以前紹介したチャットワークへの自動通知ロジックを使えば実行可能です。
ChatWorkとスプレッドシートの連携

いかがでしたでしょうか。
さっき思い立って書いたので、かなり駆け足な記事となってしまいましたが、以外とやっていることは少なかったかと思います。

今はとにかく作るのが楽しくて仕方がない時期なので、このように作ったものは簡単に報告していきます。

最後にソース全部を載せておきますね。

  var Today = new Date();
  var date_format = Utilities.formatDate(Today,"JST","yyyy/MM/dd");
  
  // アクティブなスプレッドシートのアクティブなシートを使用する
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("result");
  var listSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("list");
  var checkSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("check");

  var lastcolumn = sheet.getLastColumn();

function runPageSpeed() {
  
  // APIを変数に格納
  var APIkey = 'hogehoge';
  
  
  // 2行目〜内容のある最終行目に対して処理
  var lastRow = listSheet.getLastRow();
  var processTimes = listSheet.getLastRow()/10 + 1;
  

    for (var i=1; i <= listSheet.getLastRow(); i++) {
      // A列のURLを取得し空の場合はスキップ
      var url = listSheet.getRange(i+1,2).getValue();
      if (!url) { continue; }
      // デスクトップとモバイルそれぞれの際のURLを配列に入れる
      var request = 'https://www.googleapis.com/pagespeedonline/v2/runPagespeed?url=' + url + '&key=' + APIkey + '&strategy=';
      var url = [request + 'desktop', request + 'mobile'];
      // URLをAPIに投げてみてエラーが返ってくる場合はログに残す
      try {
        var response = [
          UrlFetchApp.fetch(url[0], {muteHttpExceptions: true }),
          UrlFetchApp.fetch(url[1], {muteHttpExceptions: true })
        ];
      }
      catch (err)
      {
        Logger.log(err);
        return(err);
      }
      
      // 帰ってきたjsonをパースする
      var parsedResult = [
        JSON.parse(response[0].getContentText()),
        JSON.parse(response[1].getContentText())
      ];
      
      
      // ログを残す。jsでのconsole.logみたいなもの
      Logger.log(parsedResult[0].ruleGroups.SPEED.score);
      Logger.log(parsedResult[1].ruleGroups.SPEED.score);
      if (i == 1) {
        // B列にPCのスコア、C列にSPのスコアを書き込む
        sheet.getRange(i+1,lastcolumn+1).setValue(parsedResult[0].ruleGroups.SPEED.score);
        sheet.getRange(i+2,lastcolumn+1).setValue(parsedResult[1].ruleGroups.SPEED.score);
      } else {
        sheet.getRange(i*2,lastcolumn+1).setValue(parsedResult[0].ruleGroups.SPEED.score);
        sheet.getRange(i*2+1,lastcolumn+1).setValue(parsedResult[1].ruleGroups.SPEED.score);
      }
    }
  var date = sheet.getRange(1,lastcolumn+1).setValue(date_format);
 
}

//最低値を下回ったら、チャットをおくる
function chat() {
  var num = checkSheet.getRange('L2').getValue();
  var probData = checkSheet.getRange(2,6,num+1,3).getValues();
  
  var mes = "";
  
  if (num !== 0) {
  
  var size = probData.length;
  for (var i = 0; i < size; i++) {
    for (var x = 0; x < 3; x++) {
      mes = mes + probData[i][x] + " ";
    }
    
    mes = mes + String.fromCharCode(10);
  }
  
    Logger.log(mes);

  
  var client = ChatWorkClient.factory({token: 'hoge'}); //チャットワークAPI
  client.sendMessage({
    room_id:fugafuga, //ルームID
    body:'スコアのお知らせです。'+ String.fromCharCode(10) + mes});
    
  }
}  

// リスト更新
function listUpdate() {
  var lastRow = listSheet.getLastRow();
  var getList = listSheet.getRange(2,1, lastRow, 1).getValues();
  
  for (var i=2; i <= lastRow; i++) {
    var print = sheet.getRange(i*2-2,1).setValue(getList[i-2]);
  }
  //"check"部分の更新
  var lR = sheet.getRange('A:A').getLastRow();
  var copyToCheck = sheet.getRange(2,1,lR,2).copyTo(checkSheet.getRange(2,1))
}


この記事が気に入ったらサポートをしてみませんか?