GitHub の Traffic Data を 継続的にトラッキングする

この記事は[「freeeデータに関わる人たち Advent Calendar 2020」](https://adventar.org/calendars/5461) の、17日目の記事です。

GitHub 上でレポジトリを公開していると、日毎に「clone数」「PV数」などのTraffic データを取得することができます。

(GitHub のレポジトリメニューから [Insights] → [Traffic] と移動)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83767/57deaedf-74e3-da23-4beb-27e6089cc2d6.png" width="480">

GitHubのトラッキングデータは直近2週間に限定されており「一年間を通じたTraffic」など、長期のデータを確認することはできません。

今回は、GitHubのAPIを経由して、定期的にレポジトリの Trafficデータ を取得し、継続的なデータトラッキングを行っている設定をメモがてら記述します。

(今回の記事では、個人所有のレポジトリを利用しました。)

## やること

- GitHub のREST API経由で、レポジトリの Traffic Dataを取得。
- Google Apps Script で、スプレッドシートに日別のPV数を記録する。
- 毎週データを取得、継続的にデータを記録していく。

## 手順

- GitHub のPersonal Access Token を取得、権限設定する
- Traffic Data を Google Apps Script で抽出
- 定期的に実行するための設定を行う


## GitHub のAPIキーを取得、権限設定する

APIを利用するための Personal Access Token を取得します。取得の方法は以下のドキュメントが詳しいです。

- [英語ドキュメント](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token)
- [日本語ドキュメント](https://docs.github.com/ja/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token)

GitHubの右上、アカウントアイコンから [Settings] → [Developer settings] → [Personal access token]を選択。

[generate new token]をクリックして、新しいトークンを発行します。トークンがアクセスできるスコープを設定。今回取得するのは、公開レポジトリのTrafficデータなので[public_repo] だけにチェックを入れます。

APIをコールする時には、必要以上の権限を付与しないように注意。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83767/2c15af23-4d91-de50-6358-b9c3e9da6d58.png" width="480">


トークンが発行されます。トークンの文字列は、発行された瞬間しか表示されません。万が一控え忘れると、再発行が必要となるので要注意。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83767/c630002b-d4bc-0941-762e-971c87f84bbe.jpeg" width="480">

トークンが取得できたら、curl でテストコールしてみましょう。

```bash

curl \
  -H "Accept: application/vnd.github.v3+json" \
  -H "Authorization: token ${取得したトークン文字列}" \
  https://api.github.com/repos/${GitHubのアカウント名}/${レポジトリ名}/traffic/views
```

PV数がJSONで返ってきたら、設定は成功しています。JSONはこんな感じ。


```json
{
  "count": 14850,
  "uniques": 3782,
  "views": [
    {
      "timestamp": "2016-10-10T00:00:00Z",
      "count": 440,
      "uniques": 143
    },
    {
      "timestamp": "2016-10-11T00:00:00Z",
      "count": 1308,
      "uniques": 414
    },
    {
      "timestamp": "2016-10-12T00:00:00Z",
      "count": 1486,
      "uniques": 452
    },
    {
      "timestamp": "2016-10-13T00:00:00Z",
      "count": 1170,
      "uniques": 401
    },
    {
      "timestamp": "2016-10-14T00:00:00Z",
      "count": 868,
      "uniques": 266
    },
    {
      "timestamp": "2016-10-15T00:00:00Z",
      "count": 495,
      "uniques": 157
    },
    {
      "timestamp": "2016-10-16T00:00:00Z",
      "count": 524,
      "uniques": 175
    },
    {
      "timestamp": "2016-10-17T00:00:00Z",
      "count": 1263,
      "uniques": 412
    },
    {
      "timestamp": "2016-10-18T00:00:00Z",
      "count": 1402,
      "uniques": 417
    },
    {
      "timestamp": "2016-10-19T00:00:00Z",
      "count": 1394,
      "uniques": 424
    },
    {
      "timestamp": "2016-10-20T00:00:00Z",
      "count": 1492,
      "uniques": 448
    },
    {
      "timestamp": "2016-10-21T00:00:00Z",
      "count": 1153,
      "uniques": 332
    },
    {
      "timestamp": "2016-10-22T00:00:00Z",
      "count": 566,
      "uniques": 168
    },
    {
      "timestamp": "2016-10-23T00:00:00Z",
      "count": 675,
      "uniques": 184
    },
    {
      "timestamp": "2016-10-24T00:00:00Z",
      "count": 614,
      "uniques": 237
    }
  ]
}

```

## Traffic Data を Google Apps Script で 抽出

Google スプレッドシートを準備します。
今回のユースケースでは、一行目に「timestamp」「count」「uniques」と記述。シートの名前を「PV数」と設定します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83767/5311d346-288f-7e88-0174-184a548259dd.png" width="480">


シートの設定ができたら、[ツール] → [スクリプトエディタ] で、Google Apps Script のエディタを開きます。


スプレッドシートのシートIDを確認します。シートのURLで「d」と「edit」の文字列に挟まれている数字が、シートのIDとなります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83767/4fb97801-77cb-1752-31c9-c8ae470a70ba.jpeg" width="480">

シートのIDが取得できたら、Google Apps Script のコードを記述します。

```javascript
function getPV () {
  // シートを定義
  const mySheet = SpreadsheetApp.openById ('${シートのID}').getSheetByName ('PV数');

  // GitHub トークンをヘッダに設定
  const headers = {
    Authorization: 'token ${取得した Personal Access token}',
  };
  const options = {
    headers: headers,
  };
  // GitHub にリクエスト
  const requestUrl =
    'https://api.github.com/repos/${GitHubアカウント名}/${レポジトリ名}/traffic/views';
  const response = UrlFetchApp.fetch (requestUrl, options);
  const jsonData = JSON.parse (response);
  const rows = jsonData.views.length;
  Logger.log (jsonData);

  // Timestamp, views, Unique を書き込み
  for (let i = 0; i < rows; i++) {
    mySheet.insertRows (2, 1);
    mySheet.getRange (2, 1, 1, 1).setValue (jsonData.views[i].timestamp);
    mySheet.getRange (2, 2, 1, 1).setValue (jsonData.views[i].count);
    mySheet.getRange (2, 3, 1, 1).setValue (jsonData.views[i].uniques);
  }

  // 重複データをマージ
  let data = mySheet.getDataRange ().getValues ();
  let newData = [];
  for (var i in data) {
    let row = data[i];
    let duplicate = false;
    for (let j in newData) {
      if (row.join () == newData[j].join ()) {
        duplicate = true;
      }
    }
    if (!duplicate) {
      newData.push (row);
    }
  }
  mySheet.clearContents ();
  mySheet
    .getRange (1, 1, newData.length, newData[0].length)
    .setValues (newData);
}

```

コードを保存して実行します。シートへのデータ書き込みなど、実行権限を許可するメッセージが表示されるので、権限を確認・許可します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83767/cbb4c077-6af3-e868-78d5-19ccbb79b130.png" width="480">


設定が完了したら、スクリプトを実行します。問題がなければ、シートに取得したPV数が日付と共に書き込みされます。

下記は個人アカウントで公開しているレポジトリのPV数です。訪問数が少ないですねw

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83767/a6f71585-576e-ec91-5f9f-b94c0a2ca0ea.png" width="480">


## 定期的に実行するための設定を行う


最後に、毎週でスクリプトを定期実行する設定を行います。定期実行は「トリガー」で設定します。

スクリプトエディタのメニューから [トリガー] を選択

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83767/927b2227-8122-51d2-b7f1-492de253e72d.png" width="300">


トリガーの設定をします。[イベントのソース]は「時間主導型」、タイプは「週ベースのタイマー」 を選択。曜日と時間は適宜設定します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83767/9996f8af-9cef-b029-31b5-de807db2ef2e.png" width="480">


トリガーを設定したら、完了です。実際にトリガーが成功したかどうかは、ログを見て確認します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83767/c68f8f77-099a-9eeb-66d8-cfba85afee70.png" width="480">

## 補足

毎週スクリプトを実行するたびに、過去2週間分のデータを取得します。このため、必ず1週間分のデータが重複する形になります。

今回のスクリプトでは、重複データをチェックするためのルーチンを記述。

- 記述ずみのデータを変数「data」に格納
- 新たに取得したデータと比較し、すでに記述済みのデータは除外
- 新しいデータのみシートに書き込む

という処理をしています。