GASでPageSpeed Insights APIを使い定期的にSpeedIndexを測定

#はじめに

今回は、GASとPageSpeed Insights APIを使いスプレッドシートに定期的にSpeedIndexを測定する方法について書きたいと思います。

ステップ
1.　PageSpeed Insights APIのキーを取得
2.　APIを使用し、GASで速度計測プログラムの作成
3.　スプレッドシートを取得
4.　2で作成したプログラムを使用し、SpeedIndexを測定する
5.　定期実行トリガーを設定

#PageSpeed Insightsとは
PageSpeed InsightsはGoogleが提供している、WEBページのページの読み込み速度(SpeedIndex)やSEO改善の提案を提示してくれるツールです。

#ステップ1.APIキーの取得
https://developers.google.com/speed/docs/insights/v4/first-app

1.上記にアクセスし、Get a Keyボタンを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270493/01ac1873-af20-3246-0f11-dae30c7b1cd0.png )

2.プロジェクトの作成
初めての場合はCreate a new projectを押下して、プロジェクト名を付けてください。
すでにプロジェクトがある場合は、そのプロジェクトを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270493/1a048e85-3767-2a22-b674-d6bb2443458a.png)

3.APIキーの取得
2の手順でNEXTを押下するとAPIキーが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270493/0acbe297-fd9e-5919-eea5-3d87dbfc0ebe.png)

#ステップ2.速度計測プログラムの作成
APIキーが取得できたので早速、プログラムを作成していきます。

```javascript
function getSpeedIndex(url,terminal) {
  const api = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed';
  const parameters = {
    url: encodeURIComponent(url),
    strategy: encodeURIComponent(terminal),
    key: encodeURIComponent('取得したAPIキー')
  };
  let build = `${api}?`;
  for (key in parameters) {
    build += `${key}=${parameters[key]}?`;
  }
  
  try{
    var jsonData = UrlFetchApp.fetch(bildurl).getContentText();
    var json = JSON.parse(jsonData);
    const lighthouse = json.lighthouseResult;
    
    return lighthouse.audits['speed-index'].displayValue;
  }catch(exception_var){
    console.log(exception_var);
    return "計測エラー";
  }
}
```
第一引数は計測したいURLを指定し、
第二引数には、端末を指定します（Desktop or Mobile）
6行目のkeyには先ほど作成したAPIキーを指定してください

#ステップ3.スプレッドシートを取得

まず初めにGASからスプレッドシートの情報を取得するためのプログラムを書いていきます。

```javascript
var id= "スプレッドシートのIDを指定"
var File = SpreadsheetApp.openById(id);
var sheet = File.getSheetByName("シート名"); 
```

下記画像、URLのhogehogeがスプレッドシートのIDとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270493/aa368571-007d-94c1-c730-87bf0f52a7dc.png)

例：スプレッドシートの書き方
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270493/c8cef62c-0fd7-ec03-a94d-4fa30348bb72.png)


#ステップ4.スプレッドシートの情報をもとにAPIを実行
スプレッドシートに書いたURL・端末を取得し、APIを実行してSpeedIndexを測定していきたいと思います。

```javascript
  //配列
  let arr = [];
  let speed_index = "";

  //Mobile計測
  speed_index = getSpeedIndex(sheet.getRange("A2").getValue(),sheet.getRange("B2").getValue());
  if(speed_index == "計測エラー"){
    while(speed_index == "計測エラー"){
      Utilities.sleep(110 * 1000);
      speed_index = getSpeedIndex(sheet.getRange("A2").getValue(),sheet.getRange("B2").getValue());
    }
  }
  Array.prototype.push.apply(arr, [Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm:ss'), speed_index]);
  Utilities.sleep(110 * 1000);
  console.log(arr);

  //PC計測
  speed_index = getSpeedIndex(sheet.getRange("C2").getValue(),sheet.getRange("D2").getValue());
  if(speed_index == "計測エラー"){
    while(speed_index == "計測エラー"){
      Utilities.sleep(110 * 1000);
      speed_index = getSpeedIndex(sheet.getRange("C2").getValue(),sheet.getRange("D2").getValue());
    }
  }
  Array.prototype.push.apply(arr, [Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm:ss'), speed_index]);
  Utilities.sleep(110 * 1000);
  console.log(arr);
  
  sheet.appendRow(arr);
```

上記プログラムの簡単な流れを説明します。
1.　APIを実行
2.　1で計測が出来なかった場合、110秒待ち再度APIを実行。これを取得できるまで繰り返す
3.　取得したデータを配列に格納
4.　最後に配列をスプレッドシードの最後の行に追加

待ち時間を110秒にしている理由は一定時間あたりのAPIリクエスト数が超過した際にエラーが出てしまうのを防ぐためとなります。

#ステップ5.定期実行トリガーの作成

```javascript
function setTrigger() {
 var setTime = new Date();
  setTime.setDate(setTime.getDate() + 1)
  setTime.setHours(時を設定);
  setTime.setMinutes(分を設定); 
  ScriptApp.newTrigger('定期実行したいファンクション名').timeBased().at(setTime).create();  
}
```
setTime.setDateに実行したい日にちを指定（今回は+1日し、次の日実行するようにする）
setTime.setHoursに実行したい時間を指定（20時に実行したい場合は20を指定）
setTime.setMinutesに実行したい分を指定（0分に実行したい場合は00を指定）

#今回作成したプログラムの全容
```javascript
var id= "スプレッドシートのIDを指定"
var File = SpreadsheetApp.openById(id);
var sheet = File.getSheetByName("シート名"); 

function getSpeedIndex(url,terminal) {
  const api = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed';
  const parameters = {
    url: encodeURIComponent(url),
    strategy: encodeURIComponent(terminal),
    key: encodeURIComponent('取得したAPIキー')
  };
  let build = `${api}?`;
  for (key in parameters) {
    build += `${key}=${parameters[key]}?`;
  }
  
  try{
    var jsonData = UrlFetchApp.fetch(bildurl).getContentText();
    var json = JSON.parse(jsonData);
    const lighthouse = json.lighthouseResult;
    
    return lighthouse.audits['speed-index'].displayValue;
  }catch(exception_var){
    console.log(exception_var);
    return "計測エラー";
  }
}

function main(){
  //配列
  let arr = [];
  let speed_index = "";

  //Mobile計測
  speed_index = getSpeedIndex(sheet.getRange("A2").getValue(),sheet.getRange("B2").getValue());
  if(speed_index == "計測エラー"){
    while(speed_index == "計測エラー"){
      Utilities.sleep(110 * 1000);
      speed_index = getSpeedIndex(sheet.getRange("A2").getValue(),sheet.getRange("B2").getValue());
    }
  }
  Array.prototype.push.apply(arr, [Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm:ss'), speed_index]);
  Utilities.sleep(110 * 1000);
  console.log(arr);

  //PC計測
  speed_index = getSpeedIndex(sheet.getRange("C2").getValue(),sheet.getRange("D2").getValue());
  if(speed_index == "計測エラー"){
    while(speed_index == "計測エラー"){
      Utilities.sleep(110 * 1000);
      speed_index = getSpeedIndex(sheet.getRange("C2").getValue(),sheet.getRange("D2").getValue());
    }
  }
  Array.prototype.push.apply(arr, [Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm:ss'), speed_index]);
  Utilities.sleep(110 * 1000);
  console.log(arr);
  
  sheet.appendRow(arr);
}

//トリガーの設定
function setTrigger() {
 var setTime = new Date();
  setTime.setDate(setTime.getDate() + 1)
  setTime.setHours(20);
  setTime.setMinutes(00); 
  ScriptApp.newTrigger('main').timeBased().at(setTime).create();  
}
```

#最後に
今回はSpeedIndexにフォーカスをして記事を書きましたが、
PageSpeed Insights APIはSpeedIndex以外のWEBスコアも計測できるので、とても便利です。

間違っている情報などあればコメントで教えていただければ幸いです。